// pendingOrDead looks up machines with ids and retuns those that do not // have an instance id assigned yet, and also those that are dead. func (task *provisionerTask) pendingOrDead(ids []string) (pending, dead []*state.Machine, err error) { for _, id := range ids { machine, found := task.machines[id] if !found { logger.Infof("machine %q not found", id) continue } switch machine.Life() { case state.Dying: if _, err := machine.InstanceId(); err == nil { continue } else if !state.IsNotProvisionedError(err) { logger.Errorf("failed to load machine %q instance id: %v", machine, err) return nil, nil, err } logger.Infof("killing dying, unprovisioned machine %q", machine) if err := machine.EnsureDead(); err != nil { logger.Errorf("failed to ensure machine dead %q: %v", machine, err) return nil, nil, err } fallthrough case state.Dead: dead = append(dead, machine) logger.Infof("removing dead machine %q", machine) if err := machine.Remove(); err != nil { logger.Errorf("failed to remove dead machine %q", machine) return nil, nil, err } // now remove it from the machines map delete(task.machines, machine.Id()) continue } if instId, err := machine.InstanceId(); err != nil { if !state.IsNotProvisionedError(err) { logger.Errorf("failed to load machine %q instance id: %v", machine, err) continue } status, _, err := machine.Status() if err != nil { logger.Infof("cannot get machine %q status: %v", machine, err) continue } if status == params.StatusPending { pending = append(pending, machine) logger.Infof("found machine %q pending provisioning", machine) continue } } else { logger.Infof("machine %v already started as instance %q", machine, instId) } } logger.Tracef("pending machines: %v", pending) logger.Tracef("dead machines: %v", dead) return }
// findUnknownInstances finds instances which are not associated with a machine. func (task *provisionerTask) findUnknownInstances(stopping []instance.Instance) ([]instance.Instance, error) { // Make a copy of the instances we know about. instances := make(map[instance.Id]instance.Instance) for k, v := range task.instances { instances[k] = v } for _, m := range task.machines { if instId, err := m.InstanceId(); err == nil { delete(instances, instId) } else if !state.IsNotProvisionedError(err) { return nil, err } } // Now remove all those instances that we are stopping already, as they // have been removed from the task.machines map. for _, i := range stopping { delete(instances, i.Id()) } var unknown []instance.Instance for _, i := range instances { unknown = append(unknown, i) } logger.Tracef("unknown: %v", unknown) return unknown, nil }
// waitInstanceId waits until the supplied machine has an instance id, then // asserts it is as expected. func (s *CommonProvisionerSuite) waitInstanceId(c *C, m *state.Machine, expect instance.Id) { s.waitHardwareCharacteristics(c, m, func() bool { if actual, err := m.InstanceId(); err == nil { c.Assert(actual, Equals, expect) return true } else if !state.IsNotProvisionedError(err) { // We don't expect any errors. panic(err) } c.Logf("machine %v is still unprovisioned", m) return false }) }
func (t *LiveTests) assertStartInstance(c *C, m *state.Machine) { // Wait for machine to get an instance id. for a := waitAgent.Start(); a.Next(); { err := m.Refresh() c.Assert(err, IsNil) instId, err := m.InstanceId() if err != nil { c.Assert(state.IsNotProvisionedError(err), IsTrue) continue } _, err = t.Env.Instances([]instance.Id{instId}) c.Assert(err, IsNil) return } c.Fatalf("provisioner failed to start machine after %v", waitAgent.Total) }
func (c *Client) Status() (api.Status, error) { ms, err := c.api.state.AllMachines() if err != nil { return api.Status{}, err } status := api.Status{ Machines: make(map[string]api.MachineInfo), } for _, m := range ms { instId, err := m.InstanceId() if err != nil && !state.IsNotProvisionedError(err) { return api.Status{}, err } status.Machines[m.Id()] = api.MachineInfo{ InstanceId: string(instId), } } return status, nil }
func (context *statusContext) makeMachineStatus(machine *state.Machine) (status machineStatus) { status.Id = machine.Id() status.Life, status.AgentVersion, status.AgentState, status.AgentStateInfo, status.Err = processAgent(machine) status.Series = machine.Series() instid, err := machine.InstanceId() if err == nil { status.InstanceId = instid inst, ok := context.instances[instid] if ok { status.DNSName, _ = inst.DNSName() } else { // Double plus ungood. There is an instance id recorded // for this machine in the state, yet the environ cannot // find that id. status.InstanceState = "missing" } } else { if state.IsNotProvisionedError(err) { status.InstanceId = "pending" } else { status.InstanceId = "error" } // There's no point in reporting a pending agent state // if the machine hasn't been provisioned. This // also makes unprovisioned machines visually distinct // in the output. status.AgentState = "" } hc, err := machine.HardwareCharacteristics() if err != nil { if !errors.IsNotFoundError(err) { status.Hardware = "error" } } else { status.Hardware = hc.String() } status.Containers = make(map[string]machineStatus) return }
// assertInstanceId asserts that the machine has an instance id // that matches that of the given instance. If the instance is nil, // It asserts that the instance id is unset. func assertInstanceId(c *C, m *state.Machine, inst instance.Instance) { var wantId, gotId instance.Id var err error if inst != nil { wantId = inst.Id() } for a := waitAgent.Start(); a.Next(); { err := m.Refresh() c.Assert(err, IsNil) gotId, err = m.InstanceId() if err != nil { c.Assert(state.IsNotProvisionedError(err), IsTrue) if inst == nil { return } continue } break } c.Assert(err, IsNil) c.Assert(gotId, Equals, wantId) }
func (c *SSHCommon) machinePublicAddress(id string) (string, error) { machine, err := c.State.Machine(id) if err != nil { return "", err } // wait for instance id w := machine.Watch() for _ = range w.Changes() { if instid, err := machine.InstanceId(); err == nil { w.Stop() inst, err := c.Environ.Instances([]instance.Id{instid}) if err != nil { return "", err } return inst[0].WaitDNSName() } else if !state.IsNotProvisionedError(err) { return "", err } } // oops, watcher closed before we could get an answer return "", w.Stop() }