// startUnit creates a new data value for tracking details of the unit // and starts watching the unit for port changes. The provided // machineTag must be the tag for the machine the unit was last // observed to be assigned to. func (fw *Firewaller) startUnit(unit *apifirewaller.Unit, machineTag string) error { service, err := unit.Service() if err != nil { return err } serviceName := service.Name() unitName := unit.Name() openedPorts, err := unit.OpenedPorts() if err != nil { return err } unitd := &unitData{ fw: fw, unit: unit, ports: openedPorts, } fw.unitds[unitName] = unitd unitd.machined = fw.machineds[machineTag] 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([]network.Port, len(unitd.ports)) copy(ports, unitd.ports) go unitd.watchLoop(ports) return nil }