// startUnit creates a new data value for tracking details of the // unit and starts watching the unit for port changes. The provided // machineId must be the id for the machine the unit was last observed // to be assigned to. func (fw *Firewaller) startUnit(unit *state.Unit, machineId string) error { service, err := unit.Service() if err != nil { return err } serviceName := service.Name() unitName := unit.Name() unitd := &unitData{ fw: fw, unit: unit, ports: unit.OpenedPorts(), } fw.unitds[unitName] = unitd unitd.machined = fw.machineds[machineId] unitd.machined.unitds[unitName] = unitd if fw.serviceds[serviceName] == nil { err := fw.startService(service) if err != nil { delete(fw.unitds, unitName) return err } } unitd.serviced = fw.serviceds[serviceName] unitd.serviced.unitds[unitName] = unitd ports := make([]instance.Port, len(unitd.ports)) copy(ports, unitd.ports) go unitd.watchLoop(ports) return nil }
func (context *statusContext) processUnit(unit *state.Unit) (status unitStatus) { status.PublicAddress, _ = unit.PublicAddress() for _, port := range unit.OpenedPorts() { status.OpenedPorts = append(status.OpenedPorts, port.String()) } if unit.IsPrincipal() { status.Machine, _ = unit.AssignedMachineId() } status.Life, status.AgentVersion, status.AgentState, status.AgentStateInfo, status.Err = processAgent(unit) if subUnits := unit.SubordinateNames(); len(subUnits) > 0 { status.Subordinates = make(map[string]unitStatus) for _, name := range subUnits { subUnit := context.unitByName(name) // subUnit may be nil if subordinate was filtered out. if subUnit != nil { status.Subordinates[name] = context.processUnit(subUnit) } } } return }