// addServiceUnits adds a given number of units to a service. func addServiceUnits(state *state.State, args params.AddServiceUnits) ([]*state.Unit, error) { service, err := state.Service(args.ServiceName) if err != nil { return nil, err } if args.NumUnits < 1 { return nil, fmt.Errorf("must add at least one unit") } // New API uses placement directives. if len(args.Placement) > 0 { return jjj.AddUnitsWithPlacement(state, service, args.NumUnits, args.Placement) } // Otherwise we use the older machine spec. if args.NumUnits > 1 && args.ToMachineSpec != "" { return nil, fmt.Errorf("cannot use NumUnits with ToMachineSpec") } if args.ToMachineSpec != "" && names.IsValidMachine(args.ToMachineSpec) { _, err = state.Machine(args.ToMachineSpec) if err != nil { return nil, errors.Annotatef(err, `cannot add units for service "%v" to machine %v`, args.ServiceName, args.ToMachineSpec) } } return jjj.AddUnits(state, service, args.NumUnits, args.ToMachineSpec) }
func (s *MachineSuite) TestManageModel(c *gc.C) { usefulVersion := version.Binary{ Number: jujuversion.Current, Arch: arch.HostArch(), Series: "quantal", // to match the charm created below } envtesting.AssertUploadFakeToolsVersions(c, s.DefaultToolsStorage, s.Environ.Config().AgentStream(), s.Environ.Config().AgentStream(), usefulVersion) m, _, _ := s.primeAgent(c, state.JobManageModel) op := make(chan dummy.Operation, 200) dummy.Listen(op) a := s.newAgent(c, m) // Make sure the agent is stopped even if the test fails. defer a.Stop() done := make(chan error) go func() { done <- a.Run(nil) }() c.Logf("started test agent, waiting for workers...") r0 := s.singularRecord.nextRunner(c) r0.waitForWorker(c, "txnpruner") // Check that the provisioner and firewaller are alive by doing // a rudimentary check that it responds to state changes. // Create an exposed service, and add a unit. charm := s.AddTestingCharm(c, "dummy") svc := s.AddTestingService(c, "test-service", charm) err := svc.SetExposed() c.Assert(err, jc.ErrorIsNil) units, err := juju.AddUnits(s.State, svc, svc.Name(), 1, nil) c.Assert(err, jc.ErrorIsNil) // It should be allocated to a machine, which should then be provisioned. c.Logf("service %q added with 1 unit, waiting for unit %q's machine to be started...", svc.Name(), units[0].Name()) c.Check(opRecvTimeout(c, s.State, op, dummy.OpStartInstance{}), gc.NotNil) c.Logf("machine hosting unit %q started, waiting for the unit to be deployed...", units[0].Name()) s.waitProvisioned(c, units[0]) // Open a port on the unit; it should be handled by the firewaller. c.Logf("unit %q deployed, opening port tcp/999...", units[0].Name()) err = units[0].OpenPort("tcp", 999) c.Assert(err, jc.ErrorIsNil) c.Check(opRecvTimeout(c, s.State, op, dummy.OpOpenPorts{}), gc.NotNil) c.Logf("unit %q port tcp/999 opened, cleaning up...", units[0].Name()) err = a.Stop() c.Assert(err, jc.ErrorIsNil) select { case err := <-done: c.Assert(err, jc.ErrorIsNil) case <-time.After(coretesting.LongWait): c.Fatalf("timed out waiting for agent to terminate") } c.Logf("test agent stopped successfully.") }
func (s *FirewallerSuite) addUnit(c *gc.C, svc *state.Service) (*state.Unit, *state.Machine) { units, err := juju.AddUnits(s.State, svc, 1, "") c.Assert(err, gc.IsNil) u := units[0] id, err := u.AssignedMachineId() c.Assert(err, gc.IsNil) m, err := s.State.Machine(id) c.Assert(err, gc.IsNil) return u, m }
// addServiceUnits adds a given number of units to a service. func addServiceUnits(st *state.State, args params.AddServiceUnits) ([]*state.Unit, error) { service, err := st.Service(args.ServiceName) if err != nil { return nil, err } if args.NumUnits < 1 { return nil, errors.New("must add at least one unit") } return jjj.AddUnits(st, service, args.NumUnits, args.Placement) }
// addApplicationUnits adds a given number of units to an application. func addApplicationUnits(backend Backend, args params.AddApplicationUnits) ([]*state.Unit, error) { application, err := backend.Application(args.ApplicationName) if err != nil { return nil, errors.Trace(err) } if args.NumUnits < 1 { return nil, errors.New("must add at least one unit") } return jjj.AddUnits(backend, application, args.ApplicationName, args.NumUnits, args.Placement) }
func (s *MachineSuite) TestManageEnviron(c *gc.C) { usefulVersion := version.Current usefulVersion.Series = "quantal" // to match the charm created below envtesting.AssertUploadFakeToolsVersions(c, s.Environ.Storage(), usefulVersion) m, _, _ := s.primeAgent(c, version.Current, state.JobManageEnviron) op := make(chan dummy.Operation, 200) dummy.Listen(op) a := s.newAgent(c, m) // Make sure the agent is stopped even if the test fails. defer a.Stop() done := make(chan error) go func() { done <- a.Run(nil) }() // Check that the provisioner and firewaller are alive by doing // a rudimentary check that it responds to state changes. // Add one unit to a service; it should get allocated a machine // and then its ports should be opened. charm := s.AddTestingCharm(c, "dummy") svc := s.AddTestingService(c, "test-service", charm) err := svc.SetExposed() c.Assert(err, gc.IsNil) units, err := juju.AddUnits(s.State, svc, 1, "") c.Assert(err, gc.IsNil) c.Check(opRecvTimeout(c, s.State, op, dummy.OpStartInstance{}), gc.NotNil) // Wait for the instance id to show up in the state. s.waitProvisioned(c, units[0]) err = units[0].OpenPort("tcp", 999) c.Assert(err, gc.IsNil) c.Check(opRecvTimeout(c, s.State, op, dummy.OpOpenPorts{}), gc.NotNil) err = a.Stop() c.Assert(err, gc.IsNil) select { case err := <-done: c.Assert(err, gc.IsNil) case <-time.After(5 * time.Second): c.Fatalf("timed out waiting for agent to terminate") } c.Assert(s.singularRecord.started(), jc.DeepEquals, []string{ "charm-revision-updater", "cleaner", "environ-provisioner", "firewaller", "minunitsworker", "resumer", }) }
// addServiceUnits adds a given number of units to a service. func addServiceUnits(state *state.State, args params.AddServiceUnits) ([]*state.Unit, error) { service, err := state.Service(args.ServiceName) if err != nil { return nil, err } if args.NumUnits < 1 { return nil, fmt.Errorf("must add at least one unit") } if args.NumUnits > 1 && args.ToMachineSpec != "" { return nil, fmt.Errorf("cannot use NumUnits with ToMachineSpec") } return juju.AddUnits(state, service, args.NumUnits, args.ToMachineSpec) }
func (s *MachineSuite) TestManageModelRunsInstancePoller(c *gc.C) { s.AgentSuite.PatchValue(&instancepoller.ShortPoll, 500*time.Millisecond) usefulVersion := version.Binary{ Number: jujuversion.Current, Arch: arch.HostArch(), Series: "quantal", // to match the charm created below } envtesting.AssertUploadFakeToolsVersions( c, s.DefaultToolsStorage, s.Environ.Config().AgentStream(), s.Environ.Config().AgentStream(), usefulVersion, ) m, _, _ := s.primeAgent(c, state.JobManageModel) a := s.newAgent(c, m) defer a.Stop() go func() { c.Check(a.Run(nil), jc.ErrorIsNil) }() // Add one unit to a service; charm := s.AddTestingCharm(c, "dummy") svc := s.AddTestingService(c, "test-service", charm) units, err := juju.AddUnits(s.State, svc, svc.Name(), 1, nil) c.Assert(err, jc.ErrorIsNil) m, instId := s.waitProvisioned(c, units[0]) insts, err := s.Environ.Instances([]instance.Id{instId}) c.Assert(err, jc.ErrorIsNil) addrs := network.NewAddresses("1.2.3.4") dummy.SetInstanceAddresses(insts[0], addrs) dummy.SetInstanceStatus(insts[0], "running") for attempt := coretesting.LongAttempt.Start(); attempt.Next(); { if !attempt.HasNext() { c.Logf("final machine addresses: %#v", m.Addresses()) c.Fatalf("timed out waiting for machine to get address") } err := m.Refresh() c.Assert(err, jc.ErrorIsNil) instStatus, err := m.InstanceStatus() c.Assert(err, jc.ErrorIsNil) c.Logf("found status is %q %q", instStatus.Status, instStatus.Message) if reflect.DeepEqual(m.Addresses(), addrs) && instStatus.Message == "running" { c.Logf("machine %q address updated: %+v", m.Id(), addrs) break } c.Logf("waiting for machine %q address to be updated", m.Id()) } }
// addServiceUnits adds a given number of units to a service. func addServiceUnits(state *state.State, args params.AddServiceUnits) ([]*state.Unit, error) { service, err := state.Service(args.ServiceName) if err != nil { return nil, err } if args.NumUnits < 1 { return nil, fmt.Errorf("must add at least one unit") } if args.NumUnits > 1 && args.ToMachineSpec != "" { return nil, fmt.Errorf("cannot use NumUnits with ToMachineSpec") } if args.ToMachineSpec != "" && names.IsValidMachine(args.ToMachineSpec) { _, err = state.Machine(args.ToMachineSpec) if err != nil { return nil, errors.Annotatef(err, `cannot add units for service "%v" to machine %v`, args.ServiceName, args.ToMachineSpec) } } return jjj.AddUnits(state, service, args.NumUnits, args.ToMachineSpec) }
func (s *ConnSuite) TestAddUnits(c *gc.C) { withNets := []string{"net1", "net2"} withoutNets := []string{"net3", "net4"} curl := charmtesting.Charms.ClonedURL(s.repo.Path, "quantal", "riak") sch, err := s.conn.PutCharm(curl, s.repo, false) c.Assert(err, gc.IsNil) svc, err := s.conn.State.AddService("testriak", "user-admin", sch, withNets) c.Assert(err, gc.IsNil) err = svc.SetConstraints(constraints.MustParse("networks=^" + strings.Join(withoutNets, ",^"))) c.Assert(err, gc.IsNil) units, err := juju.AddUnits(s.conn.State, svc, 2, "") c.Assert(err, gc.IsNil) c.Assert(units, gc.HasLen, 2) s.assertAssignedMachineRequestedNetworks(c, units[0], withNets, withoutNets) s.assertAssignedMachineRequestedNetworks(c, units[1], withNets, withoutNets) id0, err := units[0].AssignedMachineId() c.Assert(err, gc.IsNil) id1, err := units[1].AssignedMachineId() c.Assert(err, gc.IsNil) c.Assert(id0, gc.Not(gc.Equals), id1) units, err = juju.AddUnits(s.conn.State, svc, 2, "0") c.Assert(err, gc.ErrorMatches, `cannot add multiple units of service "testriak" to a single machine`) units, err = juju.AddUnits(s.conn.State, svc, 1, "0") c.Assert(err, gc.IsNil) s.assertAssignedMachineRequestedNetworks(c, units[0], withNets, withoutNets) id2, err := units[0].AssignedMachineId() c.Assert(id2, gc.Equals, id0) units, err = juju.AddUnits(s.conn.State, svc, 1, "lxc:0") c.Assert(err, gc.IsNil) s.assertAssignedMachineRequestedNetworks(c, units[0], withNets, withoutNets) id3, err := units[0].AssignedMachineId() c.Assert(id3, gc.Equals, id0+"/lxc/0") units, err = juju.AddUnits(s.conn.State, svc, 1, "lxc:"+id3) c.Assert(err, gc.IsNil) s.assertAssignedMachineRequestedNetworks(c, units[0], withNets, withoutNets) id4, err := units[0].AssignedMachineId() c.Assert(id4, gc.Equals, id0+"/lxc/0/lxc/0") // Check that all but the first colon is left alone. _, err = juju.AddUnits(s.conn.State, svc, 1, "lxc:"+strings.Replace(id3, "/", ":", -1)) c.Assert(err, gc.ErrorMatches, `invalid force machine id ".*"`) }
func (s *MachineSuite) TestManageEnvironRunsInstancePoller(c *gc.C) { s.agentSuite.PatchValue(&instancepoller.ShortPoll, 500*time.Millisecond) usefulVersion := version.Current usefulVersion.Series = "quantal" // to match the charm created below envtesting.AssertUploadFakeToolsVersions(c, s.Environ.Storage(), usefulVersion) m, _, _ := s.primeAgent(c, version.Current, state.JobManageEnviron) a := s.newAgent(c, m) defer a.Stop() go func() { c.Check(a.Run(nil), gc.IsNil) }() // Add one unit to a service; charm := s.AddTestingCharm(c, "dummy") svc := s.AddTestingService(c, "test-service", charm) units, err := juju.AddUnits(s.State, svc, 1, "") c.Assert(err, gc.IsNil) m, instId := s.waitProvisioned(c, units[0]) insts, err := s.Environ.Instances([]instance.Id{instId}) c.Assert(err, gc.IsNil) addrs := []network.Address{network.NewAddress("1.2.3.4", network.ScopeUnknown)} dummy.SetInstanceAddresses(insts[0], addrs) dummy.SetInstanceStatus(insts[0], "running") for a := coretesting.LongAttempt.Start(); a.Next(); { if !a.HasNext() { c.Logf("final machine addresses: %#v", m.Addresses()) c.Fatalf("timed out waiting for machine to get address") } err := m.Refresh() c.Assert(err, gc.IsNil) instStatus, err := m.InstanceStatus() c.Assert(err, gc.IsNil) if reflect.DeepEqual(m.Addresses(), addrs) && instStatus == "running" { break } } }
func (t *LiveTests) TestBootstrapAndDeploy(c *gc.C) { if !t.CanOpenState || !t.HasProvisioner { c.Skip(fmt.Sprintf("skipping provisioner test, CanOpenState: %v, HasProvisioner: %v", t.CanOpenState, t.HasProvisioner)) } t.BootstrapOnce(c) // TODO(niemeyer): Stop growing this kitchen sink test and split it into proper parts. c.Logf("opening state") st := t.Env.(testing.GetStater).GetStateInAPIServer() c.Logf("opening API connection") apiState, err := juju.NewAPIState(t.Env, api.DefaultDialOpts()) c.Assert(err, gc.IsNil) defer apiState.Close() // Check that the agent version has made it through the // bootstrap process (it's optional in the config.Config) cfg, err := st.EnvironConfig() c.Assert(err, gc.IsNil) agentVersion, ok := cfg.AgentVersion() c.Check(ok, gc.Equals, true) c.Check(agentVersion, gc.Equals, version.Current.Number) // Check that the constraints have been set in the environment. cons, err := st.EnvironConstraints() c.Assert(err, gc.IsNil) c.Assert(cons.String(), gc.Equals, "mem=2048M") // Wait for machine agent to come up on the bootstrap // machine and find the deployed series from that. m0, err := st.Machine("0") c.Assert(err, gc.IsNil) instId0, err := m0.InstanceId() c.Assert(err, gc.IsNil) // Check that the API connection is working. status, err := apiState.Client().Status(nil) c.Assert(err, gc.IsNil) c.Assert(status.Machines["0"].InstanceId, gc.Equals, string(instId0)) mw0 := newMachineToolWaiter(m0) defer mw0.Stop() // If the series has not been specified, we expect the most recent Ubuntu LTS release to be used. expectedVersion := version.Current expectedVersion.Series = config.LatestLtsSeries() mtools0 := waitAgentTools(c, mw0, expectedVersion) // Create a new service and deploy a unit of it. c.Logf("deploying service") repoDir := c.MkDir() url := charmtesting.Charms.ClonedURL(repoDir, mtools0.Version.Series, "dummy") sch, err := testing.PutCharm(st, url, &charm.LocalRepository{Path: repoDir}, false) c.Assert(err, gc.IsNil) svc, err := st.AddService("dummy", "user-admin", sch, nil) c.Assert(err, gc.IsNil) units, err := juju.AddUnits(st, svc, 1, "") c.Assert(err, gc.IsNil) unit := units[0] // Wait for the unit's machine and associated agent to come up // and announce itself. mid1, err := unit.AssignedMachineId() c.Assert(err, gc.IsNil) m1, err := st.Machine(mid1) c.Assert(err, gc.IsNil) mw1 := newMachineToolWaiter(m1) defer mw1.Stop() waitAgentTools(c, mw1, mtools0.Version) err = m1.Refresh() c.Assert(err, gc.IsNil) instId1, err := m1.InstanceId() c.Assert(err, gc.IsNil) uw := newUnitToolWaiter(unit) defer uw.Stop() utools := waitAgentTools(c, uw, expectedVersion) // Check that we can upgrade the environment. newVersion := utools.Version newVersion.Patch++ t.checkUpgrade(c, st, newVersion, mw0, mw1, uw) // BUG(niemeyer): Logic below is very much wrong. Must be: // // 1. EnsureDying on the unit and EnsureDying on the machine // 2. Unit dies by itself // 3. Machine removes dead unit // 4. Machine dies by itself // 5. Provisioner removes dead machine // // Now remove the unit and its assigned machine and // check that the PA removes it. c.Logf("removing unit") err = unit.Destroy() c.Assert(err, gc.IsNil) // Wait until unit is dead uwatch := unit.Watch() defer uwatch.Stop() for unit.Life() != state.Dead { c.Logf("waiting for unit change") <-uwatch.Changes() err := unit.Refresh() c.Logf("refreshed; err %v", err) if errors.IsNotFound(err) { c.Logf("unit has been removed") break } c.Assert(err, gc.IsNil) } for { c.Logf("destroying machine") err := m1.Destroy() if err == nil { break } c.Assert(err, gc.FitsTypeOf, &state.HasAssignedUnitsError{}) time.Sleep(5 * time.Second) err = m1.Refresh() if errors.IsNotFound(err) { break } c.Assert(err, gc.IsNil) } c.Logf("waiting for instance to be removed") t.assertStopInstance(c, t.Env, instId1) }