Пример #1
0
func newExecutor(c *gc.C, st *operation.State) (operation.Executor, string) {
	path := filepath.Join(c.MkDir(), "state")
	err := operation.NewStateFile(path).Write(st)
	c.Assert(err, jc.ErrorIsNil)
	executor, err := operation.NewExecutor(path, failGetInstallCharm, failAcquireLock)
	c.Assert(err, jc.ErrorIsNil)
	return executor, path
}
Пример #2
0
func (s *ExecutorSuite) initLockTest(c *gc.C, lockFunc func() (mutex.Releaser, error)) operation.Executor {
	initialState := justInstalledState()
	statePath := filepath.Join(c.MkDir(), "state")
	err := operation.NewStateFile(statePath).Write(&initialState)
	c.Assert(err, jc.ErrorIsNil)
	executor, err := operation.NewExecutor(statePath, failGetInstallCharm, lockFunc)
	c.Assert(err, jc.ErrorIsNil)

	return executor
}
Пример #3
0
func (s *NewExecutorSuite) TestNewExecutorNoFile(c *gc.C) {
	charmURL := corecharm.MustParseURL("cs:quantal/nyancat-323")
	getInstallCharm := func() (*corecharm.URL, error) {
		return charmURL, nil
	}
	executor, err := operation.NewExecutor(s.path("missing"), getInstallCharm, failAcquireLock)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(executor.State(), gc.DeepEquals, operation.State{
		Kind:     operation.Install,
		Step:     operation.Queued,
		CharmURL: charmURL,
	})
	ft.Removed{"missing"}.Check(c, s.basePath)
}
Пример #4
0
func (s *NewExecutorSuite) TestNewExecutorValidFile(c *gc.C) {
	// note: this content matches valid persistent state as of 1.21; we expect
	// that "hook" will have to become "last-hook" to enable action execution
	// during hook error states. If you do this, please leave at least one test
	// with this form of the yaml in place.
	ft.File{"existing", `
started: true
op: continue
opstep: pending
`[1:], 0666}.Create(c, s.basePath)
	executor, err := operation.NewExecutor(s.path("existing"), failGetInstallCharm, failAcquireLock)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(executor.State(), gc.DeepEquals, operation.State{
		Kind:    operation.Continue,
		Step:    operation.Pending,
		Started: true,
	})
}
Пример #5
0
func (s *NewExecutorSuite) TestNewExecutorInvalidFile(c *gc.C) {
	ft.File{"existing", "", 0666}.Create(c, s.basePath)
	executor, err := operation.NewExecutor(s.path("existing"), failGetInstallCharm, failAcquireLock)
	c.Assert(executor, gc.IsNil)
	c.Assert(err, gc.ErrorMatches, `cannot read ".*": invalid operation state: .*`)
}
Пример #6
0
func (s *NewExecutorSuite) TestNewExecutorNoFileNoCharm(c *gc.C) {
	executor, err := operation.NewExecutor(s.path("missing"), failGetInstallCharm, failAcquireLock)
	c.Assert(executor, gc.IsNil)
	c.Assert(err, gc.ErrorMatches, "lol!")
}
Пример #7
0
func (u *Uniter) init(unitTag names.UnitTag) (err error) {
	u.unit, err = u.st.Unit(unitTag)
	if err != nil {
		return err
	}
	if u.unit.Life() == params.Dead {
		// If we started up already dead, we should not progress further. If we
		// become Dead immediately after starting up, we may well complete any
		// operations in progress before detecting it; but that race is fundamental
		// and inescapable, whereas this one is not.
		return worker.ErrTerminateAgent
	}
	if err = u.setupLocks(); err != nil {
		return err
	}
	if err := jujuc.EnsureSymlinks(u.paths.ToolsDir); err != nil {
		return err
	}
	if err := os.MkdirAll(u.paths.State.RelationsDir, 0755); err != nil {
		return errors.Trace(err)
	}
	relations, err := newRelations(u.st, unitTag, u.paths, u.tomb.Dying())
	if err != nil {
		return errors.Annotatef(err, "cannot create relations")
	}
	u.relations = relations
	storageAttachments, err := storage.NewAttachments(
		u.st, unitTag, u.paths.State.StorageDir, u.tomb.Dying(),
	)
	if err != nil {
		return errors.Annotatef(err, "cannot create storage hook source")
	}
	u.storage = storageAttachments
	u.addCleanup(storageAttachments.Stop)

	deployer, err := charm.NewDeployer(
		u.paths.State.CharmDir,
		u.paths.State.DeployerDir,
		charm.NewBundlesDir(u.paths.State.BundlesDir),
	)
	if err != nil {
		return errors.Annotatef(err, "cannot create deployer")
	}
	u.deployer = &deployerProxy{deployer}
	runnerFactory, err := runner.NewFactory(
		u.st, unitTag, u.leadershipTracker, u.relations.GetInfo, u.storage, u.paths,
	)
	if err != nil {
		return err
	}
	u.operationFactory = operation.NewFactory(
		u.deployer,
		runnerFactory,
		&operationCallbacks{u},
		u.storage,
		u.tomb.Dying(),
	)

	operationExecutor, err := operation.NewExecutor(
		u.paths.State.OperationsFile, u.getServiceCharmURL, u.acquireExecutionLock,
	)
	if err != nil {
		return err
	}
	u.operationExecutor = operationExecutor

	logger.Debugf("starting juju-run listener on unix:%s", u.paths.Runtime.JujuRunSocket)
	u.runListener, err = NewRunListener(u, u.paths.Runtime.JujuRunSocket)
	if err != nil {
		return err
	}
	u.addCleanup(func() error {
		// TODO(fwereade): RunListener returns no error on Close. This seems wrong.
		u.runListener.Close()
		return nil
	})
	// The socket needs to have permissions 777 in order for other users to use it.
	if version.Current.OS != version.Windows {
		return os.Chmod(u.paths.Runtime.JujuRunSocket, 0777)
	}
	return nil
}
Пример #8
0
func newOperationExecutor(u *Uniter) (operation.Executor, error) {
	return operation.NewExecutor(
		u.paths.State.OperationsFile, u.getServiceCharmURL, u.acquireExecutionLock,
	)
}