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 }
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 }
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) }
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, }) }
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: .*`) }
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!") }
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 }
func newOperationExecutor(u *Uniter) (operation.Executor, error) { return operation.NewExecutor( u.paths.State.OperationsFile, u.getServiceCharmURL, u.acquireExecutionLock, ) }