func (c *bootstrapCommand) Init(args []string) (err error) { if c.showClouds && c.showRegionsForCloud != "" { return errors.New("--clouds and --regions can't be used together") } if c.showClouds { return cmd.CheckEmpty(args) } if c.showRegionsForCloud != "" { return cmd.CheckEmpty(args) } if c.AgentVersionParam != "" && c.BuildAgent { return errors.New("--agent-version and --build-agent can't be used together") } if c.BootstrapSeries != "" && !charm.IsValidSeries(c.BootstrapSeries) { return errors.NotValidf("series %q", c.BootstrapSeries) } // Parse the placement directive. Bootstrap currently only // supports provider-specific placement directives. if c.Placement != "" { _, err = instance.ParsePlacement(c.Placement) if err != instance.ErrPlacementScopeMissing { // We only support unscoped placement directives for bootstrap. return errors.Errorf("unsupported bootstrap placement directive %q", c.Placement) } } if !c.AutoUpgrade { // With no auto upgrade chosen, we default to the version matching the bootstrap client. vers := jujuversion.Current c.AgentVersion = &vers } if c.AgentVersionParam != "" { if vers, err := version.ParseBinary(c.AgentVersionParam); err == nil { c.AgentVersion = &vers.Number } else if vers, err := version.Parse(c.AgentVersionParam); err == nil { c.AgentVersion = &vers } else { return err } } if c.AgentVersion != nil && (c.AgentVersion.Major != jujuversion.Current.Major || c.AgentVersion.Minor != jujuversion.Current.Minor) { return errors.New("requested agent version major.minor mismatch") } switch len(args) { case 0: // no args or flags, go interactive. c.interactive = true return nil } c.Cloud = args[0] if i := strings.IndexRune(c.Cloud, '/'); i > 0 { c.Cloud, c.Region = c.Cloud[:i], c.Cloud[i+1:] } if len(args) > 1 { c.controllerName = args[1] return cmd.CheckEmpty(args[2:]) } return nil }
func (c *restoreCommand) Init(args []string) error { if c.showDescription { return cmd.CheckEmpty(args) } if len(args) == 0 { return fmt.Errorf("no backup file specified") } c.backupFile = args[0] return cmd.CheckEmpty(args[1:]) }
func (c *JenvCommand) Init(args []string) error { if len(args) == 0 { return errors.New("no jenv file provided") } // Store the path to the jenv file. if err := c.jenvFile.Set(args[0]); err != nil { return errors.Annotate(err, "invalid jenv path") } args = args[1:] if len(args) > 0 { // Store and validate the provided environment name. c.envName, args = args[0], args[1:] if !names.IsValidUser(c.envName) { return errors.Errorf("invalid model name %q", c.envName) } } else { // Retrieve the environment name from the jenv file name. base := filepath.Base(c.jenvFile.Path) c.envName = base[:len(base)-len(filepath.Ext(base))] } // No other arguments are expected. return cmd.CheckEmpty(args) }
// Init implements Command.Init. func (c *removeCommand) Init(args []string) error { if len(args) == 0 { return errors.Errorf("no username supplied") } c.UserName = args[0] return cmd.CheckEmpty(args[1:]) }
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) }
func (c *UpgradeJujuCommand) Init(args []string) error { if c.vers != "" { vers, err := version.Parse(c.vers) if err != nil { return err } if vers.Major != version.Current.Major { return fmt.Errorf("cannot upgrade to version incompatible with CLI") } if c.UploadTools && vers.Build != 0 { // TODO(fwereade): when we start taking versions from actual built // code, we should disable --version when used with --upload-tools. // For now, it's the only way to experiment with version upgrade // behaviour live, so the only restriction is that Build cannot // be used (because its value needs to be chosen internally so as // not to collide with existing tools). return fmt.Errorf("cannot specify build number when uploading tools") } c.Version = vers } if len(c.Series) > 0 && !c.UploadTools { return fmt.Errorf("--series requires --upload-tools") } return cmd.CheckEmpty(args) }
func (c *addCredentialCommand) Init(args []string) (err error) { if len(args) < 1 { return errors.New("Usage: juju add-credential <cloud-name> [-f <credentials.yaml>]") } c.CloudName = args[0] return cmd.CheckEmpty(args[1:]) }
// SetFlags implements Command.Init. func (c *useEnvironmentCommand) Init(args []string) error { if len(args) == 0 || strings.TrimSpace(args[0]) == "" { return errors.New("no environment supplied") } name, args := args[0], args[1:] // First check to see if an owner has been specified. bits := strings.SplitN(name, "/", 2) switch len(bits) { case 1: // No user specified c.EnvName = bits[0] case 2: owner := bits[0] if names.IsValidUser(owner) { c.Owner = owner } else { return errors.Errorf("%q is not a valid user", owner) } c.EnvName = bits[1] } // Environment names can generally be anything, but we take a good // stab at trying to determine if the user has specified a UUID // instead of a name. For now, we only accept a properly formatted UUID, // which means one with dashes in the right place. if names.IsValidEnvironment(c.EnvName) { c.EnvUUID, c.EnvName = c.EnvName, "" } return cmd.CheckEmpty(args) }
func (c *exposeCommand) Init(args []string) error { if len(args) == 0 { return errors.New("no application name specified") } c.ApplicationName = args[0] return cmd.CheckEmpty(args[1:]) }
// Init is part of the cmd.Command interface. func (c *RelationGetCommand) Init(args []string) error { if c.RelationId == -1 { return fmt.Errorf("no relation id specified") } c.Key = "" if len(args) > 0 { if c.Key = args[0]; c.Key == "-" { c.Key = "" } args = args[1:] } name, err := c.ctx.RemoteUnitName() if err == nil { c.UnitName = name } else if cause := errors.Cause(err); !errors.IsNotFound(cause) { return errors.Trace(err) } if len(args) > 0 { c.UnitName = args[0] args = args[1:] } if c.UnitName == "" { return fmt.Errorf("no unit id specified") } return cmd.CheckEmpty(args) }
// Init implements Command. func (c *dumpDBCommand) Init(args []string) error { if len(args) == 1 { c.model = args[0] return nil } return cmd.CheckEmpty(args) }
func (c *portCommand) Init(args []string) error { if args == nil { return errors.New("no port specified") } parts := strings.Split(args[0], "/") if len(parts) > 2 { return fmt.Errorf("expected %s; got %q", portFormat, args[0]) } port, err := strconv.Atoi(parts[0]) if err != nil { return badPort(parts[0]) } if port < 1 || port > 65535 { return badPort(port) } protocol := "tcp" if len(parts) == 2 { protocol = strings.ToLower(parts[1]) if protocol != "tcp" && protocol != "udp" { return fmt.Errorf(`protocol must be "tcp" or "udp"; got %q`, protocol) } } c.Port = port c.Protocol = protocol return cmd.CheckEmpty(args[1:]) }
func (c *ensureAvailabilityCommand) Init(args []string) error { if c.NumStateServers < 0 || (c.NumStateServers%2 != 1 && c.NumStateServers != 0) { return fmt.Errorf("must specify a number of state servers odd and non-negative") } if c.PlacementSpec != "" { placementSpecs := strings.Split(c.PlacementSpec, ",") c.Placement = make([]string, len(placementSpecs)) for i, spec := range placementSpecs { p, err := instance.ParsePlacement(strings.TrimSpace(spec)) if err == nil && names.IsContainerMachine(p.Directive) { return errors.New("ensure-availability cannot be used with container placement directives") } if err == nil && p.Scope == instance.MachineScope { // Targeting machines is ok. c.Placement[i] = p.String() continue } if err != instance.ErrPlacementScopeMissing { return fmt.Errorf("unsupported ensure-availability placement directive %q", spec) } c.Placement[i] = spec } } return cmd.CheckEmpty(args) }
// Init is part of the cmd.Command interface. func (c *applicationVersionSetCommand) Init(args []string) error { if len(args) < 1 { return errors.New("no version specified") } c.version = args[0] return cmd.CheckEmpty(args[1:]) }
// Init implements Command.Init. func (c *DisenableUserBase) Init(args []string) error { if len(args) == 0 { return errors.New("no username supplied") } c.user = args[0] return cmd.CheckEmpty(args[1:]) }
func (c *publishCommand) Init(args []string) error { if len(args) == 0 { return nil } c.URL = args[0] return cmd.CheckEmpty(args[1:]) }
func (c *UnexposeCommand) Init(args []string) error { if len(args) == 0 { return errors.New("no service name specified") } c.ServiceName = args[0] return cmd.CheckEmpty(args[1:]) }
func (c *debugLogCommand) Init(args []string) error { if c.level != "" { level, ok := loggo.ParseLevel(c.level) if !ok || level < loggo.TRACE || level > loggo.ERROR { return errors.Errorf("level value %q is not one of %q, %q, %q, %q, %q", c.level, loggo.TRACE, loggo.DEBUG, loggo.INFO, loggo.WARNING, loggo.ERROR) } c.params.Level = level } if c.tail && c.notail { return errors.NotValidf("setting --tail and --no-tail") } if c.utc { c.tz = time.UTC } if c.date { c.format = "2006-01-02 15:04:05" } else { c.format = "15:04:05" } if c.ms { c.format = c.format + ".000" } return cmd.CheckEmpty(args) }
func (c *BootstrapCommand) Init(args []string) (err error) { if len(c.Series) > 0 && !c.UploadTools { return fmt.Errorf("--upload-series requires --upload-tools") } if len(c.seriesOld) > 0 && !c.UploadTools { return fmt.Errorf("--series requires --upload-tools") } if len(c.Series) > 0 && len(c.seriesOld) > 0 { return fmt.Errorf("--upload-series and --series can't be used together") } if len(c.seriesOld) > 0 { c.Series = c.seriesOld } // Parse the placement directive. Bootstrap currently only // supports provider-specific placement directives. if c.Placement != "" { _, err = instance.ParsePlacement(c.Placement) if err != instance.ErrPlacementScopeMissing { // We only support unscoped placement directives for bootstrap. return fmt.Errorf("unsupported bootstrap placement directive %q", c.Placement) } } return cmd.CheckEmpty(args) }
func (c *removeCloudCommand) Init(args []string) (err error) { if len(args) < 1 { return errors.New("Usage: juju remove-cloud <cloud name>") } c.Cloud = args[0] return cmd.CheckEmpty(args[1:]) }
func (c *MigrateCommand) Init(args []string) error { if len(args) == 0 { return errors.New("missing operation") } c.operation, args = args[0], args[1:] switch c.operation { case "export": if len(args) == 0 { return errors.New("missing model uuid") } c.modelUUID, args = args[0], args[1:] case "import": if len(args) == 0 { return errors.New("missing yaml filename") } c.filename, args = args[0], args[1:] default: return errors.Errorf("unknown operation %q", c.operation) } if !names.IsValidMachine(c.machineId) { return errors.Errorf("%q is not a valid machine id", c.machineId) } c.machineTag = names.NewMachineTag(c.machineId) return cmd.CheckEmpty(args) }
func (c *bootstrapCommand) Init(args []string) (err error) { if c.AgentVersionParam != "" && c.UploadTools { return fmt.Errorf("--agent-version and --upload-tools can't be used together") } if c.BootstrapSeries != "" && !charm.IsValidSeries(c.BootstrapSeries) { return errors.NotValidf("series %q", c.BootstrapSeries) } if c.BootstrapImage != "" { if c.BootstrapSeries == "" { return errors.Errorf("--bootstrap-image must be used with --bootstrap-series") } cons, err := constraints.Merge(c.Constraints, c.BootstrapConstraints) if err != nil { return errors.Trace(err) } if !cons.HasArch() { return errors.Errorf("--bootstrap-image must be used with --bootstrap-constraints, specifying architecture") } } // Parse the placement directive. Bootstrap currently only // supports provider-specific placement directives. if c.Placement != "" { _, err = instance.ParsePlacement(c.Placement) if err != instance.ErrPlacementScopeMissing { // We only support unscoped placement directives for bootstrap. return fmt.Errorf("unsupported bootstrap placement directive %q", c.Placement) } } if !c.AutoUpgrade { // With no auto upgrade chosen, we default to the version matching the bootstrap client. vers := jujuversion.Current c.AgentVersion = &vers } if c.AgentVersionParam != "" { if vers, err := version.ParseBinary(c.AgentVersionParam); err == nil { c.AgentVersion = &vers.Number } else if vers, err := version.Parse(c.AgentVersionParam); err == nil { c.AgentVersion = &vers } else { return err } } if c.AgentVersion != nil && (c.AgentVersion.Major != jujuversion.Current.Major || c.AgentVersion.Minor != jujuversion.Current.Minor) { return fmt.Errorf("requested agent version major.minor mismatch") } // The user must specify two positional arguments: the controller name, // and the cloud name (optionally with region specified). if len(args) < 2 { return errors.New("controller name and cloud name are required") } c.controllerName = bootstrappedControllerName(args[0]) c.Cloud = args[1] if i := strings.IndexRune(c.Cloud, '/'); i > 0 { c.Cloud, c.Region = c.Cloud[:i], c.Cloud[i+1:] } return cmd.CheckEmpty(args[2:]) }
// Init is defined on the cmd.Command interface. It checks the // arguments for sanity and sets up the command to run. func (c *listCommand) Init(args []string) error { // No arguments are accepted, just flags. if err := cmd.CheckEmpty(args); err != nil { return errors.Trace(err) } return nil }
func (c *removeCredentialCommand) Init(args []string) (err error) { if len(args) < 2 { return errors.New("Usage: juju remove-credential <cloud-name> <credential-name>") } c.cloud = args[0] c.credential = args[1] return cmd.CheckEmpty(args[2:]) }
func (c *addCloudCommand) Init(args []string) (err error) { if len(args) < 2 { return errors.New("Usage: juju add-cloud <cloud name> <cloud definition file>") } c.Cloud = args[0] c.CloudFile = args[1] return cmd.CheckEmpty(args[2:]) }
func (c *setDefaultRegionCommand) Init(args []string) (err error) { if len(args) < 2 { return errors.New("Usage: juju set-default-region <cloud-name> <region>") } c.cloud = args[0] c.region = args[1] return cmd.CheckEmpty(args[2:]) }
// Init sets the fail message and checks for malformed invocations. func (c *ActionFailCommand) Init(args []string) error { if len(args) == 0 { c.failMessage = "action failed without reason given, check action for errors" return nil } c.failMessage = args[0] return cmd.CheckEmpty(args[1:]) }
// Init implements cmd.Command.Init. func (c *showBudgetCommand) Init(args []string) error { if len(args) < 1 { return errors.New("missing arguments") } c.budget, args = args[0], args[1:] return cmd.CheckEmpty(args) }
func (c *GetCommand) Init(args []string) error { // TODO(dfc) add --schema-only if len(args) == 0 { return errors.New("no service name specified") } c.ServiceName = args[0] return cmd.CheckEmpty(args[1:]) }
func (c *RemoveUserCommand) Init(args []string) error { if len(args) == 0 { return errors.New("no username supplied") } c.User = args[0] return cmd.CheckEmpty(args[1:]) }