func (m *mockStorageAccessor) StorageAttachmentLife(ids []params.StorageAttachmentId) ([]params.LifeResult, error) { if m.storageAttachmentLife != nil { return m.storageAttachmentLife(ids) } results := make([]params.LifeResult, len(ids)) for i, id := range ids { storageTag, err := names.ParseStorageTag(id.StorageTag) if err != nil { results[i].Error = common.ServerError(err) continue } unitTag, err := names.ParseUnitTag(id.UnitTag) if err != nil { results[i].Error = common.ServerError(err) continue } att, err := m.storageAttachment(storageTag, unitTag) if err != nil { results[i].Error = common.ServerError(err) continue } results[i].Life = att.Life } return results, nil }
// AddMetricBatches adds the metrics for the specified unit. func (u *UniterAPIV2) AddMetricBatches(args params.MetricBatchParams) (params.ErrorResults, error) { result := params.ErrorResults{ Results: make([]params.ErrorResult, len(args.Batches)), } canAccess, err := u.accessUnit() if err != nil { logger.Warningf("failed to check unit access: %v", err) return params.ErrorResults{}, common.ErrPerm } for i, batch := range args.Batches { tag, err := names.ParseUnitTag(batch.Tag) if err != nil { result.Results[i].Error = common.ServerError(err) continue } if !canAccess(tag) { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } metrics := make([]state.Metric, len(batch.Batch.Metrics)) for j, metric := range batch.Batch.Metrics { metrics[j] = state.Metric{ Key: metric.Key, Value: metric.Value, Time: metric.Time, } } _, err = u.unit.AddMetrics(batch.Batch.UUID, batch.Batch.Created, batch.Batch.CharmURL, metrics) result.Results[i].Error = common.ServerError(err) } return result, nil }
// GetAssignedMachine returns the assigned machine tag (if any) for // each given unit. func (f *FirewallerAPI) GetAssignedMachine(args params.Entities) (params.StringResults, error) { result := params.StringResults{ Results: make([]params.StringResult, len(args.Entities)), } canAccess, err := f.accessUnit() if err != nil { return params.StringResults{}, err } for i, entity := range args.Entities { tag, err := names.ParseUnitTag(entity.Tag) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } unit, err := f.getUnit(canAccess, tag) if err == nil { var machineId string machineId, err = unit.AssignedMachineId() if err == nil { result.Results[i].Result = names.NewMachineTag(machineId).String() } } result.Results[i].Error = common.ServerError(err) } return result, nil }
func (s startUniter) step(c *gc.C, ctx *context) { if s.unitTag == "" { s.unitTag = "unit-u-0" } if ctx.uniter != nil { panic("don't start two uniters!") } if ctx.api == nil { panic("API connection not established") } tag, err := names.ParseUnitTag(s.unitTag) if err != nil { panic(err.Error()) } locksDir := filepath.Join(ctx.dataDir, "locks") lock, err := fslock.NewLock(locksDir, "uniter-hook-execution") c.Assert(err, jc.ErrorIsNil) uniterParams := uniter.UniterParams{ St: ctx.api, UnitTag: tag, LeadershipManager: ctx.leader, DataDir: ctx.dataDir, HookLock: lock, MetricsTimerChooser: uniter.NewTestingMetricsTimerChooser( ctx.collectMetricsTicker.ReturnTimer, ctx.sendMetricsTicker.ReturnTimer, ), UpdateStatusSignal: ctx.updateStatusHookTicker.ReturnTimer, NewOperationExecutor: s.newExecutorFunc, } ctx.uniter = uniter.NewUniter(&uniterParams) uniter.SetUniterObserver(ctx.uniter, ctx) }
func (c *RunCommand) Init(args []string) error { // make sure we aren't in an existing hook context if contextId, err := getenv("JUJU_CONTEXT_ID"); err == nil && contextId != "" { return fmt.Errorf("juju-run cannot be called from within a hook, have context %q", contextId) } if !c.noContext { if len(args) < 1 { return fmt.Errorf("missing unit-name") } var unitName string unitName, args = args[0], args[1:] // If the command line param is a unit id (like service/2) we need to // change it to the unit tag as that is the format of the agent directory // on disk (unit-service-2). if names.IsValidUnit(unitName) { c.unit = names.NewUnitTag(unitName) } else { var err error c.unit, err = names.ParseUnitTag(unitName) if err != nil { return errors.Trace(err) } } } if len(args) < 1 { return fmt.Errorf("missing commands") } c.commands, args = args[0], args[1:] return cmd.CheckEmpty(args) }
// AssignedMachine returns the machine tag for each given unit tag, or // an error satisfying params.IsCodeNotAssigned when a unit has no // assigned machine. func (u *UniterAPIV1) AssignedMachine(args params.Entities) (params.StringResults, error) { result := params.StringResults{ Results: make([]params.StringResult, len(args.Entities)), } canAccess, err := u.accessUnit() if err != nil { return params.StringResults{}, err } for i, entity := range args.Entities { tag, err := names.ParseUnitTag(entity.Tag) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } if !canAccess(tag) { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } unit, err := u.getUnit(tag) if err != nil { result.Results[i].Error = common.ServerError(err) continue } machineId, err := unit.AssignedMachineId() if err != nil { result.Results[i].Error = common.ServerError(err) } else { result.Results[i].Result = names.NewMachineTag(machineId).String() } } return result, nil }
// UpdateSettings persists all changes made to the local settings of // all given pairs of relation and unit. Keys with empty values are // considered a signal to delete these values. func (u *UniterAPI) UpdateSettings(args params.RelationUnitsSettings) (params.ErrorResults, error) { result := params.ErrorResults{ Results: make([]params.ErrorResult, len(args.RelationUnits)), } canAccess, err := u.accessUnit() if err != nil { return params.ErrorResults{}, err } for i, arg := range args.RelationUnits { unit, err := names.ParseUnitTag(arg.Unit) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } relUnit, err := u.getRelationUnit(canAccess, arg.Relation, unit) if err == nil { var settings *state.Settings settings, err = relUnit.Settings() if err == nil { for k, v := range arg.Settings { if v == "" { settings.Delete(k) } else { settings.Set(k, v) } } _, err = settings.Write() } } result.Results[i].Error = common.ServerError(err) } return result, nil }
// ReadSettings returns the local settings of each given set of // relation/unit. func (u *UniterAPI) ReadSettings(args params.RelationUnits) (params.RelationSettingsResults, error) { result := params.RelationSettingsResults{ Results: make([]params.RelationSettingsResult, len(args.RelationUnits)), } canAccess, err := u.accessUnit() if err != nil { return params.RelationSettingsResults{}, err } for i, arg := range args.RelationUnits { unit, err := names.ParseUnitTag(arg.Unit) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } relUnit, err := u.getRelationUnit(canAccess, arg.Relation, unit) if err == nil { var settings *state.Settings settings, err = relUnit.Settings() if err == nil { result.Results[i].Settings, err = convertRelationSettings(settings.Map()) } } result.Results[i].Error = common.ServerError(err) } return result, nil }
// ReadRemoteSettings returns the remote settings of each given set of // relation/local unit/remote unit. func (u *UniterAPI) ReadRemoteSettings(args params.RelationUnitPairs) (params.RelationSettingsResults, error) { result := params.RelationSettingsResults{ Results: make([]params.RelationSettingsResult, len(args.RelationUnitPairs)), } canAccess, err := u.accessUnit() if err != nil { return params.RelationSettingsResults{}, err } for i, arg := range args.RelationUnitPairs { unit, err := names.ParseUnitTag(arg.LocalUnit) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } relUnit, err := u.getRelationUnit(canAccess, arg.Relation, unit) if err == nil { // TODO(dfc) rework this logic remoteUnit := "" remoteUnit, err = u.checkRemoteUnit(relUnit, arg.RemoteUnit) if err == nil { var settings map[string]interface{} settings, err = relUnit.ReadSettings(remoteUnit) if err == nil { result.Results[i].Settings, err = convertRelationSettings(settings) } } } result.Results[i].Error = common.ServerError(err) } return result, nil }
// JoinedRelations returns the tags of all relations for which each supplied unit // has entered scope. It should be called RelationsInScope, but it's not convenient // to make that change until we have versioned APIs. func (u *UniterAPI) JoinedRelations(args params.Entities) (params.StringsResults, error) { result := params.StringsResults{ Results: make([]params.StringsResult, len(args.Entities)), } if len(args.Entities) == 0 { return result, nil } canRead, err := u.accessUnit() if err != nil { return params.StringsResults{}, err } for i, entity := range args.Entities { tag, err := names.ParseUnitTag(entity.Tag) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } err = common.ErrPerm if canRead(tag) { var unit *state.Unit unit, err = u.getUnit(tag) if err == nil { result.Results[i].Result, err = relationsInScopeTags(unit) } } result.Results[i].Error = common.ServerError(err) } return result, nil }
// GetMeterStatus returns meter status information for each unit. func (u *uniterBaseAPI) GetMeterStatus(args params.Entities) (params.MeterStatusResults, error) { result := params.MeterStatusResults{ Results: make([]params.MeterStatusResult, len(args.Entities)), } canAccess, err := u.accessUnit() if err != nil { return params.MeterStatusResults{}, common.ErrPerm } for i, entity := range args.Entities { unitTag, err := names.ParseUnitTag(entity.Tag) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } err = common.ErrPerm var status state.MeterStatus if canAccess(unitTag) { var unit *state.Unit unit, err = u.getUnit(unitTag) if err == nil { status, err = meterstatus.MeterStatusWrapper(unit.GetMeterStatus) } result.Results[i].Code = status.Code.String() result.Results[i].Info = status.Info } result.Results[i].Error = common.ServerError(err) } return result, nil }
// SetCharmURL sets the charm URL for each given unit. An error will // be returned if a unit is dead, or the charm URL is not know. func (u *UniterAPI) SetCharmURL(args params.EntitiesCharmURL) (params.ErrorResults, error) { result := params.ErrorResults{ Results: make([]params.ErrorResult, len(args.Entities)), } canAccess, err := u.accessUnit() if err != nil { return params.ErrorResults{}, err } for i, entity := range args.Entities { tag, err := names.ParseUnitTag(entity.Tag) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } err = common.ErrPerm if canAccess(tag) { var unit *state.Unit unit, err = u.getUnit(tag) if err == nil { var curl *charm.URL curl, err = charm.ParseURL(entity.CharmURL) if err == nil { err = unit.SetCharmURL(curl) } } } result.Results[i].Error = common.ServerError(err) } return result, nil }
// ConfigSettings returns the complete set of service charm config // settings available to each given unit. func (u *UniterAPI) ConfigSettings(args params.Entities) (params.ConfigSettingsResults, error) { result := params.ConfigSettingsResults{ Results: make([]params.ConfigSettingsResult, len(args.Entities)), } canAccess, err := u.accessUnit() if err != nil { return params.ConfigSettingsResults{}, err } for i, entity := range args.Entities { tag, err := names.ParseUnitTag(entity.Tag) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } err = common.ErrPerm if canAccess(tag) { var unit *state.Unit unit, err = u.getUnit(tag) if err == nil { var settings charm.Settings settings, err = unit.ConfigSettings() if err == nil { result.Results[i].Settings = params.ConfigSettings(settings) } } } result.Results[i].Error = common.ServerError(err) } return result, nil }
// DestroyAllSubordinates destroys all subordinates of each given unit. func (u *uniterBaseAPI) DestroyAllSubordinates(args params.Entities) (params.ErrorResults, error) { result := params.ErrorResults{ Results: make([]params.ErrorResult, len(args.Entities)), } canAccess, err := u.accessUnit() if err != nil { return params.ErrorResults{}, err } for i, entity := range args.Entities { tag, err := names.ParseUnitTag(entity.Tag) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } err = common.ErrPerm if canAccess(tag) { var unit *state.Unit unit, err = u.getUnit(tag) if err == nil { err = u.destroySubordinates(unit) } } result.Results[i].Error = common.ServerError(err) } return result, nil }
func (s *StorageAPI) watchOneStorageAttachment(id params.StorageAttachmentId, canAccess func(names.Tag) bool) (params.NotifyWatchResult, error) { // Watching a storage attachment is implemented as watching the // underlying volume or filesystem attachment. The only thing // we don't necessarily see in doing this is the lifecycle state // changes, but these may be observed by using the // WatchUnitStorageAttachments watcher. nothing := params.NotifyWatchResult{} unitTag, err := names.ParseUnitTag(id.UnitTag) if err != nil || !canAccess(unitTag) { return nothing, common.ErrPerm } storageTag, err := names.ParseStorageTag(id.StorageTag) if err != nil { return nothing, err } machineTag, err := s.st.UnitAssignedMachine(unitTag) if err != nil { return nothing, err } watch, err := common.WatchStorageAttachment(s.st, storageTag, machineTag, unitTag) if err != nil { return nothing, errors.Trace(err) } if _, ok := <-watch.Changes(); ok { return params.NotifyWatchResult{ NotifyWatcherId: s.resources.Register(watch), }, nil } return nothing, watcher.EnsureErr(watch) }
func (s startUniter) step(c *gc.C, ctx *context) { if s.unitTag == "" { s.unitTag = "unit-u-0" } if ctx.uniter != nil { panic("don't start two uniters!") } if ctx.api == nil { panic("API connection not established") } tag, err := names.ParseUnitTag(s.unitTag) if err != nil { panic(err.Error()) } locksDir := filepath.Join(ctx.dataDir, "locks") lock, err := fslock.NewLock(locksDir, "uniter-hook-execution") c.Assert(err, jc.ErrorIsNil) operationExecutor := operation.NewExecutor if s.newExecutorFunc != nil { operationExecutor = s.newExecutorFunc } uniterParams := uniter.UniterParams{ UniterFacade: ctx.api, UnitTag: tag, LeadershipTracker: ctx.leaderTracker, CharmDirLocker: ctx.charmDirLocker, DataDir: ctx.dataDir, MachineLock: lock, UpdateStatusSignal: ctx.updateStatusHookTicker.ReturnTimer, NewOperationExecutor: operationExecutor, Observer: ctx, } ctx.uniter = uniter.NewUniter(&uniterParams) }
// PrivateAddress returns the private address for each given unit, if set. func (u *uniterBaseAPI) PrivateAddress(args params.Entities) (params.StringResults, error) { result := params.StringResults{ Results: make([]params.StringResult, len(args.Entities)), } canAccess, err := u.accessUnit() if err != nil { return params.StringResults{}, err } for i, entity := range args.Entities { tag, err := names.ParseUnitTag(entity.Tag) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } err = common.ErrPerm if canAccess(tag) { var unit *state.Unit unit, err = u.getUnit(tag) if err == nil { var address network.Address address, err = unit.PrivateAddress() if err == nil { result.Results[i].Result = address.Value } else if network.IsNoAddress(err) { err = common.NoAddressSetError(tag, "private") } } } result.Results[i].Error = common.ServerError(err) } return result, nil }
// AddMetricBatches implements the MetricsAdder interface. func (api *MetricsAdderAPI) AddMetricBatches(args params.MetricBatchParams) (params.ErrorResults, error) { result := params.ErrorResults{ Results: make([]params.ErrorResult, len(args.Batches)), } for i, batch := range args.Batches { tag, err := names.ParseUnitTag(batch.Tag) if err != nil { result.Results[i].Error = common.ServerError(err) continue } metrics := make([]state.Metric, len(batch.Batch.Metrics)) for j, metric := range batch.Batch.Metrics { metrics[j] = state.Metric{ Key: metric.Key, Value: metric.Value, Time: metric.Time, } } _, err = api.state.AddMetrics( state.BatchParam{ UUID: batch.Batch.UUID, Created: batch.Batch.Created, CharmURL: batch.Batch.CharmURL, Metrics: metrics, Unit: tag, }, ) result.Results[i].Error = common.ServerError(err) } return result, nil }
// API2Payload converts an API Payload info struct into // a payload.FullPayloadInfo struct. func API2Payload(apiInfo Payload) (payload.FullPayloadInfo, error) { labels := make([]string, len(apiInfo.Labels)) copy(labels, apiInfo.Labels) var unit, machine string var empty payload.FullPayloadInfo if apiInfo.Unit != "" { tag, err := names.ParseUnitTag(apiInfo.Unit) if err != nil { return empty, errors.Trace(err) } unit = tag.Id() } if apiInfo.Machine != "" { tag, err := names.ParseMachineTag(apiInfo.Machine) if err != nil { return empty, errors.Trace(err) } machine = tag.Id() } return payload.FullPayloadInfo{ Payload: payload.Payload{ PayloadClass: charm.PayloadClass{ Name: apiInfo.Class, Type: apiInfo.Type, }, ID: apiInfo.ID, Status: apiInfo.Status, Labels: labels, Unit: unit, }, Machine: machine, }, nil }
// OpenedPorts returns a map of network.PortRange to unit tag for all opened // port ranges on the machine for the subnet matching given subnetTag. func (m *Machine) OpenedPorts(subnetTag names.SubnetTag) (map[network.PortRange]names.UnitTag, error) { var results params.MachinePortsResults var subnetTagAsString string if subnetTag.Id() != "" { subnetTagAsString = subnetTag.String() } args := params.MachinePortsParams{ Params: []params.MachinePorts{ {MachineTag: m.tag.String(), SubnetTag: subnetTagAsString}, }, } err := m.st.facade.FacadeCall("GetMachinePorts", args, &results) if err != nil { return nil, err } if len(results.Results) != 1 { return nil, fmt.Errorf("expected 1 result, got %d", len(results.Results)) } result := results.Results[0] if result.Error != nil { return nil, result.Error } // Convert string tags to names.UnitTag before returning. endResult := make(map[network.PortRange]names.UnitTag) for _, ports := range result.Ports { unitTag, err := names.ParseUnitTag(ports.UnitTag) if err != nil { return nil, err } endResult[ports.PortRange.NetworkPortRange()] = unitTag } return endResult, nil }
// GetPrincipal returns the result of calling PrincipalName() and // converting it to a tag, on each given unit. func (u *UniterAPI) GetPrincipal(args params.Entities) (params.StringBoolResults, error) { result := params.StringBoolResults{ Results: make([]params.StringBoolResult, len(args.Entities)), } canAccess, err := u.accessUnit() if err != nil { return params.StringBoolResults{}, err } for i, entity := range args.Entities { tag, err := names.ParseUnitTag(entity.Tag) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } err = common.ErrPerm if canAccess(tag) { var unit *state.Unit unit, err = u.getUnit(tag) if err == nil { principal, ok := unit.PrincipalName() if principal != "" { result.Results[i].Result = names.NewUnitTag(principal).String() } result.Results[i].Ok = ok } } result.Results[i].Error = common.ServerError(err) } return result, nil }
func (u *UniterAPI) getUnit(tag string) (*state.Unit, error) { t, err := names.ParseUnitTag(tag) if err != nil { return nil, err } return u.st.Unit(t.Id()) }
// HasSubordinates returns the whether each given unit has any subordinates. func (u *UniterAPI) HasSubordinates(args params.Entities) (params.BoolResults, error) { result := params.BoolResults{ Results: make([]params.BoolResult, len(args.Entities)), } canAccess, err := u.accessUnit() if err != nil { return params.BoolResults{}, err } for i, entity := range args.Entities { tag, err := names.ParseUnitTag(entity.Tag) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } err = common.ErrPerm if canAccess(tag) { var unit *state.Unit unit, err = u.getUnit(tag) if err == nil { subordinates := unit.SubordinateNames() result.Results[i].Result = len(subordinates) > 0 } } result.Results[i].Error = common.ServerError(err) } return result, nil }
func (u *UniterAPIV3) checkRemoteUnit(relUnit *state.RelationUnit, remoteUnitTag string) (string, error) { // Make sure the unit is indeed remote. if remoteUnitTag == u.auth.GetAuthTag().String() { return "", common.ErrPerm } // Check remoteUnit is indeed related. Note that we don't want to actually get // the *Unit, because it might have been removed; but its relation settings will // persist until the relation itself has been removed (and must remain accessible // because the local unit's view of reality may be time-shifted). tag, err := names.ParseUnitTag(remoteUnitTag) if err != nil { return "", common.ErrPerm } remoteUnitName := tag.Id() remoteServiceName, err := names.UnitService(remoteUnitName) if err != nil { return "", common.ErrPerm } rel := relUnit.Relation() _, err = rel.RelatedEndpoints(remoteServiceName) if err != nil { return "", common.ErrPerm } return remoteUnitName, nil }
// ClosePort sets the policy of the port with protocol and number to // be closed, for all given units. func (u *UniterAPI) ClosePort(args params.EntitiesPorts) (params.ErrorResults, error) { result := params.ErrorResults{ Results: make([]params.ErrorResult, len(args.Entities)), } canAccess, err := u.accessUnit() if err != nil { return params.ErrorResults{}, err } for i, entity := range args.Entities { tag, err := names.ParseUnitTag(entity.Tag) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } err = common.ErrPerm if canAccess(tag) { var unit *state.Unit unit, err = u.getUnit(tag) if err == nil { err = unit.ClosePort(entity.Protocol, entity.Port) } } result.Results[i].Error = common.ServerError(err) } return result, nil }
// AvailabilityZone returns the availability zone for each given unit, if applicable. func (u *UniterAPIV3) AvailabilityZone(args params.Entities) (params.StringResults, error) { var results params.StringResults canAccess, err := u.accessUnit() if err != nil { return results, errors.Trace(err) } // Prep the results. results = params.StringResults{ Results: make([]params.StringResult, len(args.Entities)), } // Collect the zones. No zone will be collected for any entity where // the tag is invalid or not authorized. Instead the corresponding // result will be updated with the error. for i, entity := range args.Entities { tag, err := names.ParseUnitTag(entity.Tag) if err != nil { results.Results[i].Error = common.ServerError(common.ErrPerm) continue } err = common.ErrPerm if canAccess(tag) { var zone string zone, err = getZone(u.st, tag) if err == nil { results.Results[i].Result = zone } } results.Results[i].Error = common.ServerError(err) } return results, nil }
// PublicAddress returns the public address for each given unit, if set. func (u *UniterAPI) PublicAddress(args params.Entities) (params.StringResults, error) { result := params.StringResults{ Results: make([]params.StringResult, len(args.Entities)), } canAccess, err := u.accessUnit() if err != nil { return params.StringResults{}, err } for i, entity := range args.Entities { tag, err := names.ParseUnitTag(entity.Tag) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } err = common.ErrPerm if canAccess(tag) { var unit *state.Unit unit, err = u.getUnit(tag) if err == nil { address, ok := unit.PublicAddress() if ok { result.Results[i].Result = address } else { err = common.NoAddressSetError(tag, "public") } } } result.Results[i].Error = common.ServerError(err) } return result, nil }
// EnterScope ensures each unit has entered its scope in the relation, // for all of the given relation/unit pairs. See also // state.RelationUnit.EnterScope(). func (u *UniterAPI) EnterScope(args params.RelationUnits) (params.ErrorResults, error) { result := params.ErrorResults{ Results: make([]params.ErrorResult, len(args.RelationUnits)), } canAccess, err := u.accessUnit() if err != nil { return params.ErrorResults{}, err } for i, arg := range args.RelationUnits { tag, err := names.ParseUnitTag(arg.Unit) if err != nil { result.Results[i].Error = common.ServerError(common.ErrPerm) continue } relUnit, err := u.getRelationUnit(canAccess, arg.Relation, tag) if err == nil { // Construct the settings, passing the unit's // private address (we already know it). privateAddress, _ := relUnit.PrivateAddress() settings := map[string]interface{}{ "private-address": privateAddress, } err = relUnit.EnterScope(settings) } result.Results[i].Error = common.ServerError(err) } return result, nil }
func (s startUniter) step(c *gc.C, ctx *context) { if s.unitTag == "" { s.unitTag = "unit-u-0" } if ctx.uniter != nil { panic("don't start two uniters!") } if ctx.api == nil { panic("API connection not established") } tag, err := names.ParseUnitTag(s.unitTag) if err != nil { panic(err.Error()) } locksDir := filepath.Join(ctx.dataDir, "locks") lock, err := fslock.NewLock(locksDir, "uniter-hook-execution") c.Assert(err, jc.ErrorIsNil) uniterParams := uniter.UniterParams{ ctx.api, tag, ctx.leader, ctx.dataDir, lock, uniter.NewTestingMetricsTimerChooser(ctx.metricsTicker.ReturnTimer), ctx.updateStatusHookTicker.ReturnTimer, } ctx.uniter = uniter.NewUniter(&uniterParams) uniter.SetUniterObserver(ctx.uniter, ctx) }
func tryClosePorts( protocol string, fromPort, toPort int, unitTag names.UnitTag, machinePorts map[network.PortRange]params.RelationUnit, pendingPorts map[PortRange]PortRangeInfo, ) error { // TODO(dimitern) Once port ranges are linked to relations in // addition to networks, refactor this functions and test it // better to ensure it handles relations properly. relationId := -1 // Validate the given range. newRange, err := validatePortRange(protocol, fromPort, toPort) if err != nil { return err } rangeKey := PortRange{ Ports: newRange, RelationId: relationId, } rangeInfo, isKnown := pendingPorts[rangeKey] if isKnown { if rangeInfo.ShouldOpen { // If the same range is already pending to be opened, just // remove it from pending. delete(pendingPorts, rangeKey) } return nil } // Ensure the range we're trying to close is opened on the // machine. relUnit, found := machinePorts[newRange] if !found { // Trying to close a range which is not open is ignored. return nil } else if relUnit.Unit != unitTag.String() { relUnitTag, err := names.ParseUnitTag(relUnit.Unit) if err != nil { return errors.Annotatef( err, "machine ports %v contain invalid unit tag", newRange, ) } return errors.Errorf( "cannot close %v (opened by %q) from %q", newRange, relUnitTag.Id(), unitTag.Id(), ) } rangeInfo = pendingPorts[rangeKey] rangeInfo.ShouldOpen = false pendingPorts[rangeKey] = rangeInfo return nil }