func (s *StateSuite) TestInjectMachine(c *C) { _, err := s.State.InjectMachine(state.InstanceId(""), state.JobHostUnits) c.Assert(err, ErrorMatches, "cannot inject a machine without an instance id") _, err = s.State.InjectMachine(state.InstanceId("i-mlazy")) c.Assert(err, ErrorMatches, "cannot add a new machine: no jobs specified") m, err := s.State.InjectMachine(state.InstanceId("i-mindustrious"), state.JobHostUnits, state.JobManageEnviron) c.Assert(err, IsNil) c.Assert(m.Jobs(), DeepEquals, []state.MachineJob{state.JobHostUnits, state.JobManageEnviron}) instanceId, err := m.InstanceId() c.Assert(err, IsNil) c.Assert(instanceId, Equals, state.InstanceId("i-mindustrious")) }
// Run initializes state for an environment. func (c *BootstrapCommand) Run(_ *cmd.Context) error { if err := c.Conf.read("bootstrap"); err != nil { return err } cfg, err := config.New(c.EnvConfig) if err != nil { return err } // There is no entity that's created at init time. c.Conf.StateInfo.EntityName = "" st, err := state.Initialize(c.Conf.StateInfo, cfg) if err != nil { return err } defer st.Close() m, err := st.InjectMachine(state.InstanceId(c.InstanceId), state.JobManageEnviron) if err != nil { return err } if c.Conf.OldPassword != "" { if err := m.SetMongoPassword(c.Conf.OldPassword); err != nil { return err } if err := st.SetAdminMongoPassword(c.Conf.OldPassword); err != nil { return err } } return nil }
func (e *environ) StartInstance(machineId string, info *state.Info, tools *state.Tools) (environs.Instance, error) { defer delay() log.Printf("environs/dummy: dummy startinstance, machine %s", machineId) if err := e.checkBroken("StartInstance"); err != nil { return nil, err } e.state.mu.Lock() defer e.state.mu.Unlock() if _, ok := e.Config().CACert(); !ok { return nil, fmt.Errorf("no CA certificate in environment configuration") } if info.EntityName != state.MachineEntityName(machineId) { return nil, fmt.Errorf("entity name must match started machine") } if tools != nil && (strings.HasPrefix(tools.Series, "unknown") || strings.HasPrefix(tools.Arch, "unknown")) { return nil, fmt.Errorf("cannot find image for %s-%s", tools.Series, tools.Arch) } i := &instance{ state: e.state, id: state.InstanceId(fmt.Sprintf("%s-%d", e.state.name, e.state.maxId)), ports: make(map[state.Port]bool), machineId: machineId, } e.state.insts[i.id] = i e.state.maxId++ e.state.ops <- OpStartInstance{ Env: e.state.name, MachineId: machineId, Instance: i, Info: info, Secret: e.ecfg().secret(), } return i, nil }
func (e *environ) Destroy(ensureInsts []environs.Instance) error { log.Printf("environs/openstack: destroying environment %q", e.name) insts, err := e.AllInstances() if err != nil { return fmt.Errorf("cannot get instances: %v", err) } found := make(map[state.InstanceId]bool) var ids []state.InstanceId for _, inst := range insts { ids = append(ids, inst.Id()) found[inst.Id()] = true } // Add any instances we've been told about but haven't yet shown // up in the instance list. for _, inst := range ensureInsts { id := state.InstanceId(inst.(*instance).Id()) if !found[id] { ids = append(ids, id) found[id] = true } } err = e.terminateInstances(ids) if err != nil { return err } // To properly observe e.storageUnlocked we need to get its value while // holding e.ecfgMutex. e.Storage() does this for us, then we convert // back to the (*storage) to access the private deleteAll() method. st := e.Storage().(*storage) return st.deleteAll() }
func (s *StateSuite) TestAllMachines(c *C) { numInserts := 42 for i := 0; i < numInserts; i++ { m, err := s.State.AddMachine(state.JobHostUnits) c.Assert(err, IsNil) err = m.SetInstanceId(state.InstanceId(fmt.Sprintf("foo-%d", i))) c.Assert(err, IsNil) err = m.SetAgentTools(newTools("7.8.9-foo-bar", "http://arble.tgz")) c.Assert(err, IsNil) err = m.EnsureDying() c.Assert(err, IsNil) } s.AssertMachineCount(c, numInserts) ms, _ := s.State.AllMachines() for i, m := range ms { c.Assert(m.Id(), Equals, strconv.Itoa(i)) instId, err := m.InstanceId() c.Assert(err, IsNil) c.Assert(string(instId), Equals, fmt.Sprintf("foo-%d", i)) tools, err := m.AgentTools() c.Check(err, IsNil) c.Check(tools, DeepEquals, newTools("7.8.9-foo-bar", "http://arble.tgz")) c.Assert(m.Life(), Equals, state.Dying) } }
func (s *BootstrapSuite) TestSetMachineId(c *C) { args := []string{ "--instance-id", "over9000", "--env-config", b64yaml{ "name": "dummyenv", "type": "dummy", "state-server": false, "authorized-keys": "i-am-a-key", "ca-cert": testing.CACert, }.encode(), } _, cmd, err := s.initBootstrapCommand(c, args...) c.Assert(err, IsNil) err = cmd.Run(nil) c.Assert(err, IsNil) st, err := state.Open(&state.Info{ Addrs: []string{testing.MgoAddr}, CACert: []byte(testing.CACert), }) c.Assert(err, IsNil) defer st.Close() machines, err := st.AllMachines() c.Assert(err, IsNil) c.Assert(len(machines), Equals, 1) instid, err := machines[0].InstanceId() c.Assert(err, IsNil) c.Assert(instid, Equals, state.InstanceId("over9000")) }
func (s *MachineSuite) TestMachineInstanceId(c *C) { machine, err := s.State.AddMachine(state.JobHostUnits) c.Assert(err, IsNil) err = s.machines.Update( D{{"_id", machine.Id()}}, D{{"$set", D{{"instanceid", "spaceship/0"}}}}, ) c.Assert(err, IsNil) err = machine.Refresh() c.Assert(err, IsNil) iid, _ := machine.InstanceId() c.Assert(iid, Equals, state.InstanceId("spaceship/0")) }
func (s *MachineSuite) TestMachineInstanceIdCorrupt(c *C) { machine, err := s.State.AddMachine(state.JobHostUnits) c.Assert(err, IsNil) err = s.machines.Update( D{{"_id", machine.Id()}}, D{{"$set", D{{"instanceid", D{{"foo", "bar"}}}}}}, ) c.Assert(err, IsNil) err = machine.Refresh() c.Assert(err, IsNil) iid, err := machine.InstanceId() c.Assert(state.IsNotFound(err), Equals, true) c.Assert(iid, Equals, state.InstanceId("")) }
func (t *LiveTests) TestInstanceGroups(c *C) { ec2conn := ec2.EnvironEC2(t.Env) groups := amzec2.SecurityGroupNames( ec2.JujuGroupName(t.Env), ec2.MachineGroupName(t.Env, "98"), ec2.MachineGroupName(t.Env, "99"), ) info := make([]amzec2.SecurityGroupInfo, len(groups)) // Create a group with the same name as the juju group // but with different permissions, to check that it's deleted // and recreated correctly. oldJujuGroup := createGroup(c, ec2conn, groups[0].Name, "old juju group") // Add two permissions: one is required and should be left alone; // the other is not and should be deleted. // N.B. this is unfortunately sensitive to the actual set of permissions used. _, err := ec2conn.AuthorizeSecurityGroup(oldJujuGroup, []amzec2.IPPerm{ { Protocol: "tcp", FromPort: 22, ToPort: 22, SourceIPs: []string{"0.0.0.0/0"}, }, { Protocol: "udp", FromPort: 4321, ToPort: 4322, SourceIPs: []string{"3.4.5.6/32"}, }, }) c.Assert(err, IsNil) inst0, err := t.Env.StartInstance("98", testing.InvalidStateInfo("98"), nil) c.Assert(err, IsNil) defer t.Env.StopInstances([]environs.Instance{inst0}) // Create a same-named group for the second instance // before starting it, to check that it's reused correctly. oldMachineGroup := createGroup(c, ec2conn, groups[2].Name, "old machine group") inst1, err := t.Env.StartInstance("99", testing.InvalidStateInfo("99"), nil) c.Assert(err, IsNil) defer t.Env.StopInstances([]environs.Instance{inst1}) groupsResp, err := ec2conn.SecurityGroups(groups, nil) c.Assert(err, IsNil) c.Assert(groupsResp.Groups, HasLen, len(groups)) // For each group, check that it exists and record its id. for i, group := range groups { found := false for _, g := range groupsResp.Groups { if g.Name == group.Name { groups[i].Id = g.Id info[i] = g found = true break } } if !found { c.Fatalf("group %q not found", group.Name) } } // The old juju group should have been reused. c.Check(groups[0].Id, Equals, oldJujuGroup.Id) // Check that it authorizes the correct ports and there // are no extra permissions (in particular we are checking // that the unneeded permission that we added earlier // has been deleted). perms := info[0].IPPerms c.Assert(perms, HasLen, 5) checkPortAllowed(c, perms, 22) // SSH checkPortAllowed(c, perms, 37017) // MongoDB checkSecurityGroupAllowed(c, perms, groups[0]) // The old machine group should have been reused also. c.Check(groups[2].Id, Equals, oldMachineGroup.Id) // Check that each instance is part of the correct groups. resp, err := ec2conn.Instances([]string{string(inst0.Id()), string(inst1.Id())}, nil) c.Assert(err, IsNil) c.Assert(resp.Reservations, HasLen, 2) for _, r := range resp.Reservations { c.Assert(r.Instances, HasLen, 1) // each instance must be part of the general juju group. msg := Commentf("reservation %#v", r) c.Assert(hasSecurityGroup(r, groups[0]), Equals, true, msg) inst := r.Instances[0] switch state.InstanceId(inst.InstanceId) { case inst0.Id(): c.Assert(hasSecurityGroup(r, groups[1]), Equals, true, msg) c.Assert(hasSecurityGroup(r, groups[2]), Equals, false, msg) case inst1.Id(): c.Assert(hasSecurityGroup(r, groups[2]), Equals, true, msg) c.Assert(hasSecurityGroup(r, groups[1]), Equals, false, msg) default: c.Errorf("unknown instance found: %v", inst) } } }
func (inst *instance) Id() state.InstanceId { return state.InstanceId(inst.Entity.Id) }
c.Assert(err, IsNil) err = m1.EnsureDead() c.Assert(err, IsNil) }, []string{"1", "4"}, }, { "Add many, change many, and remove many at once", func(c *C, s *state.State) { machines := [20]*state.Machine{} var err error for i := 0; i < len(machines); i++ { machines[i], err = s.AddMachine(state.JobHostUnits) c.Assert(err, IsNil) } for i := 0; i < len(machines); i++ { err = machines[i].SetInstanceId(state.InstanceId("spam" + fmt.Sprint(i))) c.Assert(err, IsNil) } for i := 10; i < len(machines); i++ { err = machines[i].EnsureDead() c.Assert(err, IsNil) err = s.RemoveMachine(machines[i].Id()) c.Assert(err, IsNil) } }, []string{"5", "6", "7", "8", "9", "10", "11", "12", "13", "14"}, }, { "Do not report never-seen and removed or dead", func(c *C, s *state.State) { m, err := s.AddMachine(state.JobHostUnits) c.Assert(err, IsNil)