// 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(cfg *config.Config, env environs.Environ) (*upgradeVersions, 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 } client := version.Current.Number available, err := environs.FindAvailableTools(env, client.Major) if err != nil { if !errors.IsNotFoundError(err) { return nil, err } if !c.UploadTools { if c.Version == version.Zero { return nil, errUpToDate } return nil, err } } dev := c.Development || cfg.Development() || agent.IsDev() || client.IsDev() return &upgradeVersions{ dev: dev, agent: agent, client: client, chosen: c.Version, tools: available, }, nil }
// BootstrapConfig returns a copy of the supplied configuration with // secret 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) { p, err := Provider(cfg.Type()) if err != nil { return nil, err } secrets, err := p.SecretAttrs(cfg) if err != nil { return nil, err } m := cfg.AllAttrs() for k := range secrets { delete(m, k) } // We never want to push admin-secret or the root CA private key to the cloud. delete(m, "admin-secret") m["ca-private-key"] = "" if cfg, err = config.New(m); err != nil { return nil, err } if _, ok := cfg.AgentVersion(); !ok { return nil, fmt.Errorf("environment configuration has no agent-version") } return cfg, nil }
// 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 }
// Open implements environs.EnvironProvider.Open. func (environProvider) Open(cfg *config.Config) (env environs.Environ, err error) { logger.Infof("opening environment %q", cfg.Name()) if _, ok := cfg.AgentVersion(); !ok { cfg, err = cfg.Apply(map[string]interface{}{ "agent-version": version.CurrentNumber().String(), }) if err != nil { return nil, err } } environ := &localEnviron{name: cfg.Name()} err = environ.SetConfig(cfg) if err != nil { logger.Errorf("failure setting config: %v", err) return nil, err } return environ, nil }