// Run runs set of commands on multiple hosts defined by network sequentially.
// TODO: This megamoth method needs a big refactor and should be split
//       to multiple smaller methods.
349722
func (sup *Stackup) Run(network *Network, envVars EnvList, commands ...*Command) error {
	if len(commands) == 0 {
		return errors.New("no commands to be run")
	}

	env := envVars.AsExport()

	// Create clients for every host (either SSH or Localhost).
	var bastion *SSHClient
	if network.Bastion != "" {
		bastion = &SSHClient{}
		if err := bastion.Connect(network.Bastion); err != nil {
			return errors.Wrap(err, "connecting to bastion failed")
		}
	}

	var wg sync.WaitGroup
	clientCh := make(chan Client, len(network.Hosts))
	errCh := make(chan error, len(network.Hosts))

	for i, host := range network.Hosts {
		wg.Add(1)
		go func(i int, host string) {
			defer wg.Done()

			// Localhost client.
			if host == "localhost" {
				local := &LocalhostClient{
					env: env + `export SUP_HOST="` + host + `";`,
				}
				if err := local.Connect(host); err != nil {
					errCh <- errors.Wrap(err, "connecting to localhost failed")
					return
				}
				clientCh <- local
				return
			}

			// SSH client.
			remote := &SSHClient{
				env:   env + `export SUP_HOST="` + host + `";`,
				user:  network.User,
				color: Colors[i%len(Colors)],
			}

			if bastion != nil {
				if err := remote.ConnectWith(host, bastion.DialThrough); err != nil {
					errCh <- errors.Wrap(err, "connecting to remote host through bastion failed")
					return
				}
			} else {
				if err := remote.Connect(host); err != nil {
					errCh <- errors.Wrap(err, "connecting to remote host failed")
					return
				}
			}
			clientCh <- remote
		}(i, host)
	}
	wg.Wait()
	close(clientCh)
	close(errCh)

	maxLen := 0
	var clients []Client
	for client := range clientCh {
		if remote, ok := client.(*SSHClient); ok {
			defer remote.Close()
		}
		_, prefixLen := client.Prefix()
		if prefixLen > maxLen {
			maxLen = prefixLen
		}
		clients = append(clients, client)
	}
	for err := range errCh {
		return errors.Wrap(err, "connecting to clients failed")
	}

	// Run command or run multiple commands defined by target sequentially.
	for _, cmd := range commands {
		// Translate command into task(s).
		tasks, err := sup.createTasks(cmd, clients, env)
		if err != nil {
			return errors.Wrap(err, "creating task failed")
		}

		// Run tasks sequentially.
		for _, task := range tasks {
			var writers []io.Writer
			var wg sync.WaitGroup

			// Run tasks on the provided clients.
			for _, c := range task.Clients {
				var prefix string
				var prefixLen int
				if sup.prefix {
					prefix, prefixLen = c.Prefix()
					if len(prefix) < maxLen { // Left padding.
						prefix = strings.Repeat(" ", maxLen-prefixLen) + prefix
					}
				}

				err := c.Run(task)
				if err != nil {
					return errors.Wrap(err, prefix+"task failed")
				}

				// Copy over tasks's STDOUT.
				wg.Add(1)
				go func(c Client) {
					defer wg.Done()
					_, err := io.Copy(os.Stdout, prefixer.New(c.Stdout(), prefix))
					if err != nil && err != io.EOF {
						// TODO: io.Copy() should not return io.EOF at all.
						// Upstream bug? Or prefixer.WriteTo() bug?
						fmt.Fprintf(os.Stderr, "%v", errors.Wrap(err, prefix+"reading STDOUT failed"))
					}
				}(c)

				// Copy over tasks's STDERR.
				wg.Add(1)
				go func(c Client) {
					defer wg.Done()
					_, err := io.Copy(os.Stderr, prefixer.New(c.Stderr(), prefix))
					if err != nil && err != io.EOF {
						fmt.Fprintf(os.Stderr, "%v", errors.Wrap(err, prefix+"reading STDERR failed"))
					}
				}(c)

				writers = append(writers, c.Stdin())
			}

			// Copy over task's STDIN.
			if task.Input != nil {
				go func() {
					writer := io.MultiWriter(writers...)
					_, err := io.Copy(writer, task.Input)
					if err != nil && err != io.EOF {
						fmt.Fprintf(os.Stderr, "%v", errors.Wrap(err, "copying STDIN failed"))
					}
					// TODO: Use MultiWriteCloser (not in Stdlib), so we can writer.Close() instead?
					for _, c := range clients {
						c.WriteClose()
					}
				}()
			}

			// Catch OS signals and pass them to all active clients.
			trap := make(chan os.Signal, 1)
			signal.Notify(trap, os.Interrupt)
			go func() {
				for {
					select {
					case sig, ok := <-trap:
						if !ok {
							return
						}
						for _, c := range task.Clients {
							err := c.Signal(sig)
							if err != nil {
								fmt.Fprintf(os.Stderr, "%v", errors.Wrap(err, "sending signal failed"))
							}
						}
					}
				}
			}()

			// Wait for all I/O operations first.
			wg.Wait()

			// Make sure each client finishes the task, return on failure.
			for _, c := range task.Clients {
				wg.Add(1)
				go func(c Client) {
					defer wg.Done()
					if err := c.Wait(); err != nil {
						var prefix string
						if sup.prefix {
							var prefixLen int
							prefix, prefixLen = c.Prefix()
							if len(prefix) < maxLen { // Left padding.
								prefix = strings.Repeat(" ", maxLen-prefixLen) + prefix
							}
						}
						if e, ok := err.(*ssh.ExitError); ok && e.ExitStatus() != 15 {
							// TODO: Store all the errors, and print them after Wait().
							fmt.Fprintf(os.Stderr, "%s%v\n", prefix, e)
							os.Exit(e.ExitStatus())
						}
						fmt.Fprintf(os.Stderr, "%s%v\n", prefix, err)

						// TODO: Shouldn't os.Exit(1) here. Instead, collect the exit statuses for later.
						os.Exit(1)
					}
				}(c)
			}

			// Wait for all commands to finish.
			wg.Wait()

			// Stop catching signals for the currently active clients.
			signal.Stop(trap)
			close(trap)
		}
	}

	return nil
}
127484
func (c *AddMachineCmd) Run(app subcommands.Application, args []string, env subcommands.Env) int {
	ctx := cli.GetContext(app, c, env)
	// TODO(smut): Validate required fields client-side.
	req := &crimson.CreateMachineRequest{
		Machine: &c.machine,
	}
	client := getClient(ctx)
	resp, err := client.CreateMachine(ctx, req)
	if err != nil {
		errors.Log(ctx, err)
		return 1
	}
	printMachines(c.f.tsv, resp)
	return 0
}
285948
func (c *listCommand) Run(ctx *cmd.Context) (err error) {
	if c.all {
		return c.listForController(ctx)
	}
	return c.listForModel(ctx)
}
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)
}
421616
func (*ExecRunner) Run(cmd string) error {
	glog.Infoln("Run:", cmd)
	c := exec.Command("/bin/bash", "-c", cmd)
	if err := c.Run(); err != nil {
		return errors.Wrapf(err, "running command: %s", cmd)
	}
	return nil
}
1150463
func (c *removeCommand) Run(ctx *cmd.Context) (err error) {
	client, err := getRemoveImageAPI(&c.CachedImagesCommandBase)
	if err != nil {
		return err
	}
	defer client.Close()

	return client.DeleteImage(c.Kind, c.Series, c.Arch)
}
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
	})
}
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)
}
980114
func (c *setPlanCommand) Run(ctx *cmd.Context) error {
	root, err := c.NewAPIRoot()
	if err != nil {
		return errors.Trace(err)
	}
	client := application.NewClient(root)
	credentials, err := c.requestMetricCredentials(client, ctx)
	if err != nil {
		return errors.Trace(err)
	}
	err = client.SetMetricCredentials(c.Application, credentials)
	if err != nil {
		return errors.Trace(err)
	}
	return nil
}
958935
func (c *RenameCommand) Run(ctx *cmd.Context) error {
	return c.RunWithAPI(ctx, func(api SpaceAPI, ctx *cmd.Context) error {
		err := api.RenameSpace(c.Name, c.NewName)
		if err != nil {
			return errors.Annotatef(err, "cannot rename space %q", c.Name)
		}

		ctx.Infof("renamed space %q to %q", c.Name, c.NewName)
		return nil
	})
}
1343988
func (a *MachineAgent) Run(*cmd.Context) (err error) {
	defer a.Done(err)
	useMultipleCPUs()
	if err := a.ReadConfig(a.Tag().String()); err != nil {
		return errors.Errorf("cannot read agent configuration: %v", err)
	}

	setupAgentLogging(a.CurrentConfig())

	if err := introspection.WriteProfileFunctions(); err != nil {
		// This isn't fatal, just annoying.
		logger.Errorf("failed to write profile funcs: %v", err)
	}

	// When the API server and peergrouper have manifolds, they can
	// have dependencies on a central hub worker.
	a.centralHub = centralhub.New(a.Tag().(names.MachineTag))

	// Before doing anything else, we need to make sure the certificate generated for
	// use by mongo to validate controller connections is correct. This needs to be done
	// before any possible restart of the mongo service.
	// See bug http://pad.lv/1434680
	if err := a.AgentConfigWriter.ChangeConfig(upgradeCertificateDNSNames); err != nil {
		return errors.Annotate(err, "error upgrading server certificate")
	}

	// moved from NewMachineAgent here because the agent config could not be ready yet there.
	if err := a.registerPrometheusCollectors(); err != nil {
		return errors.Trace(err)
	}

	agentConfig := a.CurrentConfig()
	agentName := a.Tag().String()
	machineLock, err := machinelock.New(machinelock.Config{
		AgentName:   agentName,
		Clock:       clock.WallClock,
		Logger:      loggo.GetLogger("juju.machinelock"),
		LogFilename: agent.MachineLockLogFilename(agentConfig),
	})
	// There will only be an error if the required configuration
	// values are not passed in.
	if err != nil {
		return errors.Trace(err)
	}
	a.machineLock = machineLock
	a.upgradeComplete = upgradesteps.NewLock(agentConfig)

	createEngine := a.makeEngineCreator(agentName, agentConfig.UpgradedToVersion())
	charmrepo.CacheDir = filepath.Join(agentConfig.DataDir(), "charmcache")
	if err := a.createJujudSymlinks(agentConfig.DataDir()); err != nil {
		return err
	}
	a.runner.StartWorker("engine", createEngine)

	// At this point, all workers will have been configured to start
	close(a.workersStarted)
	err = a.runner.Wait()
	switch errors.Cause(err) {
	case jworker.ErrTerminateAgent:
		err = a.uninstallAgent()
	case jworker.ErrRebootMachine:
		logger.Infof("Caught reboot error")
		err = a.executeRebootOrShutdown(params.ShouldReboot)
	case jworker.ErrShutdownMachine:
		logger.Infof("Caught shutdown error")
		err = a.executeRebootOrShutdown(params.ShouldShutdown)
	}
	return cmdutil.AgentDone(logger, err)
}
371131
func (config *Config) Run(cmd string) (string, error) {
	if config.DisplayOutput == true {
		fmt.Printf("run: %s\n", cmd)
	}
	return config.doRun(cmd, false)
}
461003
func (cmd *GenerateConfigCommand) Run(_ context.Context) error {
	conf := server.NewConfig()
	ret, err := toml.Marshal(*conf)
	if err != nil {
		return errors.Wrap(err, "unmarshalling default config")
	}
	fmt.Fprintf(cmd.Stdout, "%s\n", ret)
	return nil
}
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)
}
1139065
func Run(argv interface{}, fn CommandFunc, descs ...string) int {
	return RunWithArgs(argv, os.Args, fn, descs...)
}
903734
func (c *TechSupportCommand) Run(args []string) int {
	c.InitOpts()
	rest, err := c.parseOpts(args)
	if err != nil {
		if errwrap.Contains(err, "flag: help requested") {
			return 0
		}
		return 1
	}
	if len(rest) != 0 {
		c.Ui.Error(c.Help())
		return 1
	}

	ri, err := sockaddr.NewRouteInfo()
	if err != nil {
		c.Ui.Error(fmt.Sprintf("error loading route information: %v", err))
		return 1
	}

	const initNumCmds = 4
	type cmdResult struct {
		cmd []string
		out string
	}
	output := make(map[string]cmdResult, initNumCmds)
	ri.VisitCommands(func(name string, cmd []string) {
		out, err := exec.Command(cmd[0], cmd[1:]...).Output()
		if err != nil {
			out = []byte(fmt.Sprintf("ERROR: command %q failed: %v", name, err))
		}

		output[name] = cmdResult{
			cmd: cmd,
			out: string(out),
		}
	})

	out := c.rowWriterOutputFactory()

	for cmdName, result := range output {
		switch c.outputMode {
		case "md":
			c.Ui.Output(fmt.Sprintf("## cmd: `%s`", cmdName))
			c.Ui.Output("")
			c.Ui.Output(fmt.Sprintf("Command: `%#v`", result.cmd))
			c.Ui.Output("```")
			c.Ui.Output(result.out)
			c.Ui.Output("```")
			c.Ui.Output("")
		case "raw":
			c.Ui.Output(fmt.Sprintf("cmd: %q: %#v", cmdName, result.cmd))
			c.Ui.Output("")
			c.Ui.Output(result.out)
			c.Ui.Output("")
		default:
			c.Ui.Error(fmt.Sprintf("Unsupported output type: %q", c.outputMode))
			return 1
		}

		out("s", "GOOS", runtime.GOOS)
		out("s", "GOARCH", runtime.GOARCH)
		out("s", "Compiler", runtime.Compiler)
		out("s", "Version", runtime.Version())
		ifs, err := net.Interfaces()
		if err != nil {
			out("v", "net.Interfaces", err)
		} else {
			for i, intf := range ifs {
				out("s", fmt.Sprintf("net.Interfaces[%d].Name", i), intf.Name)
				out("s", fmt.Sprintf("net.Interfaces[%d].Flags", i), intf.Flags)
				out("+v", fmt.Sprintf("net.Interfaces[%d].Raw", i), intf)
				addrs, err := intf.Addrs()
				if err != nil {
					out("v", fmt.Sprintf("net.Interfaces[%d].Addrs", i), err)
				} else {
					for j, addr := range addrs {
						out("s", fmt.Sprintf("net.Interfaces[%d].Addrs[%d]", i, j), addr)
					}
				}
			}
		}
	}

	return 0
}
1028522
func (c *command) run() []byte {
	cmd := exec.Command(c.program, c.args...)
	var stdout, stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	err := cmd.Run()
	out := stdout.Bytes()
	if err != nil {
		log.Fatalf("Could not run %v: %v: %v: %v", c, err, string(out), stderr.String())
	}
	return out
}