Beispiel #1
0
// PrivateAddress implements the server side of Client.PrivateAddress.
func (c *Client) PrivateAddress(p params.PrivateAddress) (results params.PrivateAddressResults, err error) {
	switch {
	case names.IsValidMachine(p.Target):
		machine, err := c.api.stateAccessor.Machine(p.Target)
		if err != nil {
			return results, err
		}
		addr, err := machine.PrivateAddress()
		if err != nil {
			return results, errors.Annotatef(err, "error fetching address for machine %q", machine)
		}
		return params.PrivateAddressResults{PrivateAddress: addr.Value}, nil

	case names.IsValidUnit(p.Target):
		unit, err := c.api.stateAccessor.Unit(p.Target)
		if err != nil {
			return results, err
		}
		addr, err := unit.PrivateAddress()
		if err != nil {
			return results, errors.Annotatef(err, "error fetching address for unit %q", unit)
		}
		return params.PrivateAddressResults{PrivateAddress: addr.Value}, nil
	}
	return results, fmt.Errorf("unknown unit or machine %q", p.Target)

}
Beispiel #2
0
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)
}
Beispiel #3
0
// PrivateAddress implements the server side of Client.PrivateAddress.
func (c *Client) PrivateAddress(p params.PrivateAddress) (results params.PrivateAddressResults, err error) {
	switch {
	case names.IsValidMachine(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.IsValidUnit(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)
}
Beispiel #4
0
// Init initializes the command for running.
func (a *UnitAgent) Init(args []string) error {
	if a.UnitName == "" {
		return cmdutil.RequiredError("unit-name")
	}
	if !names.IsValidUnit(a.UnitName) {
		return fmt.Errorf(`--unit-name option expects "<service>/<n>" argument`)
	}
	if err := a.AgentConf.CheckArgs(args); err != nil {
		return err
	}
	a.runner = worker.NewRunner(cmdutil.IsFatal, cmdutil.MoreImportant, worker.RestartDelay)

	if !a.logToStdErr {
		if err := a.ReadConfig(a.Tag().String()); err != nil {
			return err
		}
		agentConfig := a.CurrentConfig()

		// the writer in ctx.stderr gets set as the loggo writer in github.com/juju/cmd/logging.go
		a.ctx.Stderr = &lumberjack.Logger{
			Filename:   agent.LogFilename(agentConfig),
			MaxSize:    300, // megabytes
			MaxBackups: 2,
		}

	}

	return nil
}
Beispiel #5
0
// ReadSettings returns a map holding the settings of the unit with the
// supplied name within this relation. An error will be returned if the
// relation no longer exists, or if the unit's service is not part of the
// relation, or the settings are invalid; but mere non-existence of the
// unit is not grounds for an error, because the unit settings are
// guaranteed to persist for the lifetime of the relation, regardless
// of the lifetime of the unit.
func (ru *RelationUnit) ReadSettings(uname string) (params.RelationSettings, error) {
	if !names.IsValidUnit(uname) {
		return nil, errors.Errorf("%q is not a valid unit", uname)
	}
	tag := names.NewUnitTag(uname)
	var results params.RelationSettingsResults
	args := params.RelationUnitPairs{
		RelationUnitPairs: []params.RelationUnitPair{{
			Relation:   ru.relation.tag.String(),
			LocalUnit:  ru.unit.tag.String(),
			RemoteUnit: tag.String(),
		}},
	}
	err := ru.st.facade.FacadeCall("ReadRemoteSettings", 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
	}
	return result.Settings, nil
}
Beispiel #6
0
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.IsValidMachine(target) && !names.IsValidUnit(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
}
Beispiel #7
0
func (s *serviceSuite) TestServiceNameFormats(c *gc.C) {
	assertService := func(s string, expect bool) {
		c.Assert(names.IsValidService(s), gc.Equals, expect)
		// Check that anything that is considered a valid service name
		// is also (in)valid if a(n) (in)valid unit designator is added
		// to it.
		c.Assert(names.IsValidUnit(s+"/0"), gc.Equals, expect)
		c.Assert(names.IsValidUnit(s+"/99"), gc.Equals, expect)
		c.Assert(names.IsValidUnit(s+"/-1"), gc.Equals, false)
		c.Assert(names.IsValidUnit(s+"/blah"), gc.Equals, false)
		c.Assert(names.IsValidUnit(s+"/"), gc.Equals, false)
	}

	for i, test := range serviceNameTests {
		c.Logf("test %d: %q", i, test.pattern)
		assertService(test.pattern, test.valid)
	}
}
Beispiel #8
0
// IsValid checks if the port range is valid.
func (p PortRange) IsValid() bool {
	proto := strings.ToLower(p.Protocol)
	if proto != "tcp" && proto != "udp" {
		return false
	}
	if !names.IsValidUnit(p.UnitName) {
		return false
	}
	return p.FromPort <= p.ToPort
}
Beispiel #9
0
func targetToTag(target string) (names.Tag, error) {
	switch {
	case names.IsValidMachine(target):
		return names.NewMachineTag(target), nil
	case names.IsValidUnit(target):
		return names.NewUnitTag(target), nil
	default:
		return nil, errors.NotValidf("target %q", target)
	}
}
Beispiel #10
0
// Unit returns the service's unit with name.
func (s *Service) Unit(name string) (*Unit, error) {
	if !names.IsValidUnit(name) {
		return nil, fmt.Errorf("%q is not a valid unit name", name)
	}
	udoc := &unitDoc{}
	sel := bson.D{{"_id", name}, {"service", s.doc.Name}}
	if err := s.st.units.Find(sel).One(udoc); err != nil {
		return nil, fmt.Errorf("cannot get unit %q from service %q: %v", name, s.doc.Name, err)
	}
	return newUnit(s.st, udoc), nil
}
Beispiel #11
0
// resolveMachine returns the machine id resolving the given unit or machine
// placeholder.
func (h *bundleHandler) resolveMachine(placeholder string) (string, error) {
	machineOrUnit := resolve(placeholder, h.results)
	if !names.IsValidUnit(machineOrUnit) {
		return machineOrUnit, nil
	}
	for h.unitStatus[machineOrUnit] == "" {
		if err := h.updateUnitStatus(); err != nil {
			return "", errors.Annotate(err, "cannot resolve machine")
		}
	}
	return h.unitStatus[machineOrUnit], nil
}
Beispiel #12
0
func (c *RemoveUnitCommand) Init(args []string) error {
	c.UnitNames = args
	if len(c.UnitNames) == 0 {
		return fmt.Errorf("no units specified")
	}
	for _, name := range c.UnitNames {
		if !names.IsValidUnit(name) {
			return fmt.Errorf("invalid unit name %q", name)
		}
	}
	return nil
}
Beispiel #13
0
func (c *resolvedCommand) Init(args []string) error {
	if len(args) > 0 {
		c.UnitName = args[0]
		if !names.IsValidUnit(c.UnitName) {
			return fmt.Errorf("invalid unit name %q", c.UnitName)
		}
		args = args[1:]
	} else {
		return fmt.Errorf("no unit specified")
	}
	return cmd.CheckEmpty(args)
}
Beispiel #14
0
func (u unitAssigner) Handle(ids []string) error {
	logger.Tracef("Handling unit assignments: %q", ids)
	if len(ids) == 0 {
		return nil
	}

	units := make([]names.UnitTag, len(ids))
	for i, id := range ids {
		if !names.IsValidUnit(id) {
			return errors.Errorf("%q is not a valid unit id", id)
		}
		units[i] = names.NewUnitTag(id)
	}

	results, err := u.api.AssignUnits(units)
	if err != nil {
		return err
	}

	failures := map[string]error{}

	logger.Tracef("Unit assignment results: %q", results)
	// errors are returned in the same order as the ids given. Any errors from
	// the assign units call must be reported as error statuses on the
	// respective units (though the assignments will be retried).  Not found
	// errors indicate that the unit was removed before the assignment was
	// requested, which can be safely ignored.
	for i, err := range results {
		if err != nil && !errors.IsNotFound(err) {
			failures[units[i].String()] = err
		}
	}

	if len(failures) > 0 {
		args := params.SetStatus{
			Entities: make([]params.EntityStatusArgs, len(failures)),
		}

		x := 0
		for unit, err := range failures {
			args.Entities[x] = params.EntityStatusArgs{
				Tag:    unit,
				Status: params.StatusError,
				Info:   err.Error(),
			}
			x++
		}

		return u.api.SetAgentStatus(args)
	}
	return nil
}
Beispiel #15
0
// IsValid checks if the port range is valid.
func (p PortRange) Validate() error {
	proto := strings.ToLower(p.Protocol)
	if proto != "tcp" && proto != "udp" {
		return errors.Errorf("invalid protocol %q", proto)
	}
	if !names.IsValidUnit(p.UnitName) {
		return errors.Errorf("invalid unit %q", p.UnitName)
	}
	if p.FromPort > p.ToPort {
		return errors.Errorf("invalid port range %d-%d", p.FromPort, p.ToPort)
	}
	return nil
}
Beispiel #16
0
// Init initializes the command for running.
func (a *UnitAgent) Init(args []string) error {
	if a.UnitName == "" {
		return requiredError("unit-name")
	}
	if !names.IsValidUnit(a.UnitName) {
		return fmt.Errorf(`--unit-name option expects "<service>/<n>" argument`)
	}
	if err := a.AgentConf.CheckArgs(args); err != nil {
		return err
	}
	a.runner = worker.NewRunner(isFatal, moreImportant)
	return nil
}
Beispiel #17
0
// Init implements Command.Init.
func (c *addCommand) Init(args []string) (err error) {
	if len(args) < 2 {
		return errors.New("storage add requires a unit and a storage directive")
	}

	u := args[0]
	if !names.IsValidUnit(u) {
		return errors.NotValidf("unit name %q", u)
	}
	c.unitTag = names.NewUnitTag(u).String()

	c.storageCons, err = storage.ParseConstraintsMap(args[1:], false)
	return
}
Beispiel #18
0
// Unit returns a unit by name.
func (st *State) Unit(name string) (*Unit, error) {
	if !names.IsValidUnit(name) {
		return nil, fmt.Errorf("%q is not a valid unit name", name)
	}
	doc := unitDoc{}
	err := st.units.FindId(name).One(&doc)
	if err == mgo.ErrNotFound {
		return nil, errors.NotFoundf("unit %q", name)
	}
	if err != nil {
		return nil, fmt.Errorf("cannot get unit %q: %v", name, err)
	}
	return newUnit(st, &doc), nil
}
Beispiel #19
0
// validate returns an error if any fields are invalid or missing.
func (c check) validate() error {
	if !names.IsValidService(c.serviceName) {
		return errors.Errorf("invalid service name %q", c.serviceName)
	}
	if !names.IsValidUnit(c.unitName) {
		return errors.Errorf("invalid unit name %q", c.unitName)
	}
	if c.response == nil {
		return errors.New("missing response channel")
	}
	if c.abort == nil {
		return errors.New("missing abort channel")
	}
	return nil
}
Beispiel #20
0
// ReadSettings returns a map holding the settings of the unit with the
// supplied name within this relation. An error will be returned if the
// relation no longer exists, or if the unit's service is not part of the
// relation, or the settings are invalid; but mere non-existence of the
// unit is not grounds for an error, because the unit settings are
// guaranteed to persist for the lifetime of the relation, regardless
// of the lifetime of the unit.
func (ru *RelationUnit) ReadSettings(uname string) (m map[string]interface{}, err error) {
	defer errors.Maskf(&err, "cannot read settings for unit %q in relation %q", uname, ru.relation)
	if !names.IsValidUnit(uname) {
		return nil, fmt.Errorf("%q is not a valid unit name", uname)
	}
	key, err := ru.key(uname)
	if err != nil {
		return nil, err
	}
	node, err := readSettings(ru.st, key)
	if err != nil {
		return nil, err
	}
	return node.Map(), nil
}
Beispiel #21
0
// Init reads and verifies the cli arguments for the collectMetricsCommand
func (c *collectMetricsCommand) Init(args []string) error {
	if len(args) == 0 {
		return errors.New("you need to specify a unit or service.")
	}
	if names.IsValidUnit(args[0]) {
		c.units = []string{args[0]}
	} else if names.IsValidService(args[0]) {
		c.services = []string{args[0]}
	} else {
		return errors.Errorf("%q is not a valid unit or service", args[0])
	}
	if err := cmd.CheckEmpty(args[1:]); err != nil {
		return errors.Errorf("unknown command line arguments: " + strings.Join(args, ","))
	}
	return nil
}
Beispiel #22
0
func inferRemoteUnit(rctxs map[int]*ContextRelation, info CommandInfo) (int, string, error) {
	relationId := info.RelationId
	hasRelation := relationId != -1
	remoteUnit := info.RemoteUnitName
	hasRemoteUnit := remoteUnit != ""

	// Check baseline sanity of remote unit, if supplied.
	if hasRemoteUnit {
		if !names.IsValidUnit(remoteUnit) {
			return -1, "", errors.Errorf(`invalid remote unit: %s`, remoteUnit)
		} else if !hasRelation {
			return -1, "", errors.Errorf("remote unit provided without a relation: %s", remoteUnit)
		}
	}

	// Check sanity of relation, if supplied, otherwise easy early return.
	if !hasRelation {
		return relationId, remoteUnit, nil
	}
	rctx, found := rctxs[relationId]
	if !found {
		return -1, "", errors.Errorf("unknown relation id: %d", relationId)
	}

	// Past basic sanity checks; if forced, accept what we're given.
	if info.ForceRemoteUnit {
		return relationId, remoteUnit, nil
	}

	// Infer an appropriate remote unit if we can.
	possibles := rctx.UnitNames()
	if remoteUnit == "" {
		switch len(possibles) {
		case 0:
			return -1, "", errors.Errorf("cannot infer remote unit in empty relation %d", relationId)
		case 1:
			return relationId, possibles[0], nil
		}
		return -1, "", errors.Errorf("ambiguous remote unit; possibilities are %+v", possibles)
	}
	for _, possible := range possibles {
		if remoteUnit == possible {
			return relationId, remoteUnit, nil
		}
	}
	return -1, "", errors.Errorf("unknown remote unit %s; possibilities are %+v", remoteUnit, possibles)
}
Beispiel #23
0
func (ctx *SimpleContext) deployedUnitsUpstartJobs() (map[string]string, error) {
	fis, err := ioutil.ReadDir(ctx.initDir)
	if err != nil {
		return nil, err
	}
	installed := make(map[string]string)
	for _, fi := range fis {
		if groups := deployedRe.FindStringSubmatch(fi.Name()); len(groups) == 4 {
			unitName := groups[2] + "/" + groups[3]
			if !names.IsValidUnit(unitName) {
				continue
			}
			installed[unitName] = groups[1]
		}
	}
	return installed, nil
}
Beispiel #24
0
// Validate checks if the port range is valid.
func (p PortRange) Validate() error {
	proto := strings.ToLower(p.Protocol)
	if proto != "tcp" && proto != "udp" {
		return errors.Errorf("invalid protocol %q", proto)
	}
	if !names.IsValidUnit(p.UnitName) {
		return errors.Errorf("invalid unit %q", p.UnitName)
	}
	if p.FromPort > p.ToPort {
		return errors.Errorf("invalid port range %d-%d", p.FromPort, p.ToPort)
	}
	if p.FromPort <= 0 || p.FromPort > 65535 ||
		p.ToPort <= 0 || p.ToPort > 65535 {
		return errors.Errorf("port range bounds must be between 1 and 65535, got %d-%d", p.FromPort, p.ToPort)
	}
	return nil
}
Beispiel #25
0
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.IsValidMachine(machineId) {
			nameErrors = append(nameErrors, fmt.Sprintf("  %q is not a valid machine id", machineId))
		}
	}
	for _, service := range c.services {
		if !names.IsValidService(service) {
			nameErrors = append(nameErrors, fmt.Sprintf("  %q is not a valid service name", service))
		}
	}
	for _, unit := range c.units {
		if !names.IsValidUnit(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)
}
Beispiel #26
0
// Init reads and verifies the cli arguments for the SetMeterStatusCommand
func (c *SetMeterStatusCommand) Init(args []string) error {
	if len(args) != 2 {
		return errors.New("you need to specify an entity (service or unit) and a status")
	}
	if names.IsValidUnit(args[0]) {
		c.Tag = names.NewUnitTag(args[0])
	} else if names.IsValidService(args[0]) {
		c.Tag = names.NewServiceTag(args[0])
	} else {
		return errors.Errorf("%q is not a valid unit or service", args[0])
	}
	c.Status = args[1]

	if err := cmd.CheckEmpty(args[2:]); err != nil {
		return errors.Errorf("unknown command line arguments: " + strings.Join(args, ","))
	}
	return nil
}
Beispiel #27
0
func (c *debugHooksCommand) Init(args []string) error {
	if len(args) < 1 {
		return fmt.Errorf("no unit name specified")
	}
	c.Target = args[0]
	if !names.IsValidUnit(c.Target) {
		return fmt.Errorf("%q is not a valid unit name", c.Target)
	}

	// If any of the hooks is "*", then debug all hooks.
	c.hooks = append([]string{}, args[1:]...)
	for _, h := range c.hooks {
		if h == "*" {
			c.hooks = nil
			break
		}
	}
	return nil
}
Beispiel #28
0
// NewCommands is part of the Factory interface.
func (f *factory) NewCommands(args CommandArgs, sendResponse CommandResponseFunc) (Operation, error) {
	if args.Commands == "" {
		return nil, errors.New("commands required")
	} else if sendResponse == nil {
		return nil, errors.New("response sender required")
	}
	if args.RemoteUnitName != "" {
		if args.RelationId == -1 {
			return nil, errors.New("remote unit not valid without relation")
		} else if !names.IsValidUnit(args.RemoteUnitName) {
			return nil, errors.Errorf("invalid remote unit name %q", args.RemoteUnitName)
		}
	}
	return &runCommands{
		args:          args,
		sendResponse:  sendResponse,
		callbacks:     f.config.Callbacks,
		runnerFactory: f.config.RunnerFactory,
	}, nil
}
Beispiel #29
0
func (ctx *SimpleContext) deployedUnitsInitSystemJobs() (map[string]string, error) {
	fis, err := ctx.listServices()
	if err != nil {
		return nil, err
	}
	if err != nil {
		return nil, err
	}
	installed := make(map[string]string)
	for _, fi := range fis {
		if groups := deployedRe.FindStringSubmatch(fi); len(groups) > 0 {
			unitName := groups[2] + "/" + groups[3]
			if !names.IsValidUnit(unitName) {
				continue
			}
			installed[unitName] = groups[1]
		}
	}
	return installed, nil
}
Beispiel #30
0
// Init gets the unit tag, and checks for other correct args.
func (c *doCommand) Init(args []string) error {
	switch len(args) {
	case 0:
		return errors.New("no unit specified")
	case 1:
		return errors.New("no action specified")
	default:
		// Grab and verify the unit and action names.
		unitName := args[0]
		if !names.IsValidUnit(unitName) {
			return errors.Errorf("invalid unit name %q", unitName)
		}
		ActionName := args[1]
		if valid := ActionNameRule.MatchString(ActionName); !valid {
			return fmt.Errorf("invalid action name %q", ActionName)
		}
		c.unitTag = names.NewUnitTag(unitName)
		c.actionName = ActionName
		if len(args) == 2 {
			return nil
		}
		// Parse CLI key-value args if they exist.
		c.args = make([][]string, 0)
		for _, arg := range args[2:] {
			thisArg := strings.SplitN(arg, "=", 2)
			if len(thisArg) != 2 {
				return fmt.Errorf("argument %q must be of the form key...=value", arg)
			}
			keySlice := strings.Split(thisArg[0], ".")
			// check each key for validity
			for _, key := range keySlice {
				if valid := keyRule.MatchString(key); !valid {
					return fmt.Errorf("key %q must start and end with lowercase alphanumeric, and contain only lowercase alphanumeric and hyphens", key)
				}
			}
			// c.args={..., [key, key, key, key, value]}
			c.args = append(c.args, append(keySlice, thisArg[1]))
		}
		return nil
	}
}