Ejemplo n.º 1
0
// Run connects to the environment specified on the command line and bootstraps
// a juju in that environment if none already exists. If there is as yet no environments.yaml file,
// the user is informed how to create one.
func (c *BootstrapCommand) Run(ctx *cmd.Context) (resultErr error) {
	bootstrapFuncs := getBootstrapFuncs()

	if len(c.seriesOld) > 0 {
		fmt.Fprintln(ctx.Stderr, "Use of --series is deprecated. Please use --upload-series instead.")
	}

	environ, cleanup, err := environFromName(ctx, c.EnvName, &resultErr, "Bootstrap")
	if err != nil {
		return err
	}
	validator, err := environ.ConstraintsValidator()
	if err != nil {
		return err
	}
	unsupported, err := validator.Validate(c.Constraints)
	if len(unsupported) > 0 {
		logger.Warningf("unsupported constraints: %v", err)
	} else if err != nil {
		return err
	}

	defer cleanup()
	if err := bootstrapFuncs.EnsureNotBootstrapped(environ); err != nil {
		return err
	}

	// Block interruption during bootstrap. Providers may also
	// register for interrupt notification so they can exit early.
	interrupted := make(chan os.Signal, 1)
	defer close(interrupted)
	ctx.InterruptNotify(interrupted)
	defer ctx.StopInterruptNotify(interrupted)
	go func() {
		for _ = range interrupted {
			ctx.Infof("Interrupt signalled: waiting for bootstrap to exit")
		}
	}()

	// If --metadata-source is specified, override the default tools metadata source so
	// SyncTools can use it, and also upload any image metadata.
	if c.MetadataSource != "" {
		metadataDir := ctx.AbsPath(c.MetadataSource)
		logger.Infof("Setting default tools and image metadata sources: %s", metadataDir)
		tools.DefaultBaseURL = metadataDir
		if err := imagemetadata.UploadImageMetadata(environ.Storage(), metadataDir); err != nil {
			// Do not error if image metadata directory doesn't exist.
			if !os.IsNotExist(err) {
				return fmt.Errorf("uploading image metadata: %v", err)
			}
		} else {
			logger.Infof("custom image metadata uploaded")
		}
	}
	// TODO (wallyworld): 2013-09-20 bug 1227931
	// We can set a custom tools data source instead of doing an
	// unnecessary upload.
	if environ.Config().Type() == provider.Local {
		c.UploadTools = true
	}
	if c.UploadTools {
		err = bootstrapFuncs.UploadTools(ctx, environ, c.Constraints.Arch, true, c.Series...)
		if err != nil {
			return err
		}
	}
	return bootstrapFuncs.Bootstrap(ctx, environ, environs.BootstrapParams{
		Constraints: c.Constraints,
		Placement:   c.Placement,
	})
}