func (s *BootstrapSuite) TestSetConstraints(c *C) { tcons := constraints.Value{Mem: uint64p(2048), CpuCores: uint64p(2)} _, cmd, err := s.initBootstrapCommand(c, "--env-config", testConfig, "--constraints", tcons.String()) 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), Password: testPasswordHash(), }, state.DefaultDialOpts()) c.Assert(err, IsNil) defer st.Close() cons, err := st.EnvironConstraints() c.Assert(err, IsNil) c.Assert(cons, DeepEquals, tcons) machines, err := st.AllMachines() c.Assert(err, IsNil) c.Assert(machines, HasLen, 1) cons, err = machines[0].Constraints() c.Assert(err, IsNil) c.Assert(cons, DeepEquals, tcons) }
func (st *State) addMachineOps(mdoc *machineDoc, metadata *instanceData, cons constraints.Value, containerParams *containerRefParams) (*machineDoc, []txn.Op, error) { if mdoc.Series == "" { return nil, nil, fmt.Errorf("no series specified") } if len(mdoc.Jobs) == 0 { return nil, nil, fmt.Errorf("no jobs specified") } if containerParams.hostId != "" && mdoc.ContainerType == "" { return nil, nil, fmt.Errorf("no container type specified") } jset := make(map[MachineJob]bool) for _, j := range mdoc.Jobs { if jset[j] { return nil, nil, fmt.Errorf("duplicate job: %s", j) } jset[j] = true } if containerParams.hostId == "" { // we are creating a new machine instance (not a container). seq, err := st.sequence("machine") if err != nil { return nil, nil, err } mdoc.Id = strconv.Itoa(seq) containerParams.hostId = mdoc.Id containerParams.newHost = true } if mdoc.ContainerType != "" { // we are creating a container so set up a namespaced id. seq, err := st.sequence(fmt.Sprintf("machine%s%sContainer", containerParams.hostId, mdoc.ContainerType)) if err != nil { return nil, nil, err } mdoc.Id = fmt.Sprintf("%s/%s/%d", containerParams.hostId, mdoc.ContainerType, seq) containerParams.containerId = mdoc.Id } mdoc.Life = Alive sdoc := statusDoc{ Status: params.StatusPending, } // Machine constraints do not use a container constraint value. // Both provisioning and deployment constraints use the same constraints.Value struct // so here we clear the container value. Provisioning ignores the container value but // clearing it avoids potential confusion. cons.Container = nil ops := []txn.Op{ { C: st.machines.Name, Id: mdoc.Id, Assert: txn.DocMissing, Insert: *mdoc, }, createConstraintsOp(st, machineGlobalKey(mdoc.Id), cons), createStatusOp(st, machineGlobalKey(mdoc.Id), sdoc), } if metadata != nil { ops = append(ops, txn.Op{ C: st.instanceData.Name, Id: mdoc.Id, Assert: txn.DocMissing, Insert: *metadata, }) } ops = append(ops, createContainerRefOp(st, containerParams)...) return mdoc, ops, nil }