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 }