// Run implements Command.Run.
436703
func (c *listKeysCommand) Run(context *cmd.Context) error {
	client, err := c.NewKeyManagerClient()
	if err != nil {
		return err
	}
	defer client.Close()

	mode := ssh.Fingerprints
	if c.showFullKey {
		mode = ssh.FullKeys
	}
	// TODO(alexisb) - currently keys are global which is not ideal.
	// keymanager needs to be updated to allow keys per user
	c.user = "admin"
	results, err := client.ListKeys(mode, c.user)
	if err != nil {
		return errors.Trace(err)
	}
	result := results[0]
	if result.Error != nil {
		return errors.Trace(result.Error)
	}
	if len(result.Result) == 0 {
		context.Infof("No keys to display.")
		return nil
	}
	modelName, err := c.ModelName()
	if err != nil {
		return errors.Trace(err)
	}
	fmt.Fprintf(context.Stdout, "Keys used in model: %s\n", modelName)
	fmt.Fprintln(context.Stdout, strings.Join(result.Result, "\n"))
	return nil
}
1016222
func (c *disableCommand) Run(ctx *cmd.Context) error {
	if c.api == nil {
		api, err := c.NewUserManagerAPIClient()
		if err != nil {
			return errors.Trace(err)
		}
		c.api = api
		defer c.api.Close()
	}

	if err := c.api.DisableUser(c.User); err != nil {
		return block.ProcessBlockedError(err, block.BlockChange)
	}
	ctx.Infof("User %q disabled", c.User)
	return nil
}
692712
func (c *showModelCommand) Run(ctx *cmd.Context) error {
	controllerName, err := c.ControllerName()
	if err != nil {
		return errors.Trace(err)
	}
	_, modelDetails, err := c.ModelDetails()
	if err != nil {
		return errors.Trace(err)
	}
	modelTag := names.NewModelTag(modelDetails.ModelUUID)

	api, err := c.getAPI()
	if err != nil {
		return err
	}
	defer api.Close()

	results, err := api.ModelInfo([]names.ModelTag{modelTag})
	if err != nil {
		return err
	}
	if results[0].Error != nil {
		return results[0].Error
	}
	infoMap, err := c.apiModelInfoToModelInfoMap([]params.ModelInfo{*results[0].Result}, controllerName)
	if err != nil {
		return errors.Trace(err)
	}
	return c.out.Write(ctx, infoMap)
}
865538
func (c *BootstrapCommand) Run(_ *cmd.Context) error {

	bootstrapParamsData, err := ioutil.ReadFile(c.BootstrapParamsFile)
	if err != nil {
		return errors.Annotate(err, "reading bootstrap params file")
	}
	var args instancecfg.StateInitializationParams
	if err := args.Unmarshal(bootstrapParamsData); err != nil {
		return errors.Trace(err)
	}

	isCAAS := args.ControllerCloud.Type == caasprovider.CAASProviderType

	if isCAAS {
		if err := c.ensureConfigFilesForCaas(); err != nil {
			return errors.Trace(err)
		}
	}

	if err := c.ReadConfig(c.Tag().String()); err != nil {
		return errors.Annotate(err, "cannot read config")
	}
	agentConfig := c.CurrentConfig()

	// agent.Jobs is an optional field in the agent config, and was
	// introduced after 1.17.2. We default to allowing units on
	// machine-0 if missing.
	jobs := agentConfig.Jobs()
	if len(jobs) == 0 {
		jobs = []multiwatcher.MachineJob{
			multiwatcher.JobManageModel,
			multiwatcher.JobHostUnits,
		}
	}

	// Get the bootstrap machine's addresses from the provider.
	cloudSpec, err := environs.MakeCloudSpec(
		args.ControllerCloud,
		args.ControllerCloudRegion,
		args.ControllerCloudCredential,
	)
	if err != nil {
		return errors.Trace(err)
	}

	openParams := environs.OpenParams{
		ControllerUUID: args.ControllerConfig.ControllerUUID(),
		Cloud:          cloudSpec,
		Config:         args.ControllerModelConfig,
	}
	var env environs.BootstrapEnviron
	if isCAAS {
		env, err = environsNewCAAS(openParams)
	} else {
		env, err = environsNewIAAS(openParams)
	}
	if err != nil {
		return errors.Trace(err)
	}

	newConfigAttrs := make(map[string]interface{})

	// Check to see if a newer agent version has been requested
	// by the bootstrap client.
	desiredVersion, ok := args.ControllerModelConfig.AgentVersion()
	if ok && desiredVersion != jujuversion.Current {
		if isCAAS {
			// For CAAS, the agent-version in controller config should
			// always equals to current juju version.
			return errors.NotSupportedf(
				"desired juju version %q, current version %q for k8s controllers",
				desiredVersion, jujuversion.Current,
			)
		}

		// If we have been asked for a newer version, ensure the newer
		// tools can actually be found, or else bootstrap won't complete.
		streams := envtools.PreferredStreams(&desiredVersion, args.ControllerModelConfig.Development(), args.ControllerModelConfig.AgentStream())
		logger.Infof("newer agent binaries requested, looking for %v in streams: %v", desiredVersion, strings.Join(streams, ","))
		hostSeries, err := series.HostSeries()
		if err != nil {
			return errors.Trace(err)
		}
		filter := tools.Filter{
			Number: desiredVersion,
			Arch:   arch.HostArch(),
			Series: hostSeries,
		}
		_, toolsErr := envtools.FindTools(env, -1, -1, streams, filter)
		if toolsErr == nil {
			logger.Infof("agent binaries are available, upgrade will occur after bootstrap")
		}
		if errors.IsNotFound(toolsErr) {
			// Newer tools not available, so revert to using the tools
			// matching the current agent version.
			logger.Warningf("newer agent binaries for %q not available, sticking with version %q", desiredVersion, jujuversion.Current)
			newConfigAttrs["agent-version"] = jujuversion.Current.String()
		} else if toolsErr != nil {
			logger.Errorf("cannot find newer agent binaries: %v", toolsErr)
			return toolsErr
		}
	}

	callCtx := context.NewCloudCallContext()
	// At this stage, cloud credential has not yet been stored server-side
	// as there is no server-side. If these cloud calls will fail with
	// invalid credential, just log it.
	callCtx.InvalidateCredentialFunc = func(reason string) error {
		logger.Errorf("Cloud credential %q is not accepted by cloud provider: %v", args.ControllerCloudCredentialName, reason)
		return nil
	}

	info, ok := agentConfig.StateServingInfo()
	if !ok {
		return fmt.Errorf("bootstrap machine config has no state serving info")
	}
	if err := ensureKeys(isCAAS, args, &info, newConfigAttrs); err != nil {
		return errors.Trace(err)
	}
	addrs, err := getAddressesForMongo(isCAAS, env, callCtx, args)
	if err != nil {
		return errors.Trace(err)
	}

	if err = c.ChangeConfig(func(agentConfig agent.ConfigSetter) error {
		agentConfig.SetStateServingInfo(info)
		mmprof, err := mongo.NewMemoryProfile(args.ControllerConfig.MongoMemoryProfile())
		if err != nil {
			logger.Errorf("could not set requested memory profile: %v", err)
		} else {
			agentConfig.SetMongoMemoryProfile(mmprof)
		}
		return nil
	}); err != nil {
		return fmt.Errorf("cannot write agent config: %v", err)
	}

	agentConfig = c.CurrentConfig()

	// Create system-identity file
	if err := agent.WriteSystemIdentityFile(agentConfig); err != nil {
		return errors.Trace(err)
	}

	if err := c.startMongo(isCAAS, addrs, agentConfig); err != nil {
		return errors.Annotate(err, "failed to start mongo")
	}

	controllerModelCfg, err := env.Config().Apply(newConfigAttrs)
	if err != nil {
		return errors.Annotate(err, "failed to update model config")
	}
	args.ControllerModelConfig = controllerModelCfg

	// Initialise state, and store any agent config (e.g. password) changes.
	var controller *state.Controller
	var m *state.Machine
	err = c.ChangeConfig(func(agentConfig agent.ConfigSetter) error {
		var stateErr error
		dialOpts := mongo.DefaultDialOpts()

		// Set a longer socket timeout than usual, as the machine
		// will be starting up and disk I/O slower than usual. This
		// has been known to cause timeouts in queries.
		dialOpts.SocketTimeout = c.Timeout
		if dialOpts.SocketTimeout < minSocketTimeout {
			dialOpts.SocketTimeout = minSocketTimeout
		}

		// We shouldn't attempt to dial peers until we have some.
		dialOpts.Direct = true

		adminTag := names.NewLocalUserTag(adminUserName)
		controller, m, stateErr = agentInitializeState(
			adminTag,
			agentConfig,
			agentbootstrap.InitializeStateParams{
				StateInitializationParams: args,
				BootstrapMachineAddresses: addrs,
				BootstrapMachineJobs:      jobs,
				SharedSecret:              info.SharedSecret,
				Provider:                  environs.Provider,
				StorageProviderRegistry:   stateenvirons.NewStorageProviderRegistry(env),
			},
			dialOpts,
			stateenvirons.GetNewPolicyFunc(),
		)
		return stateErr
	})
	if err != nil {
		return err
	}
	defer controller.Close()
	st := controller.SystemState()

	// Set up default container networking mode
	model, err := st.Model()
	if err != nil {
		return err
	}
	if err = model.AutoConfigureContainerNetworking(env); err != nil {
		if errors.IsNotSupported(err) {
			logger.Debugf("Not performing container networking autoconfiguration on a non-networking environment")
		} else {
			return err
		}
	}

	// Fetch spaces from substrate
	if err = st.ReloadSpaces(env); err != nil {
		if errors.IsNotSupported(err) {
			logger.Debugf("Not performing spaces load on a non-networking environment")
		} else {
			return err
		}
	}

	if !isCAAS {
		// Populate the tools catalogue.
		if err := c.populateTools(st, env); err != nil {
			return errors.Trace(err)
		}
		// Add custom image metadata to environment storage.
		if len(args.CustomImageMetadata) > 0 {
			if err := c.saveCustomImageMetadata(st, env, args.CustomImageMetadata); err != nil {
				return err
			}
		}
	}

	// Populate the GUI archive catalogue.
	if err := c.populateGUIArchive(st, env); err != nil {
		// Do not stop the bootstrapping process for Juju GUI archive errors.
		logger.Warningf("cannot set up Juju GUI: %s", err)
	} else {
		logger.Debugf("Juju GUI successfully set up")
	}

	// bootstrap machine always gets the vote
	return m.SetHasVote(true)
}
1275018
func (c *findCommand) Run(ctx *cmd.Context) (err error) {
	if err := c.validateOrSetURL(); err != nil {
		return errors.Trace(err)
	}
	accountDetails, err := c.CurrentAccountDetails()
	if err != nil {
		return err
	}
	loggedInUser := accountDetails.User

	api, err := c.newAPIFunc(c.source)
	if err != nil {
		return err
	}
	defer api.Close()

	filter := crossmodel.ApplicationOfferFilter{
		OwnerName: c.modelOwnerName,
		ModelName: c.modelName,
		OfferName: c.offerName,
	}
	if c.interfaceName != "" {
		filter.Endpoints = []crossmodel.EndpointFilterTerm{{
			Interface: c.interfaceName,
		}}
	}
	found, err := api.FindApplicationOffers(filter)
	if err != nil {
		return err
	}

	output, err := convertFoundOffers(c.source, names.NewUserTag(loggedInUser), found...)
	if err != nil {
		return err
	}
	if len(output) == 0 {
		return errors.New("no matching application offers found")
	}
	return c.out.Write(ctx, output)
}
320298
func (c *CredentialGetCommand) Run(ctx *cmd.Context) error {
	credential, err := c.ctx.CloudSpec()
	if err != nil {
		return errors.Annotatef(err, "cannot access cloud credentials")
	}
	return c.out.Write(ctx, credential)
}
796579
func (c *listCommand) Run(ctx *cmd.Context) error {
	if err := c.validateIaasController(c.Info().Name); err != nil {
		return errors.Trace(err)
	}
	if c.Log != nil {
		if err := c.Log.Start(ctx); err != nil {
			return err
		}
	}
	client, err := c.NewAPIClient()
	if err != nil {
		return errors.Trace(err)
	}
	defer client.Close()

	result, err := client.List()
	if err != nil {
		return errors.Trace(err)
	}

	if len(result.List) == 0 {
		ctx.Infof("No backups to display.")
		return nil
	}

	verbose := c.Log != nil && c.Log.Verbose
	if verbose {
		c.dumpMetadata(ctx, &result.List[0])
	} else {
		fmt.Fprintln(ctx.Stdout, result.List[0].ID)
	}
	for _, resultItem := range result.List[1:] {
		if verbose {
			fmt.Fprintln(ctx.Stdout)
			c.dumpMetadata(ctx, &resultItem)
		} else {
			fmt.Fprintln(ctx.Stdout, resultItem.ID)
		}
	}
	return nil
}
169351
func (cmd *Command) Run(args []string) {
	cmd.Flags.SetOutput(ioutil.Discard)

	err := cmd.Flags.Parse(args)
	if err != nil {
		cmd.Usage()
		fmt.Fprintf(os.Stderr, "\nError: %v\n", err)
		os.Exit(2)
	}
	subArgs := cmd.Flags.Args()

	if len(subArgs) == 0 {
		cmd.Action(cmd, subArgs)
		return
	}

	name := subArgs[0]
	for _, subcmd := range cmd.Subcmds {
		if subcmd.Name() == name {
			subcmd.Run(subArgs[1:])
			return
		}
	}

	cmd.Action(cmd, subArgs)
}
217941
func (c *restoreCommand) Run(ctx *cmd.Context) error {
	if err := c.validateIaasController(c.Info().Name); err != nil {
		return errors.Trace(err)
	}
	if c.Log != nil {
		if err := c.Log.Start(ctx); err != nil {
			return err
		}
	}

	// Don't allow restore in an HA environment
	controllerModelUUID, modelStatus, err := c.modelStatus()
	if err != nil {
		return errors.Trace(err)
	}
	activeCount, _ := controller.ControllerMachineCounts(controllerModelUUID, modelStatus)
	if activeCount > 1 {
		return errors.Errorf("unable to restore backup in HA configuration.  For help see https://docs.jujucharms.com/stable/controllers-backup")
	}

	var archive ArchiveReader
	var meta *params.BackupsMetadataResult
	target := c.BackupId
	if c.Filename != "" {
		// Read archive specified by the Filename
		target = c.Filename
		var err error
		archive, meta, err = getArchive(c.Filename)
		if err != nil {
			return errors.Trace(err)
		}
		defer archive.Close()
	}

	client, err := c.NewAPIClient()
	if err != nil {
		return errors.Trace(err)
	}
	defer client.Close()

	// We have a backup client, now use the relevant method
	// to restore the backup.
	if c.Filename != "" {
		err = client.RestoreReader(archive, meta, c.newClient)
	} else {
		err = client.Restore(c.BackupId, c.newClient)
	}
	if err != nil {
		return errors.Trace(err)
	}
	fmt.Fprintf(ctx.Stdout, "restore from %q completed\n", target)
	return nil
}
919925
func (c *DeprecatedCommand) Run(args []string) int {
	c.warn()
	return c.Command.Run(args)
}
637869
func (c *destroyCommand) Run(ctx *cmd.Context) error {
	noWaitSet := false
	forceSet := false
	c.fs.Visit(func(flag *gnuflag.Flag) {
		if flag.Name == "no-wait" {
			noWaitSet = true
		} else if flag.Name == "force" {
			forceSet = true
		}
	})
	if !forceSet && noWaitSet {
		return errors.NotValidf("--no-wait without --force")
	}

	store := c.ClientStore()
	controllerName, err := c.ControllerName()
	if err != nil {
		return errors.Trace(err)
	}

	controllerDetails, err := store.ControllerByName(controllerName)
	if err != nil {
		return errors.Annotate(err, "cannot read controller details")
	}
	modelName, modelDetails, err := c.ModelDetails()
	if err != nil {
		return errors.Trace(err)
	}

	if modelDetails.ModelUUID == controllerDetails.ControllerUUID {
		return errors.Errorf("%q is a controller; use 'juju destroy-controller' to destroy it", modelName)
	}

	if !c.assumeYes {
		modelType, err := c.ModelType()
		if err != nil {
			return errors.Trace(err)
		}
		msg := destroyIAASModelMsg
		if modelType == model.CAAS {
			msg = destroyCAASModelMsg
		}
		fmt.Fprintf(ctx.Stdout, msg, modelName)

		if err := jujucmd.UserConfirmYes(ctx); err != nil {
			return errors.Annotate(err, "model destruction")
		}
	}

	// Attempt to connect to the API.  If we can't, fail the destroy.
	api, err := c.getAPI()
	if err != nil {
		return errors.Annotate(err, "cannot connect to API")
	}
	defer api.Close()

	configAPI, err := c.getModelConfigAPI()
	if err != nil {
		return errors.Annotate(err, "cannot connect to API")
	}
	defer configAPI.Close()

	// Check if the model has an SLA set.
	slaIsSet := false
	slaLevel, err := configAPI.SLALevel()
	if err == nil {
		slaIsSet = slaLevel != "" && slaLevel != slaUnsupported
	} else {
		logger.Debugf("could not determine model SLA level: %v", err)
	}

	if api.BestAPIVersion() < 4 {
		// Versions before 4 support only destroying the storage,
		// and will not raise an error if there is storage in the
		// controller. Force the user to specify up-front.
		if c.releaseStorage {
			return errors.New("this juju controller only supports destroying storage")
		}
		if !c.destroyStorage {
			storageAPI, err := c.getStorageAPI()
			if err != nil {
				return errors.Trace(err)
			}
			defer storageAPI.Close()

			storageDetails, err := storageAPI.ListStorageDetails()
			if err != nil {
				return errors.Trace(err)
			}
			if len(storageDetails) > 0 {
				return errors.Errorf(`cannot destroy model %q

Destroying this model will destroy the storage, but you
have not indicated that you want to do that.

Please run the the command again with --destroy-storage
to confirm that you want to destroy the storage along
with the model.

If instead you want to keep the storage, you must first
upgrade the controller to version 2.3 or greater.

`, modelName)
			}
			c.destroyStorage = true
		}
	}

	// Attempt to destroy the model.
	ctx.Infof("Destroying model")
	var destroyStorage *bool
	if c.destroyStorage || c.releaseStorage {
		destroyStorage = &c.destroyStorage
	}
	var force *bool
	var maxWait *time.Duration
	if c.Force {
		force = &c.Force
		if c.NoWait {
			zeroSec := 0 * time.Second
			maxWait = &zeroSec
		}
	}
	modelTag := names.NewModelTag(modelDetails.ModelUUID)
	if err := api.DestroyModel(modelTag, destroyStorage, force, maxWait); err != nil {
		return c.handleError(
			modelTag, modelName, api,
			errors.Annotate(err, "cannot destroy model"),
		)
	}

	// Wait for model to be destroyed.
	if err := waitForModelDestroyed(
		ctx, api,
		names.NewModelTag(modelDetails.ModelUUID),
		c.timeout,
		c.clock,
	); err != nil {
		return err
	}

	// Check if the model has an sla auth.
	if slaIsSet {
		err = c.removeModelBudget(modelDetails.ModelUUID)
		if err != nil {
			ctx.Warningf("model allocation not removed: %v", err)
		}
	}

	c.RemoveModelFromClientStore(store, controllerName, modelName)
	return nil
}
33630
func (c *ListCharmResourcesCommand) Run(ctx *cmd.Context) error {
	ctx.Warningf(DeprecatedSince)
	return c.baseRun(ctx)
}
592255
func (c *exposeCommand) Run(_ *cmd.Context) error {
	client, err := c.getAPI()
	if err != nil {
		return err
	}
	defer client.Close()
	return block.ProcessBlockedError(client.Expose(c.ApplicationName), block.BlockChange)
}
1167217
func (c *ActionSetCommand) Run(ctx *cmd.Context) error {
	for _, argSlice := range c.args {
		valueIndex := len(argSlice) - 1
		keys := argSlice[:valueIndex]
		value := argSlice[valueIndex]
		err := c.ctx.UpdateActionResults(keys, value)
		if err != nil {
			return err
		}
	}

	return nil
}
304733
func (c *showCommand) Run(ctx *cmd.Context) error {
	if err := c.validateIaasController(c.Info().Name); err != nil {
		return errors.Trace(err)
	}
	if c.Log != nil {
		if err := c.Log.Start(ctx); err != nil {
			return err
		}
	}
	client, err := c.NewAPIClient()
	if err != nil {
		return errors.Trace(err)
	}
	defer client.Close()

	result, err := client.Info(c.ID)
	if err != nil {
		return errors.Trace(err)
	}

	c.dumpMetadata(ctx, result)
	return nil
}
553728
func (c *RemoveCommand) Run(ctx *cmd.Context) error {
	return c.RunWithAPI(ctx, func(api SpaceAPI, ctx *cmd.Context) error {
		// Remove the space.
		err := api.RemoveSpace(c.name)
		if err != nil {
			return errors.Annotatef(err, "cannot remove space %q", c.name)
		}
		ctx.Infof("removed space %q", c.name)
		return nil
	})
}
329182
func (c *migrateCommand) Run(ctx *cmd.Context) error {
	spec, err := c.getMigrationSpec()
	if err != nil {
		return err
	}
	modelName, err := c.ModelName()
	if err != nil {
		return errors.Trace(err)
	}
	uuids, err := c.ModelUUIDs([]string{modelName})
	if err != nil {
		return errors.Trace(err)
	}
	spec.ModelUUID = uuids[0]
	if err := c.checkMigrationFeasibility(spec); err != nil {
		return errors.Trace(err)
	}
	controllerName, err := c.ControllerName()
	if err != nil {
		return err
	}
	api, err := c.getMigrationAPI(controllerName)
	if err != nil {
		return err
	}
	defer func() { _ = api.Close() }()
	id, err := api.InitiateMigration(*spec)
	if err != nil {
		return err
	}
	ctx.Infof("Migration started with ID %q", id)
	return nil
}