// PrivateAddress implements the server side of Client.PrivateAddress. func (c *Client) PrivateAddress(p params.PrivateAddress) (results params.PrivateAddressResults, err error) { switch { case names.IsMachine(p.Target): machine, err := c.api.state.Machine(p.Target) if err != nil { return results, err } addr := network.SelectInternalAddress(machine.Addresses(), false) if addr == "" { return results, fmt.Errorf("machine %q has no internal address", machine) } return params.PrivateAddressResults{PrivateAddress: addr}, nil case names.IsUnit(p.Target): unit, err := c.api.state.Unit(p.Target) if err != nil { return results, err } addr, ok := unit.PrivateAddress() if !ok { return results, fmt.Errorf("unit %q has no internal address", unit) } return params.PrivateAddressResults{PrivateAddress: addr}, nil } return results, fmt.Errorf("unknown unit or machine %q", p.Target) }
func (s *machineSuite) TestMachineIdFormats(c *gc.C) { for i, test := range machineIdTests { c.Logf("test %d: %q", i, test.pattern) c.Assert(names.IsMachine(test.pattern), gc.Equals, test.valid) c.Assert(names.IsContainerMachine(test.pattern), gc.Equals, test.container) } }
func (c *SSHCommon) hostFromTarget(target string) (string, error) { // If the target is neither a machine nor a unit, // assume it's a hostname and try it directly. if !names.IsMachine(target) && !names.IsUnit(target) { return target, nil } // A target may not initially have an address (e.g. the // address updater hasn't yet run), so we must do this in // a loop. if _, err := c.ensureAPIClient(); err != nil { return "", err } var err error for a := sshHostFromTargetAttemptStrategy.Start(); a.Next(); { var addr string if c.proxy { addr, err = c.apiClient.PrivateAddress(target) } else { addr, err = c.apiClient.PublicAddress(target) } if err == nil { return addr, nil } } return "", err }
// Init initializes the command for running. func (a *MachineAgent) Init(args []string) error { if !names.IsMachine(a.MachineId) { return fmt.Errorf("--machine-id option must be set, and expects a non-negative integer") } if err := a.AgentConf.CheckArgs(args); err != nil { return err } a.runner = newRunner(isFatal, moreImportant) a.upgradeComplete = make(chan struct{}) a.workersStarted = make(chan struct{}) return nil }
func (c *RemoveMachineCommand) Init(args []string) error { if len(args) == 0 { return fmt.Errorf("no machines specified") } for _, id := range args { if !names.IsMachine(id) { return fmt.Errorf("invalid machine id %q", id) } } c.MachineIds = args return nil }
func (c *RetryProvisioningCommand) Init(args []string) error { if len(args) == 0 { return fmt.Errorf("no machine specified") } c.Machines = make([]string, len(args)) for i, arg := range args { if !names.IsMachine(arg) { return fmt.Errorf("invalid machine %q", arg) } c.Machines[i] = names.NewMachineTag(arg).String() } return nil }
// ParsePlacement attempts to parse the specified string and create a // corresponding Placement structure. // // If the placement directive is non-empty and missing a scope, // ErrPlacementScopeMissing will be returned as well as a Placement // with an empty Scope field. func ParsePlacement(directive string) (*Placement, error) { if directive == "" { return nil, nil } if colon := strings.IndexRune(directive, ':'); colon != -1 { scope, directive := directive[:colon], directive[colon+1:] if scope == "" { return nil, ErrPlacementScopeMissing } // Sanity check: machine/container scopes require a machine ID as the value. if (scope == MachineScope || isContainerType(scope)) && !names.IsMachine(directive) { return nil, fmt.Errorf("invalid value %q for %q scope: expected machine-id", directive, scope) } return &Placement{Scope: scope, Directive: directive}, nil } if names.IsMachine(directive) { return &Placement{Scope: MachineScope, Directive: directive}, nil } if isContainerType(directive) { return &Placement{Scope: directive}, nil } return nil, ErrPlacementScopeMissing }
func (c *RunCommand) Init(args []string) error { if len(args) == 0 { return fmt.Errorf("no commands specified") } c.commands, args = args[0], args[1:] if c.all { if len(c.machines) != 0 { return fmt.Errorf("You cannot specify --all and individual machines") } if len(c.services) != 0 { return fmt.Errorf("You cannot specify --all and individual services") } if len(c.units) != 0 { return fmt.Errorf("You cannot specify --all and individual units") } } else { if len(c.machines) == 0 && len(c.services) == 0 && len(c.units) == 0 { return fmt.Errorf("You must specify a target, either through --all, --machine, --service or --unit") } } var nameErrors []string for _, machineId := range c.machines { if !names.IsMachine(machineId) { nameErrors = append(nameErrors, fmt.Sprintf(" %q is not a valid machine id", machineId)) } } for _, service := range c.services { if !names.IsService(service) { nameErrors = append(nameErrors, fmt.Sprintf(" %q is not a valid service name", service)) } } for _, unit := range c.units { if !names.IsUnit(unit) { nameErrors = append(nameErrors, fmt.Sprintf(" %q is not a valid unit name", unit)) } } if len(nameErrors) > 0 { return fmt.Errorf("The following run targets are not valid:\n%s", strings.Join(nameErrors, "\n")) } return cmd.CheckEmpty(args) }
func verifyConfig(cfg *MachineConfig) (err error) { defer errors.Maskf(&err, "invalid machine configuration") if !names.IsMachine(cfg.MachineId) { return fmt.Errorf("invalid machine id") } if cfg.DataDir == "" { return fmt.Errorf("missing var directory") } if cfg.LogDir == "" { return fmt.Errorf("missing log directory") } if len(cfg.Jobs) == 0 { return fmt.Errorf("missing machine jobs") } if cfg.CloudInitOutputLog == "" { return fmt.Errorf("missing cloud-init output log path") } if cfg.Tools == nil { return fmt.Errorf("missing tools") } if cfg.Tools.URL == "" { return fmt.Errorf("missing tools URL") } if cfg.StateInfo == nil { return fmt.Errorf("missing state info") } if len(cfg.StateInfo.CACert) == 0 { return fmt.Errorf("missing CA certificate") } if cfg.APIInfo == nil { return fmt.Errorf("missing API info") } if len(cfg.APIInfo.CACert) == 0 { return fmt.Errorf("missing API CA certificate") } if cfg.MachineAgentServiceName == "" { return fmt.Errorf("missing machine agent service name") } if cfg.Bootstrap { if cfg.Config == nil { return fmt.Errorf("missing environment configuration") } if cfg.StateInfo.Tag != "" { return fmt.Errorf("entity tag must be blank when starting a state server") } if cfg.APIInfo.Tag != "" { return fmt.Errorf("entity tag must be blank when starting a state server") } if cfg.StateServingInfo == nil { return fmt.Errorf("missing state serving info") } if len(cfg.StateServingInfo.Cert) == 0 { return fmt.Errorf("missing state server certificate") } if len(cfg.StateServingInfo.PrivateKey) == 0 { return fmt.Errorf("missing state server private key") } if cfg.StateServingInfo.StatePort == 0 { return fmt.Errorf("missing state port") } if cfg.StateServingInfo.APIPort == 0 { return fmt.Errorf("missing API port") } if cfg.SystemPrivateSSHKey == "" { return fmt.Errorf("missing system ssh identity") } if cfg.InstanceId == "" { return fmt.Errorf("missing instance-id") } } else { if len(cfg.StateInfo.Addrs) == 0 { return fmt.Errorf("missing state hosts") } if cfg.StateInfo.Tag != names.NewMachineTag(cfg.MachineId).String() { return fmt.Errorf("entity tag must match started machine") } if len(cfg.APIInfo.Addrs) == 0 { return fmt.Errorf("missing API hosts") } if cfg.APIInfo.Tag != names.NewMachineTag(cfg.MachineId).String() { return fmt.Errorf("entity tag must match started machine") } if cfg.StateServingInfo != nil { return fmt.Errorf("state serving info unexpectedly present") } } if cfg.MachineNonce == "" { return fmt.Errorf("missing machine nonce") } return nil }
// AddUnits starts n units of the given service and allocates machines // to them as necessary. func AddUnits(st *state.State, svc *state.Service, n int, machineIdSpec string) ([]*state.Unit, error) { units := make([]*state.Unit, n) // Hard code for now till we implement a different approach. policy := state.AssignCleanEmpty // All units should have the same networks as the service. networks, err := svc.Networks() if err != nil { return nil, fmt.Errorf("cannot get service %q networks: %v", svc.Name(), err) } // TODO what do we do if we fail half-way through this process? for i := 0; i < n; i++ { unit, err := svc.AddUnit() if err != nil { return nil, fmt.Errorf("cannot add unit %d/%d to service %q: %v", i+1, n, svc.Name(), err) } if machineIdSpec != "" { if n != 1 { return nil, fmt.Errorf("cannot add multiple units of service %q to a single machine", svc.Name()) } // machineIdSpec may be an existing machine or container, eg 3/lxc/2 // or a new container on a machine, eg lxc:3 mid := machineIdSpec var containerType instance.ContainerType specParts := strings.SplitN(machineIdSpec, ":", 2) if len(specParts) > 1 { firstPart := specParts[0] var err error if containerType, err = instance.ParseContainerType(firstPart); err == nil { mid = specParts[1] } else { mid = machineIdSpec } } if !names.IsMachine(mid) { return nil, fmt.Errorf("invalid force machine id %q", mid) } var unitCons *constraints.Value unitCons, err = unit.Constraints() if err != nil { return nil, err } var err error var m *state.Machine // If a container is to be used, create it. if containerType != "" { // Create the new machine marked as dirty so that // nothing else will grab it before we assign the unit to it. template := state.MachineTemplate{ Series: unit.Series(), Jobs: []state.MachineJob{state.JobHostUnits}, Dirty: true, Constraints: *unitCons, RequestedNetworks: networks, } m, err = st.AddMachineInsideMachine(template, mid, containerType) } else { m, err = st.Machine(mid) } if err != nil { return nil, fmt.Errorf("cannot assign unit %q to machine: %v", unit.Name(), err) } err = unit.AssignToMachine(m) if err != nil { return nil, err } } else if err := st.AssignUnit(unit, policy); err != nil { return nil, err } units[i] = unit } return units, nil }