예제 #1
0
파일: deploy.go 프로젝트: kat-co/juju
func (c *DeployCommand) Run(ctx *cmd.Context) error {
	var err error
	c.Constraints, err = common.ParseConstraints(ctx, c.ConstraintsStr)
	if err != nil {
		return err
	}
	apiRoot, err := c.NewAPIRoot()
	if err != nil {
		return errors.Trace(err)
	}
	defer apiRoot.Close()

	deploy, err := findDeployerFIFO(
		c.maybeReadLocalBundle,
		c.maybeReadLocalCharm,
		c.maybePredeployedLocalCharm,
		c.maybeReadCharmstoreBundleFn(apiRoot),
		c.charmStoreCharm, // This always returns a deployer
	)
	if err != nil {
		return errors.Trace(err)
	}

	return block.ProcessBlockedError(deploy(ctx, apiRoot), block.BlockChange)
}
예제 #2
0
파일: enableha.go 프로젝트: kat-co/juju
// Run connects to the environment specified on the command line
// and calls EnableHA.
func (c *enableHACommand) Run(ctx *cmd.Context) error {
	var err error
	c.Constraints, err = common.ParseConstraints(ctx, c.ConstraintsStr)
	if err != nil {
		return err
	}
	haClient, err := c.newHAClientFunc()
	if err != nil {
		return err
	}

	defer haClient.Close()
	enableHAResult, err := haClient.EnableHA(
		c.NumControllers,
		c.Constraints,
		c.Placement,
	)
	if err != nil {
		return block.ProcessBlockedError(err, block.BlockChange)
	}

	result := availabilityInfo{
		Added:      machineTagsToIds(enableHAResult.Added...),
		Removed:    machineTagsToIds(enableHAResult.Removed...),
		Maintained: machineTagsToIds(enableHAResult.Maintained...),
		Promoted:   machineTagsToIds(enableHAResult.Promoted...),
		Demoted:    machineTagsToIds(enableHAResult.Demoted...),
		Converted:  machineTagsToIds(enableHAResult.Converted...),
	}
	return c.out.Write(ctx, result)
}
예제 #3
0
파일: restore.go 프로젝트: bac/juju
// Run is the entry point for this command.
func (c *restoreCommand) Run(ctx *cmd.Context) error {
	var err error
	c.constraints, err = common.ParseConstraints(ctx, c.constraintsStr)
	if err != nil {
		return err
	}

	if c.Log != nil {
		if err := c.Log.Start(ctx); err != nil {
			return err
		}
	}

	var archive ArchiveReader
	var meta *params.BackupsMetadataResult
	target := c.backupId
	if c.filename != "" {
		// Read archive specified by the filename;
		// we'll need the info later regardless if
		// we need it now to rebootstrap.
		target = c.filename
		var err error
		archive, meta, err = c.getArchiveFunc(c.filename)
		if err != nil {
			return errors.Trace(err)
		}
		defer archive.Close()

		if c.bootstrap {
			if err := c.rebootstrap(ctx, meta); err != nil {
				return errors.Trace(err)
			}
		}
	}

	client, err := c.newAPIClientFunc()
	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
}
예제 #4
0
파일: add.go 프로젝트: bac/juju
func (c *addCommand) Run(ctx *cmd.Context) error {
	var err error
	c.Constraints, err = common.ParseConstraints(ctx, c.ConstraintsStr)
	if err != nil {
		return err
	}
	client, err := c.getClientAPI()
	if err != nil {
		return errors.Trace(err)
	}
	defer client.Close()

	var machineManager MachineManagerAPI
	if len(c.Disks) > 0 {
		machineManager, err = c.getMachineManagerAPI()
		if err != nil {
			return errors.Trace(err)
		}
		defer machineManager.Close()
		if machineManager.BestAPIVersion() < 1 {
			return errors.New("cannot add machines with disks: not supported by the API server")
		}
	}

	logger.Infof("load config")
	modelConfigClient, err := c.getModelConfigAPI()
	if err != nil {
		return errors.Trace(err)
	}
	defer modelConfigClient.Close()
	configAttrs, err := modelConfigClient.ModelGet()
	if err != nil {
		if params.IsCodeUnauthorized(err) {
			common.PermissionsMessage(ctx.Stderr, "add a machine to this model")
		}
		return errors.Trace(err)
	}
	config, err := config.New(config.NoDefaults, configAttrs)
	if err != nil {
		return errors.Trace(err)
	}

	if c.Placement != nil && c.Placement.Scope == "ssh" {
		logger.Infof("manual provisioning")
		authKeys, err := common.ReadAuthorizedKeys(ctx, "")
		if err != nil {
			return errors.Annotate(err, "reading authorized-keys")
		}
		args := manual.ProvisionMachineArgs{
			Host:           c.Placement.Directive,
			Client:         client,
			Stdin:          ctx.Stdin,
			Stdout:         ctx.Stdout,
			Stderr:         ctx.Stderr,
			AuthorizedKeys: authKeys,
			UpdateBehavior: &params.UpdateBehavior{
				config.EnableOSRefreshUpdate(),
				config.EnableOSUpgrade(),
			},
		}
		machineId, err := manualProvisioner(args)
		if err == nil {
			ctx.Infof("created machine %v", machineId)
		}
		return err
	}

	logger.Infof("model provisioning")
	if c.Placement != nil && c.Placement.Scope == "model-uuid" {
		uuid, ok := client.ModelUUID()
		if !ok {
			return errors.New("API connection is controller-only (should never happen)")
		}
		c.Placement.Scope = uuid
	}

	if c.Placement != nil && c.Placement.Scope == instance.MachineScope {
		// It does not make sense to add-machine <id>.
		return errors.Errorf("machine-id cannot be specified when adding machines")
	}

	jobs := []multiwatcher.MachineJob{multiwatcher.JobHostUnits}

	machineParams := params.AddMachineParams{
		Placement:   c.Placement,
		Series:      c.Series,
		Constraints: c.Constraints,
		Jobs:        jobs,
		Disks:       c.Disks,
	}
	machines := make([]params.AddMachineParams, c.NumMachines)
	for i := 0; i < c.NumMachines; i++ {
		machines[i] = machineParams
	}

	var results []params.AddMachinesResult
	// If storage is specified, we attempt to use a new API on the service facade.
	if len(c.Disks) > 0 {
		results, err = machineManager.AddMachines(machines)
	} else {
		results, err = client.AddMachines(machines)
	}
	if params.IsCodeOperationBlocked(err) {
		return block.ProcessBlockedError(err, block.BlockChange)
	}
	if err != nil {
		return errors.Trace(err)
	}

	errs := []error{}
	for _, machineInfo := range results {
		if machineInfo.Error != nil {
			errs = append(errs, machineInfo.Error)
			continue
		}
		machineId := machineInfo.Machine

		if names.IsContainerMachine(machineId) {
			ctx.Infof("created container %v", machineId)
		} else {
			ctx.Infof("created machine %v", machineId)
		}
	}
	if len(errs) == 1 {
		fmt.Fprint(ctx.Stderr, "failed to create 1 machine\n")
		return errs[0]
	}
	if len(errs) > 1 {
		fmt.Fprintf(ctx.Stderr, "failed to create %d machines\n", len(errs))
		returnErr := []string{}
		for _, e := range errs {
			returnErr = append(returnErr, e.Error())
		}
		return errors.New(strings.Join(returnErr, ", "))
	}
	return nil
}