// unitChanged responds to changes in the unit. func (f *filter) unitChanged() error { if err := f.unit.Refresh(); err != nil { if errors.IsNotFoundError(err) { return worker.ErrTerminateAgent } return err } if f.life != f.unit.Life() { switch f.life = f.unit.Life(); f.life { case state.Dying: log.Noticef("worker/uniter/filter: unit is dying") close(f.outUnitDying) f.outUpgrade = nil case state.Dead: log.Noticef("worker/uniter/filter: unit is dead") return worker.ErrTerminateAgent } } if resolved := f.unit.Resolved(); resolved != f.resolved { f.resolved = resolved if f.resolved != state.ResolvedNone { f.outResolved = f.outResolvedOn } } return nil }
// Run changes the version proposed for the juju tools. func (c *UpgradeJujuCommand) Run(_ *cmd.Context) (err error) { conn, err := juju.NewConnFromName(c.EnvName) if err != nil { return err } defer conn.Close() defer func() { if err == errUpToDate { log.Noticef(err.Error()) err = nil } }() // Determine the version to upgrade to, uploading tools if necessary. env := conn.Environ cfg, err := conn.State.EnvironConfig() if err != nil { return err } v, err := c.initVersions(cfg, env) if err != nil { return err } if c.UploadTools { series := getUploadSeries(cfg, c.Series) if err := v.uploadTools(env.Storage(), series); err != nil { return err } } if err := v.validate(); err != nil { return err } log.Infof("upgrade version chosen: %s", v.chosen) // TODO(fwereade): this list may be incomplete, pending tools.Upload change. log.Infof("available tools: %s", v.tools) // Write updated config back to state if necessary. Note that this is // crackful and racy, because we have no idea what incompatible agent- // version might be set by another administrator in the meantime. If // this happens, tough: I'm not going to pretend to do it right when // I'm not. // TODO(fwereade): Do this right. Warning: scope unclear. cfg, err = cfg.Apply(map[string]interface{}{ "agent-version": v.chosen.String(), }) if err != nil { return err } if err := conn.State.SetEnvironConfig(cfg); err != nil { return err } log.Noticef("started upgrade to %s", v.chosen) return nil }
// MgoReset deletes all content from the shared MongoDB server. func MgoReset() { session := MgoDial() defer session.Close() dbnames, err := session.DatabaseNames() if isUnauthorized(err) { // If we've got an unauthorized access error, we're // locked out of the database. We restart it to regain // access. This should only happen when tests fail. destroyMgoServer() log.Noticef("testing: restarting MongoDB server after unauthorized access") if err := startMgoServer(); err != nil { panic(err) } return } if err != nil { panic(err) } for _, name := range dbnames { switch name { case "admin", "local", "config": default: err = session.DB(name).DropDatabase() if err != nil { panic(fmt.Errorf("Cannot drop MongoDB database %v: %v", name, err)) } } } }
func (p *Provisioner) startMachine(m *state.Machine) error { // TODO(dfc) the state.Info passed to environ.StartInstance remains contentious // however as the PA only knows one state.Info, and that info is used by MAs and // UAs to locate the state for this environment, it is logical to use the same // state.Info as the PA. stateInfo, apiInfo, err := p.setupAuthentication(m) if err != nil { return err } cons, err := m.Constraints() if err != nil { return err } // Generate a unique nonce for the new instance. uuid, err := utils.NewUUID() if err != nil { return err } // Generated nonce has the format: "machine-#:UUID". The first // part is a badge, specifying the tag of the machine the provisioner // is running on, while the second part is a random UUID. nonce := fmt.Sprintf("%s:%s", state.MachineTag(p.machineId), uuid.String()) inst, err := p.environ.StartInstance(m.Id(), nonce, m.Series(), cons, stateInfo, apiInfo) if err != nil { // Set the state to error, so the machine will be skipped next // time until the error is resolved, but don't return an // error; just keep going with the other machines. log.Errorf("worker/provisioner: cannot start instance for machine %q: %v", m, err) if err1 := m.SetStatus(params.StatusError, err.Error()); err1 != nil { // Something is wrong with this machine, better report it back. log.Errorf("worker/provisioner: cannot set error status for machine %q: %v", m, err1) return err1 } return nil } if err := m.SetProvisioned(inst.Id(), nonce); err != nil { // The machine is started, but we can't record the mapping in // state. It'll keep running while we fail out and restart, // but will then be detected by findUnknownInstances and // killed again. // // TODO(dimitern) Stop the instance right away here. // // Multiple instantiations of a given machine (with the same // machine ID) cannot coexist, because findUnknownInstances is // called before startMachines. However, if the first machine // had started to do work before being replaced, we may // encounter surprising problems. return err } // populate the local cache p.instances[m.Id()] = inst p.machines[inst.Id()] = m.Id() log.Noticef("worker/provisioner: started machine %s as instance %s", m, inst.Id()) return nil }
// NewConn returns a new Conn that uses the // given environment. The environment must have already // been bootstrapped. func NewConn(environ environs.Environ) (*Conn, error) { info, _, err := environ.StateInfo() if err != nil { return nil, err } password := environ.Config().AdminSecret() if password == "" { return nil, fmt.Errorf("cannot connect without admin-secret") } err = environs.CheckEnvironment(environ) if err != nil { return nil, err } info.Password = password opts := state.DefaultDialOpts() st, err := state.Open(info, opts) if errors.IsUnauthorizedError(err) { log.Noticef("juju: authorization error while connecting to state server; retrying") // We can't connect with the administrator password,; // perhaps this was the first connection and the // password has not been changed yet. info.Password = utils.PasswordHash(password) // We try for a while because we might succeed in // connecting to mongo before the state has been // initialized and the initial password set. for a := redialStrategy.Start(); a.Next(); { st, err = state.Open(info, opts) if !errors.IsUnauthorizedError(err) { break } } if err != nil { return nil, err } if err := st.SetAdminMongoPassword(password); err != nil { return nil, err } } else if err != nil { return nil, err } conn := &Conn{ Environ: environ, State: st, } if err := conn.updateSecrets(); err != nil { conn.Close() return nil, fmt.Errorf("unable to push secrets: %v", err) } return conn, nil }
func uploadFakeToolsVersion(storage environs.Storage, vers version.Binary) (*state.Tools, error) { data := vers.String() name := tools.StorageName(vers) log.Noticef("environs/testing: uploading FAKE tools %s", vers) if err := storage.Put(name, strings.NewReader(data), int64(len(data))); err != nil { return nil, err } url, err := storage.URL(name) if err != nil { return nil, err } return &state.Tools{Binary: vers, URL: url}, nil }
func (u *Uniter) loop(name string) (err error) { if err = u.init(name); err != nil { return err } log.Noticef("worker/uniter: unit %q started", u.unit) // Start filtering state change events for consumption by modes. u.f, err = newFilter(u.st, name) if err != nil { return err } defer watcher.Stop(u.f, &u.tomb) go func() { u.tomb.Kill(u.f.Wait()) }() // Announce our presence to the world. pinger, err := u.unit.SetAgentAlive() if err != nil { return err } defer watcher.Stop(pinger, &u.tomb) // Run modes until we encounter an error. mode := ModeInit for err == nil { select { case <-u.tomb.Dying(): err = tomb.ErrDying default: mode, err = mode(u) } } log.Noticef("worker/uniter: unit %q shutting down: %s", u.unit, err) return err }
func (s *suite) TestNoticeLogger(c *C) { input := "Hello World" log.Noticef(input) c.Assert(s.writer.String(), Equals, "INFO juju "+input) }