func (e *exporter) setUnitPayloads(exUnit description.Unit, payloads []payload.FullPayloadInfo) error { unitID := exUnit.Tag().Id() machineID := exUnit.Machine().Id() for _, payload := range payloads { if payload.Machine != machineID { return errors.NotValidf("payload for unit %q reports wrong machine %q (should be %q)", unitID, payload.Machine, machineID) } args := description.PayloadArgs{ Name: payload.Name, Type: payload.Type, RawID: payload.ID, State: payload.Status, Labels: payload.Labels, } exUnit.AddPayload(args) } return nil }
func (i *importer) makeUnitDoc(s description.Service, u description.Unit) (*unitDoc, error) { // NOTE: if we want to support units having different charms deployed // than the service recomments and migrate that, then we should serialize // the charm url for each unit rather than grabbing the services charm url. // Currently the units charm url matching the service is a precondiation // to migration. charmUrl, err := charm.ParseURL(s.CharmURL()) if err != nil { return nil, errors.Trace(err) } var subordinates []string if subs := u.Subordinates(); len(subs) > 0 { for _, s := range subs { subordinates = append(subordinates, s.Id()) } } return &unitDoc{ Name: u.Name(), Service: s.Name(), Series: s.Series(), CharmURL: charmUrl, Principal: u.Principal().Id(), Subordinates: subordinates, // StorageAttachmentCount int `bson:"storageattachmentcount"` MachineId: u.Machine().Id(), Tools: i.makeTools(u.Tools()), Life: Alive, PasswordHash: u.PasswordHash(), }, nil }
func (i *importer) unit(s description.Service, u description.Unit) error { i.logger.Debugf("importing unit %s", u.Name()) // 1. construct a unitDoc udoc, err := i.makeUnitDoc(s, u) if err != nil { return errors.Trace(err) } // 2. construct a statusDoc for the workload status and agent status agentStatus := u.AgentStatus() if agentStatus == nil { return errors.NotValidf("missing agent status") } agentStatusDoc := i.makeStatusDoc(agentStatus) workloadStatus := u.WorkloadStatus() if workloadStatus == nil { return errors.NotValidf("missing workload status") } workloadStatusDoc := i.makeStatusDoc(workloadStatus) ops := addUnitOps(i.st, addUnitOpsArgs{ unitDoc: udoc, agentStatusDoc: agentStatusDoc, workloadStatusDoc: workloadStatusDoc, meterStatusDoc: &meterStatusDoc{ Code: u.MeterStatusCode(), Info: u.MeterStatusInfo(), }, }) // We should only have constraints for principal agents. // We don't encode that business logic here, if there are constraints // in the imported model, we put them in the database. if cons := u.Constraints(); cons != nil { agentGlobalKey := unitAgentGlobalKey(u.Name()) ops = append(ops, createConstraintsOp(i.st, agentGlobalKey, i.constraints(cons))) } if err := i.st.runTransaction(ops); err != nil { return errors.Trace(err) } unit := newUnit(i.st, udoc) if annotations := u.Annotations(); len(annotations) > 0 { if err := i.st.SetAnnotations(unit, annotations); err != nil { return errors.Trace(err) } } if err := i.importStatusHistory(unit.globalKey(), u.WorkloadStatusHistory()); err != nil { return errors.Trace(err) } if err := i.importStatusHistory(unit.globalAgentKey(), u.AgentStatusHistory()); err != nil { return errors.Trace(err) } return nil }
func (i *importer) unit(s description.Application, u description.Unit) error { i.logger.Debugf("importing unit %s", u.Name()) // 1. construct a unitDoc udoc, err := i.makeUnitDoc(s, u) if err != nil { return errors.Trace(err) } // 2. construct a statusDoc for the workload status and agent status agentStatus := u.AgentStatus() if agentStatus == nil { return errors.NotValidf("missing agent status") } agentStatusDoc := i.makeStatusDoc(agentStatus) workloadStatus := u.WorkloadStatus() if workloadStatus == nil { return errors.NotValidf("missing workload status") } workloadStatusDoc := i.makeStatusDoc(workloadStatus) workloadVersion := u.WorkloadVersion() versionStatus := status.Active if workloadVersion == "" { versionStatus = status.Unknown } workloadVersionDoc := statusDoc{ Status: versionStatus, StatusInfo: workloadVersion, } ops, err := addUnitOps(i.st, addUnitOpsArgs{ unitDoc: udoc, agentStatusDoc: agentStatusDoc, workloadStatusDoc: workloadStatusDoc, workloadVersionDoc: workloadVersionDoc, meterStatusDoc: &meterStatusDoc{ Code: u.MeterStatusCode(), Info: u.MeterStatusInfo(), }, }) if err != nil { return errors.Trace(err) } // If the unit is a principal, add it to its machine. if u.Principal().Id() == "" { ops = append(ops, txn.Op{ C: machinesC, Id: u.Machine().Id(), Assert: txn.DocExists, Update: bson.M{"$addToSet": bson.M{"principals": u.Name()}}, }) } // We should only have constraints for principal agents. // We don't encode that business logic here, if there are constraints // in the imported model, we put them in the database. if cons := u.Constraints(); cons != nil { agentGlobalKey := unitAgentGlobalKey(u.Name()) ops = append(ops, createConstraintsOp(i.st, agentGlobalKey, i.constraints(cons))) } if err := i.st.runTransaction(ops); err != nil { i.logger.Debugf("failed ops: %#v", ops) return errors.Trace(err) } unit := newUnit(i.st, udoc) if annotations := u.Annotations(); len(annotations) > 0 { if err := i.st.SetAnnotations(unit, annotations); err != nil { return errors.Trace(err) } } if err := i.importStatusHistory(unit.globalKey(), u.WorkloadStatusHistory()); err != nil { return errors.Trace(err) } if err := i.importStatusHistory(unit.globalAgentKey(), u.AgentStatusHistory()); err != nil { return errors.Trace(err) } if err := i.importStatusHistory(unit.globalWorkloadVersionKey(), u.WorkloadVersionHistory()); err != nil { return errors.Trace(err) } if err := i.importUnitPayloads(unit, u.Payloads()); err != nil { return errors.Trace(err) } return nil }