// addMachineInsideMachineOps returns operations to add a machine inside
// a container of the given type on an existing machine.
329673
func (st *State) addMachineInsideMachineOps(template MachineTemplate, parentId string, containerType instance.ContainerType) (*machineDoc, []txn.Op, error) {
	if template.InstanceId != "" {
		return nil, nil, errors.New("cannot specify instance id for a new container")
	}
	template, err := st.effectiveMachineTemplate(template, false)
	if err != nil {
		return nil, nil, err
	}
	if containerType == "" {
		return nil, nil, errors.New("no container type specified")
	}

	// If a parent machine is specified, make sure it exists
	// and can support the requested container type.
	parent, err := st.Machine(parentId)
	if err != nil {
		return nil, nil, err
	}
	if !parent.supportsContainerType(containerType) {
		return nil, nil, errors.Errorf("machine %s cannot host %s containers", parentId, containerType)
	}

	// Ensure that the machine is not locked for series-upgrade.
	locked, err := parent.IsLockedForSeriesUpgrade()
	if err != nil {
		return nil, nil, err
	}
	if locked {
		return nil, nil, errors.Errorf("machine %s is locked for series upgrade", parentId)
	}

	newId, err := st.newContainerId(parentId, containerType)
	if err != nil {
		return nil, nil, err
	}
	mdoc := st.machineDocForTemplate(template, newId)
	mdoc.ContainerType = string(containerType)
	prereqOps, machineOp, err := st.insertNewMachineOps(mdoc, template)
	if err != nil {
		return nil, nil, errors.Trace(err)
	}
	prereqOps = append(prereqOps,
		// Update containers record for host machine.
		addChildToContainerRefOp(st, parentId, mdoc.Id),
		// Create a containers reference document for the container itself.
		insertNewContainerRefOp(st, mdoc.Id),
	)
	return mdoc, append(prereqOps, machineOp), nil
}
1210134
func (v VirtualMachine) AddDevice(ctx context.Context, device ...types.BaseVirtualDevice) error {
	return v.configureDevice(ctx, types.VirtualDeviceConfigSpecOperationAdd, types.VirtualDeviceConfigSpecFileOperationCreate, device...)
}
946706
func ApplicationMachines(st *State, application string) ([]string, error) {
	machines, err := st.AllMachines()
	if err != nil {
		return nil, err
	}
	applicationName := unitAppName(application)
	var machineIds []string
	for _, machine := range machines {
		principalSet := set.NewStrings()
		for _, principal := range machine.Principals() {
			principalSet.Add(unitAppName(principal))
		}
		if principalSet.Contains(applicationName) {
			machineIds = append(machineIds, machine.Id())
		}
	}
	return machineIds, nil
}
820201
func (*Service) UpdateMachine(c context.Context, req *crimson.UpdateMachineRequest) (*crimson.Machine, error) {
	return updateMachine(c, req.Machine, req.UpdateMask)
}
1059483
func (c *Client) AddMachinesV2(args params.AddMachines) (params.AddMachinesResults, error) {
	results := params.AddMachinesResults{
		Machines: make([]params.AddMachinesResult, len(args.MachineParams)),
	}
	if err := c.check.ChangeAllowed(); err != nil {
		return results, errors.Trace(err)
	}
	for i, p := range args.MachineParams {
		m, err := c.addOneMachine(p)
		results.Machines[i].Error = common.ServerError(err)
		if err == nil {
			results.Machines[i].Machine = m.Id()
		}
	}
	return results, nil
}
118419
func (m *Machine) SetMachineBlockDevices(info ...BlockDeviceInfo) error {
	return setMachineBlockDevices(m.st, m.Id(), info)
}
586505
func (c *Conn) RegisterMachine(name string, id []byte, service string, class string, pid int, root_directory string) error {
	return c.object.Call(dbusInterface+".RegisterMachine", 0, name, id, service, class, uint32(pid), root_directory).Err
}
584327
func (st *State) AddMachineInsideNewMachine(template, parentTemplate MachineTemplate, containerType instance.ContainerType) (*Machine, error) {
	mdoc, ops, err := st.addMachineInsideNewMachineOps(template, parentTemplate, containerType)
	if err != nil {
		return nil, errors.Annotate(err, "cannot add a new machine")
	}
	return st.addMachine(mdoc, ops)
}
1152525
func (m *Module) AddController(ct *ControllerType) {
	m.ControllerTypeList = append(m.ControllerTypeList, ct)
}
310910
func (sb *storageBackend) removeMachineFilesystemsOps(m *Machine) ([]txn.Op, error) {
	// A machine cannot transition to Dead if it has any detachable storage
	// attached, so any attachments are for machine-bound storage.
	//
	// Even if a filesystem is "non-detachable", there still exist filesystem
	// attachments, and they may be removed independently of the filesystem.
	// For example, the user may request that the filesystem be destroyed.
	// This will cause the filesystem to become Dying, and the attachment
	// to be Dying, then Dead, and finally removed. Only once the attachment
	// is removed will the filesystem transition to Dead and then be removed.
	// Therefore, there may be filesystems that are bound, but not attached,
	// to the machine.
	machineFilesystems, err := sb.filesystems(bson.D{{"hostid", m.Id()}})
	if err != nil {
		return nil, errors.Trace(err)
	}
	ops := make([]txn.Op, 0, 2*len(machineFilesystems)+len(m.doc.Filesystems))
	for _, filesystemId := range m.doc.Filesystems {
		ops = append(ops, txn.Op{
			C:      filesystemAttachmentsC,
			Id:     filesystemAttachmentId(m.Id(), filesystemId),
			Assert: txn.DocExists,
			Remove: true,
		})
	}
	for _, f := range machineFilesystems {
		if f.doc.StorageId != "" {
			// The volume is assigned to a storage instance;
			// make sure we also remove the storage instance.
			// There should be no storage attachments remaining,
			// as the units must have been removed before the
			// machine can be; and the storage attachments must
			// have been removed before the unit can be.
			ops = append(ops,
				txn.Op{
					C:      storageInstancesC,
					Id:     f.doc.StorageId,
					Assert: txn.DocExists,
					Remove: true,
				},
			)
		}
		fsOps, err := removeFilesystemOps(sb, f, f.doc.Releasing, nil)
		if err != nil {
			return nil, errors.Trace(err)
		}
		ops = append(ops, fsOps...)
	}
	return ops, nil
}
263235
func (c *CloudAPI) AddMachineTags(machineID string, tags map[string]string) (map[string]string, error) {
	machine, err := c.GetMachine(machineID)
	if err != nil {
		return nil, err
	}

	for tag, value := range tags {
		if _, present := machine.Tags[tag]; !present {
			machine.Tags[tag] = value
		}
	}

	return machine.Tags, nil
}
295294
func (st *State) AddMachine(series string, jobs ...MachineJob) (*Machine, error) {
	ms, err := st.AddMachines(MachineTemplate{
		Series: series,
		Jobs:   jobs,
	})
	if err != nil {
		return nil, err
	}
	return ms[0], nil
}
1017827
func (u *Unit) noAssignedMachineOp() txn.Op {
	id := u.doc.DocID
	if u.doc.Principal != "" {
		id = u.doc.Principal
	}
	return txn.Op{
		C:      unitsC,
		Id:     id,
		Assert: bson.D{{"machineid", ""}},
	}
}
1360771
func WithMachineID(machineID int) IDGeneratorOp {
	return func(g *IDGenerator) {
		g.Generator = snowflake.New(machineID & 1023)
	}
}
1154708
func (m *Model) removeMachine(ch RemoveMachine) error {
	defer m.doLocked()()

	machine, ok := m.machines[ch.Id]
	if ok {
		m.hub.Publish(m.topic(modelAddRemoveMachine), []string{ch.Id})
		if err := machine.evict(); err != nil {
			return errors.Trace(err)
		}
		delete(m.machines, ch.Id)
	}
	return nil
}
1125487
func (st *State) effectiveMachineTemplate(p MachineTemplate, allowController bool) (tmpl MachineTemplate, err error) {
	// First check for obvious errors.
	if p.Series == "" {
		return tmpl, errors.New("no series specified")
	}
	if p.InstanceId != "" {
		if p.Nonce == "" {
			return tmpl, errors.New("cannot add a machine with an instance id and no nonce")
		}
	} else if p.Nonce != "" {
		return tmpl, errors.New("cannot specify a nonce without an instance id")
	}

	// We ignore all constraints if there's a placement directive.
	if p.Placement == "" {
		p.Constraints, err = st.resolveMachineConstraints(p.Constraints)
		if err != nil {
			return tmpl, err
		}
	}

	if len(p.Jobs) == 0 {
		return tmpl, errors.New("no jobs specified")
	}
	jset := make(map[MachineJob]bool)
	for _, j := range p.Jobs {
		if jset[j] {
			return MachineTemplate{}, errors.Errorf("duplicate job: %s", j)
		}
		jset[j] = true
	}
	if jset[JobManageModel] {
		if !allowController {
			return tmpl, errControllerNotAllowed
		}
	}
	return p, nil
}
541028
func (c *CloudAPI) ListMachines(filters map[string]string) ([]*cloudapi.Machine, error) {
	if err := c.ProcessFunctionHook(c, filters); err != nil {
		return nil, err
	}

	availableMachines := c.machines

	if filters != nil {
		for k, f := range filters {
			// check if valid filter
			if contains(machinesFilters, k) {
				machines := []*machine{}
				// filter from availableMachines and add to machines
				for _, m := range availableMachines {
					if k == "name" && m.Name == f {
						machines = append(machines, m)
					} else if k == "type" && m.Type == f {
						machines = append(machines, m)
					} else if k == "state" && m.State == f {
						machines = append(machines, m)
					} else if k == "image" && m.Image == f {
						machines = append(machines, m)
					} else if k == "memory" {
						i, err := strconv.Atoi(f)
						if err == nil && m.Memory == i {
							machines = append(machines, m)
						}
					} else if strings.HasPrefix(k, "tags.") {
						for t, v := range m.Tags {
							if t == k[strings.Index(k, ".")+1:] && v == f {
								machines = append(machines, m)
							}
						}
					}
				}
				availableMachines = machines
			}
		}
	}

	out := make([]*cloudapi.Machine, len(availableMachines))
	for i, machine := range availableMachines {
		out[i] = &machine.Machine
	}

	return out, nil
}