func addToolsVersionForMachine(machine description.Machine, usedVersions map[version.Binary]bool) { tools := machine.Tools() usedVersions[tools.Version()] = true for _, container := range machine.Containers() { addToolsVersionForMachine(container, usedVersions) } }
func (i *importer) machinePortsOps(m description.Machine) []txn.Op { var result []txn.Op machineId := m.Id() for _, ports := range m.NetworkPorts() { networkName := ports.NetworkName() doc := &portsDoc{ MachineID: machineId, NetworkName: networkName, } for _, opened := range ports.OpenPorts() { doc.Ports = append(doc.Ports, PortRange{ UnitName: opened.UnitName(), FromPort: opened.FromPort(), ToPort: opened.ToPort(), Protocol: opened.Protocol(), }) } result = append(result, txn.Op{ C: openedPortsC, Id: portsGlobalKey(machineId, networkName), Assert: txn.DocMissing, Insert: doc, }) } return result }
func (i *importer) importMachineBlockDevices(machine *Machine, m description.Machine) error { var devices []BlockDeviceInfo for _, device := range m.BlockDevices() { devices = append(devices, BlockDeviceInfo{ DeviceName: device.Name(), DeviceLinks: device.Links(), Label: device.Label(), UUID: device.UUID(), HardwareId: device.HardwareID(), BusAddress: device.BusAddress(), Size: device.Size(), FilesystemType: device.FilesystemType(), InUse: device.InUse(), MountPoint: device.MountPoint(), }) } if err := machine.SetMachineBlockDevices(devices...); err != nil { return errors.Trace(err) } return nil }
func (i *importer) makeMachineDoc(m description.Machine) (*machineDoc, error) { id := m.Id() supported, supportedSet := m.SupportedContainers() supportedContainers := make([]instance.ContainerType, len(supported)) for j, c := range supported { supportedContainers[j] = instance.ContainerType(c) } jobs, err := i.makeMachineJobs(m.Jobs()) if err != nil { return nil, errors.Trace(err) } return &machineDoc{ DocID: i.st.docID(id), Id: id, ModelUUID: i.st.ModelUUID(), Nonce: m.Nonce(), Series: m.Series(), ContainerType: m.ContainerType(), Principals: nil, // TODO Life: Alive, Tools: i.makeTools(m.Tools()), Jobs: jobs, NoVote: true, // State servers can't be migrated yet. HasVote: false, // State servers can't be migrated yet. PasswordHash: m.PasswordHash(), Clean: true, // check this later Addresses: i.makeAddresses(m.ProviderAddresses()), MachineAddresses: i.makeAddresses(m.MachineAddresses()), PreferredPrivateAddress: i.makeAddress(m.PreferredPrivateAddress()), PreferredPublicAddress: i.makeAddress(m.PreferredPublicAddress()), SupportedContainersKnown: supportedSet, SupportedContainers: supportedContainers, Placement: m.Placement(), }, nil }
func (i *importer) machine(m description.Machine) error { // Import this machine, then import its containers. i.logger.Debugf("importing machine %s", m.Id()) // 1. construct a machineDoc mdoc, err := i.makeMachineDoc(m) if err != nil { return errors.Annotatef(err, "machine %s", m.Id()) } // 2. construct enough MachineTemplate to pass into 'insertNewMachineOps' // - adds constraints doc // - adds status doc // - adds requested network doc // - adds machine block devices doc // TODO: consider filesystems and volumes mStatus := m.Status() if mStatus == nil { return errors.NotValidf("missing status") } machineStatusDoc := statusDoc{ ModelUUID: i.st.ModelUUID(), Status: status.Status(mStatus.Value()), StatusInfo: mStatus.Message(), StatusData: mStatus.Data(), Updated: mStatus.Updated().UnixNano(), } // XXX(mjs) - this needs to be included in the serialized model // (a card exists for the work). Fake it for now. instanceStatusDoc := statusDoc{ ModelUUID: i.st.ModelUUID(), Status: status.StatusStarted, } cons := i.constraints(m.Constraints()) networks := []string{} prereqOps, machineOp := i.st.baseNewMachineOps(mdoc, machineStatusDoc, instanceStatusDoc, cons, networks) // 3. create op for adding in instance data if instance := m.Instance(); instance != nil { prereqOps = append(prereqOps, i.machineInstanceOp(mdoc, instance)) } if parentId := ParentId(mdoc.Id); parentId != "" { prereqOps = append(prereqOps, // Update containers record for host machine. i.st.addChildToContainerRefOp(parentId, mdoc.Id), ) } // insertNewContainerRefOp adds an empty doc into the containerRefsC // collection for the machine being added. prereqOps = append(prereqOps, i.st.insertNewContainerRefOp(mdoc.Id)) // 4. gather prereqs and machine op, run ops. ops := append(prereqOps, machineOp) // 5. add any ops that we may need to add the opened ports information. ops = append(ops, i.machinePortsOps(m)...) if err := i.st.runTransaction(ops); err != nil { return errors.Trace(err) } machine := newMachine(i.st, mdoc) if annotations := m.Annotations(); len(annotations) > 0 { if err := i.st.SetAnnotations(machine, annotations); err != nil { return errors.Trace(err) } } if err := i.importStatusHistory(machine.globalKey(), m.StatusHistory()); err != nil { return errors.Trace(err) } // Now that this machine exists in the database, process each of the // containers in this machine. for _, container := range m.Containers() { if err := i.machine(container); err != nil { return errors.Annotate(err, container.Id()) } } return nil }
func (e *exporter) newMachine(exParent description.Machine, machine *Machine, instances map[string]instanceData, portsData []portsDoc) (description.Machine, error) { args := description.MachineArgs{ Id: machine.MachineTag(), Nonce: machine.doc.Nonce, PasswordHash: machine.doc.PasswordHash, Placement: machine.doc.Placement, Series: machine.doc.Series, ContainerType: machine.doc.ContainerType, } if supported, ok := machine.SupportedContainers(); ok { containers := make([]string, len(supported)) for i, containerType := range supported { containers[i] = string(containerType) } args.SupportedContainers = &containers } for _, job := range machine.Jobs() { args.Jobs = append(args.Jobs, job.MigrationValue()) } // A null value means that we don't yet know which containers // are supported. An empty slice means 'no containers are supported'. var exMachine description.Machine if exParent == nil { exMachine = e.model.AddMachine(args) } else { exMachine = exParent.AddContainer(args) } exMachine.SetAddresses( e.newAddressArgsSlice(machine.doc.MachineAddresses), e.newAddressArgsSlice(machine.doc.Addresses)) exMachine.SetPreferredAddresses( e.newAddressArgs(machine.doc.PreferredPublicAddress), e.newAddressArgs(machine.doc.PreferredPrivateAddress)) // We fully expect the machine to have tools set, and that there is // some instance data. instData, found := instances[machine.doc.Id] if !found { return nil, errors.NotValidf("missing instance data for machine %s", machine.Id()) } exMachine.SetInstance(e.newCloudInstanceArgs(instData)) // Find the current machine status. globalKey := machine.globalKey() statusArgs, err := e.statusArgs(globalKey) if err != nil { return nil, errors.Annotatef(err, "status for machine %s", machine.Id()) } exMachine.SetStatus(statusArgs) exMachine.SetStatusHistory(e.statusHistoryArgs(globalKey)) tools, err := machine.AgentTools() if err != nil { // This means the tools aren't set, but they should be. return nil, errors.Trace(err) } exMachine.SetTools(description.AgentToolsArgs{ Version: tools.Version, URL: tools.URL, SHA256: tools.SHA256, Size: tools.Size, }) for _, args := range e.networkPortsArgsForMachine(machine.Id(), portsData) { exMachine.AddNetworkPorts(args) } exMachine.SetAnnotations(e.getAnnotations(globalKey)) constraintsArgs, err := e.constraintsArgs(globalKey) if err != nil { return nil, errors.Trace(err) } exMachine.SetConstraints(constraintsArgs) return exMachine, nil }