Example #1
0
File: reboot.go Project: bac/juju
func (r *Reboot) Handle(_ <-chan struct{}) error {
	rAction, err := r.st.GetRebootAction()
	if err != nil {
		return errors.Trace(err)
	}
	logger.Debugf("Reboot worker got action: %v", rAction)
	// NOTE: Here we explicitly avoid stopping on the abort channel as we are
	// wanting to make sure that we grab the lock and return an error
	// sufficiently heavyweight to get the agent to restart.
	spec := mutex.Spec{
		Name:  r.machineLockName,
		Clock: r.clock,
		Delay: 250 * time.Millisecond,
	}

	switch rAction {
	case params.ShouldReboot:
		logger.Debugf("acquiring mutex %q for reboot", r.machineLockName)
		if _, err := mutex.Acquire(spec); err != nil {
			return errors.Trace(err)
		}
		logger.Debugf("mutex %q acquired, won't release", r.machineLockName)
		return worker.ErrRebootMachine
	case params.ShouldShutdown:
		logger.Debugf("acquiring mutex %q for shutdown", r.machineLockName)
		if _, err := mutex.Acquire(spec); err != nil {
			return errors.Trace(err)
		}
		logger.Debugf("mutex %q acquired, won't release", r.machineLockName)
		return worker.ErrShutdownMachine
	default:
		return nil
	}
}
Example #2
0
func (h *hookLock) acquire() *hookStep {
	return &hookStep{stepFunc: func(c *gc.C, ctx *context) {
		releaser, err := mutex.Acquire(hookLockSpec())
		c.Assert(err, jc.ErrorIsNil)
		h.releaser = releaser
	}}
}
Example #3
0
// runInitialiser runs the container initialiser with the initialisation hook held.
func (cs *ContainerSetup) runInitialiser(abort <-chan struct{}, containerType instance.ContainerType, initialiser container.Initialiser) error {
	logger.Debugf("running initialiser for %s containers", containerType)
	spec := mutex.Spec{
		Name:  cs.initLockName,
		Clock: clock.WallClock,
		// If we don't get the lock straigh away, there is no point trying multiple
		// times per second for an operation that is likelty to take multiple seconds.
		Delay:  time.Second,
		Cancel: abort,
	}
	logger.Debugf("acquire lock %q for container initialisation", cs.initLockName)
	releaser, err := mutex.Acquire(spec)
	if err != nil {
		return errors.Annotate(err, "failed to acquire initialization lock")
	}
	logger.Debugf("lock %q acquired", cs.initLockName)
	defer logger.Debugf("release lock %q for container initialisation", cs.initLockName)
	defer releaser.Release()

	if err := initialiser.Initialise(); err != nil {
		return errors.Trace(err)
	}

	return nil
}
Example #4
0
File: run.go Project: bac/juju
func (c *RunCommand) executeNoContext() (*exec.ExecResponse, error) {
	// Acquire the uniter hook execution lock to make sure we don't
	// stomp on each other.
	spec := mutex.Spec{
		Name:  c.MachineLockName,
		Clock: clock.WallClock,
		Delay: 250 * time.Millisecond,
	}
	logger.Debugf("acquire lock %q for juju-run", c.MachineLockName)
	releaser, err := mutex.Acquire(spec)
	if err != nil {
		return nil, errors.Trace(err)
	}
	logger.Debugf("lock %q acquired", c.MachineLockName)

	// Defer the logging first so it is executed after the Release. LIFO.
	defer logger.Debugf("release lock %q for juju-run", c.MachineLockName)
	defer releaser.Release()

	runCmd := c.appendProxyToCommands()

	return exec.RunCommands(
		exec.RunParams{
			Commands: runCmd,
		})
}
Example #5
0
File: file.go Project: bac/juju
func (s *store) acquireLock() (mutex.Releaser, error) {
	const lockName = "store-lock"
	spec := mutex.Spec{
		Name:    lockName,
		Clock:   clock.WallClock,
		Delay:   20 * time.Millisecond,
		Timeout: lockTimeout,
	}
	releaser, err := mutex.Acquire(spec)
	if err != nil {
		return nil, errors.Trace(err)
	}
	return releaser, nil
}
Example #6
0
File: runner.go Project: bac/juju
// acquireExecutionLock acquires the machine-level execution lock and returns a function to be used
// to unlock it.
func (w *hookRunner) acquireExecutionLock(interrupt <-chan struct{}) (mutex.Releaser, error) {
	spec := mutex.Spec{
		Name:   w.machineLockName,
		Clock:  w.clock,
		Delay:  250 * time.Millisecond,
		Cancel: interrupt,
	}
	logger.Debugf("acquire lock %q for meter status hook execution", w.machineLockName)
	releaser, err := mutex.Acquire(spec)
	if err != nil {
		return nil, errors.Trace(err)
	}
	logger.Debugf("lock %q acquired", w.machineLockName)
	return releaser, nil
}
Example #7
0
// acquireExecutionLock acquires the machine-level execution lock, and
// returns a func that must be called to unlock it. It's used by operation.Executor
// when running operations that execute external code.
func (u *Uniter) acquireExecutionLock() (mutex.Releaser, error) {
	// We want to make sure we don't block forever when locking, but take the
	// Uniter's catacomb into account.
	spec := mutex.Spec{
		Name:   u.hookLockName,
		Clock:  u.clock,
		Delay:  250 * time.Millisecond,
		Cancel: u.catacomb.Dying(),
	}
	logger.Debugf("acquire lock %q for uniter hook execution", u.hookLockName)
	releaser, err := mutex.Acquire(spec)
	if err != nil {
		return nil, errors.Trace(err)
	}
	logger.Debugf("lock %q acquired", u.hookLockName)
	return releaser, nil
}
Example #8
0
func (s waitHooks) step(c *gc.C, ctx *context) {
	if len(s) == 0 {
		// Give unwanted hooks a moment to run...
		ctx.s.BackingState.StartSync()
		time.Sleep(coretesting.ShortWait)
	}
	ctx.hooks = append(ctx.hooks, s...)
	c.Logf("waiting for hooks: %#v", ctx.hooks)
	match, overshoot := ctx.matchHooks(c)
	if overshoot && len(s) == 0 {
		c.Fatalf("ran more hooks than expected")
	}
	waitExecutionLockReleased := func() {
		spec := hookLockSpec()
		spec.Timeout = worstCase
		releaser, err := mutex.Acquire(spec)
		if err != nil {
			c.Fatalf("failed to acquire execution lock: %v", err)
		}
		releaser.Release()
	}
	if match {
		if len(s) > 0 {
			// only check for lock release if there were hooks
			// run; hooks *not* running may be due to the lock
			// being held.
			waitExecutionLockReleased()
		}
		return
	}
	timeout := time.After(worstCase)
	for {
		ctx.s.BackingState.StartSync()
		select {
		case <-time.After(coretesting.ShortWait):
			if match, _ = ctx.matchHooks(c); match {
				waitExecutionLockReleased()
				return
			}
		case <-timeout:
			c.Fatalf("never got expected hooks")
		}
	}
}
Example #9
0
File: run_test.go Project: bac/juju
func (s *RunTestSuite) TestNoContextWithLock(c *gc.C) {
	spec := mutex.Spec{
		Name:  testLockName,
		Clock: clock.WallClock,
		Delay: 250 * time.Millisecond,
	}
	releaser, err := mutex.Acquire(spec)
	c.Assert(err, jc.ErrorIsNil)
	defer releaser.Release() // in case of failure

	channel := s.startRunAsync(c, []string{"--no-context", "echo done"})
	ctx, err := waitForResult(channel, testing.ShortWait)
	c.Assert(err, gc.ErrorMatches, "timeout")

	releaser.Release()

	ctx, err = waitForResult(channel, testing.LongWait)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(strings.TrimRight(testing.Stdout(ctx), "\r\n"), gc.Equals, "done")
}