// checkEnvironConfig returns an error if the config is definitely invalid. func checkEnvironConfig(cfg *config.Config) error { if cfg.AdminSecret() != "" { return fmt.Errorf("admin-secret should never be written to the state") } if _, ok := cfg.AgentVersion(); !ok { return fmt.Errorf("agent-version must always be set in state") } return nil }
// BootstrapConfig returns a copy of the supplied configuration with the // admin-secret and ca-private-key attributes removed. If the resulting // config is not suitable for bootstrapping an environment, an error is // returned. func BootstrapConfig(cfg *config.Config) (*config.Config, error) { m := cfg.AllAttrs() // We never want to push admin-secret or the root CA private key to the cloud. delete(m, "admin-secret") delete(m, "ca-private-key") cfg, err := config.New(config.NoDefaults, m) if err != nil { return nil, err } if _, ok := cfg.AgentVersion(); !ok { return nil, fmt.Errorf("environment configuration has no agent-version") } return cfg, nil }
// Open implements environs.EnvironProvider.Open. func (environProvider) Open(cfg *config.Config) (environs.Environ, error) { logger.Infof("opening environment %q", cfg.Name()) if _, ok := cfg.AgentVersion(); !ok { newCfg, err := cfg.Apply(map[string]interface{}{ "agent-version": version.Current.Number.String(), }) if err != nil { return nil, err } cfg = newCfg } // Set the "namespace" attribute. We do this here, and not in Prepare, // for backwards compatibility: older versions did not store the namespace // in config. if namespace, _ := cfg.UnknownAttrs()["namespace"].(string); namespace == "" { username := os.Getenv("USER") if username == "" { u, err := userCurrent() if err != nil { return nil, fmt.Errorf("failed to determine username for namespace: %v", err) } username = u.Username } var err error namespace = fmt.Sprintf("%s-%s", username, cfg.Name()) cfg, err = cfg.Apply(map[string]interface{}{"namespace": namespace}) if err != nil { return nil, fmt.Errorf("failed to create namespace: %v", err) } } // Do the initial validation on the config. localConfig, err := providerInstance.newConfig(cfg) if err != nil { return nil, err } if err := VerifyPrerequisites(localConfig.container()); err != nil { return nil, fmt.Errorf("failed verification of local provider prerequisites: %v", err) } environ := &localEnviron{name: cfg.Name()} if err := environ.SetConfig(cfg); err != nil { return nil, fmt.Errorf("failure setting config: %v", err) } return environ, nil }
// initVersions collects state relevant to an upgrade decision. The returned // agent and client versions, and the list of currently available tools, will // always be accurate; the chosen version, and the flag indicating development // mode, may remain blank until uploadTools or validate is called. func (c *UpgradeJujuCommand) initVersions(client *api.Client, cfg *config.Config) (*upgradeContext, error) { agent, ok := cfg.AgentVersion() if !ok { // Can't happen. In theory. return nil, fmt.Errorf("incomplete environment configuration") } if c.Version == agent { return nil, errUpToDate } clientVersion := version.Current.Number findResult, err := client.FindTools(clientVersion.Major, -1, "", "") var availableTools coretools.List if params.IsCodeNotImplemented(err) { availableTools, err = findTools1dot17(cfg) } else { availableTools = findResult.List } if err != nil { return nil, err } err = findResult.Error if findResult.Error != nil { if !params.IsCodeNotFound(err) { return nil, err } if !c.UploadTools { // No tools found and we shouldn't upload any, so if we are not asking for a // major upgrade, pretend there is no more recent version available. if c.Version == version.Zero && agent.Major == clientVersion.Major { return nil, errUpToDate } return nil, err } } return &upgradeContext{ agent: agent, client: clientVersion, chosen: c.Version, tools: availableTools, apiClient: client, config: cfg, }, nil }