// addRequiredPackages is defined on the AdvancedPackagingConfig interface. func (cfg *centOSCloudConfig) addRequiredPackages() { packages := []string{ "curl", "bridge-utils", "cloud-utils", "nmap-ncat", "tmux", } if featureflag.Enabled(feature.DeveloperMode) { packages = append(packages, "socat") } // The required packages need to come from the correct repo. // For CentOS 7, this requires an rpm cloud archive be up. // In the event of the addition of such a repository, its addition should // happen in the utils/packaging/config package whilst leaving the below // code untouched. for _, pack := range packages { if config.SeriesRequiresCloudArchiveTools(cfg.series) && cfg.pacconfer.IsCloudArchivePackage(pack) { cfg.AddPackage(strings.Join(cfg.pacconfer.ApplyCloudArchiveTarget(pack), " ")) } else { cfg.AddPackage(pack) } } }
func versionInitSystem(ser string) (string, error) { seriesos, err := series.GetOSFromSeries(ser) if err != nil { notFound := errors.NotFoundf("init system for series %q", ser) return "", errors.Wrap(err, notFound) } switch seriesos { case os.Windows: return InitSystemWindows, nil case os.Ubuntu: switch ser { case "precise", "quantal", "raring", "saucy", "trusty", "utopic": return InitSystemUpstart, nil default: // vivid and later if featureflag.Enabled(feature.LegacyUpstart) { return InitSystemUpstart, nil } return InitSystemSystemd, nil } case os.CentOS: return InitSystemSystemd, nil } return "", errors.NotFoundf("unknown os %q (from series %q), init system", seriesos, ser) }
// decorateAndWriteInfo decorates the info struct with information // from the given cfg, and the writes that out to the filesystem. func decorateAndWriteInfo(info configstore.EnvironInfo, cfg *config.Config) error { // Sanity check our config. var endpoint configstore.APIEndpoint if cert, ok := cfg.CACert(); !ok { return errors.Errorf("CACert is not set") } else if uuid, ok := cfg.UUID(); !ok { return errors.Errorf("UUID is not set") } else if adminSecret := cfg.AdminSecret(); adminSecret == "" { return errors.Errorf("admin-secret is not set") } else { endpoint = configstore.APIEndpoint{ CACert: cert, EnvironUUID: uuid, } } creds := configstore.APICredentials{ User: configstore.DefaultAdminUsername, Password: cfg.AdminSecret(), } if featureflag.Enabled(feature.JES) { endpoint.ServerUUID = endpoint.EnvironUUID } info.SetAPICredentials(creds) info.SetAPIEndpoint(endpoint) info.SetBootstrapConfig(cfg.AllAttrs()) if err := info.Write(); err != nil { return errors.Annotatef(err, "cannot create environment info %q", cfg.Name()) } return nil }
// DestroyController implements the Environ interface. func (e *manualEnviron) DestroyController(controllerUUID string) error { script := ` set -x touch %s # If jujud is running, we then wait for a while for it to stop. stopped=0 if pkill -%d jujud; then for i in ` + "`seq 1 30`" + `; do if pgrep jujud > /dev/null ; then sleep 1 else echo "jujud stopped" stopped=1 break fi done fi if [ $stopped -ne 1 ]; then # If jujud didn't stop nicely, we kill it hard here. %spkill -9 jujud service %s stop fi rm -f /etc/init/juju* rm -f /etc/systemd/system/juju* rm -fr %s %s exit 0 ` var diagnostics string if featureflag.Enabled(feature.DeveloperMode) { diagnostics = ` echo "Dump engine report and goroutines for stuck jujud" source /etc/profile.d/juju-introspection.sh juju-engine-report juju-goroutines ` } script = fmt.Sprintf( script, // WARNING: this is linked with the use of uninstallFile in // the agent package. Don't change it without extreme care, // and handling for mismatches with already-deployed agents. utils.ShQuote(path.Join( agent.DefaultPaths.DataDir, agent.UninstallFile, )), terminationworker.TerminationSignal, diagnostics, mongo.ServiceName, utils.ShQuote(agent.DefaultPaths.DataDir), utils.ShQuote(agent.DefaultPaths.LogDir), ) logger.Tracef("destroy controller script: %s", script) stdout, stderr, err := runSSHCommand( "ubuntu@"+e.host, []string{"sudo", "/bin/bash"}, script, ) logger.Debugf("script stdout: \n%s", stdout) logger.Debugf("script stderr: \n%s", stderr) return err }
// checkProviderType ensures the provider type is okay. func checkProviderType(envType string) error { featureflag.SetFlagsFromEnvironment(osenv.JujuFeatureFlagEnvKey) flag, ok := provisionalProviders[envType] if ok && !featureflag.Enabled(flag) { msg := `the %q provider is provisional in this version of Juju. To use it anyway, set JUJU_DEV_FEATURE_FLAGS="%s" in your shell model` return errors.Errorf(msg, envType, flag) } return nil }
// lookup translates a facade name and version into a facadeRecord. func (f *FacadeRegistry) lookup(name string, version int) (facadeRecord, error) { if versions, ok := f.facades[name]; ok { if record, ok := versions[version]; ok { if featureflag.Enabled(record.feature) { return record, nil } } } return facadeRecord{}, errors.NotFoundf("%s(%d)", name, version) }
// Write implements EnvironInfo.Write. func (info *environInfo) Write() error { info.mu.Lock() defer info.mu.Unlock() lock, err := acquireEnvironmentLock(info.environmentDir, "writing") if err != nil { return errors.Annotatef(err, "cannot write info") } defer lock.Unlock() // In order to write out the environment info to the cache // file we need to make sure the server UUID is set. Sufficiently // up to date servers will write the server UUID to the JENV // file as connections are made to the API server. It is possible // that for an old JENV file, the first update (on API connection) // may write a JENV file, and the subsequent update will create the // entry in the cache file. // If the source was the cache file, then always write there to // avoid stale data in the cache file. if info.source == sourceCache || (featureflag.Enabled(feature.JES) && info.serverUUID != "") { if err := info.ensureNoJENV(); info.source == sourceCreated && err != nil { return errors.Trace(err) } logger.Debugf("writing cache file") filename := cacheFilename(info.environmentDir) cache, err := readCacheFile(filename) if err != nil { return errors.Trace(err) } if err := cache.updateInfo(info); err != nil { return errors.Trace(err) } if err := writeCacheFile(filename, cache); err != nil { return errors.Trace(err) } oldPath := info.path info.path = filename // If source was jenv file, delete the jenv. if info.source == sourceJenv { err := os.Remove(oldPath) if err != nil { return errors.Trace(err) } } info.source = sourceCache } else { logger.Debugf("writing jenv file") if err := info.writeJENVFile(); err != nil { return errors.Trace(err) } info.source = sourceJenv } return nil }
// descriptionFromVersions aggregates the information in a versions map into a // more friendly form for List(). func descriptionFromVersions(name string, vers versions) FacadeDescription { intVersions := make([]int, 0, len(vers)) for version, record := range vers { if featureflag.Enabled(record.feature) { intVersions = append(intVersions, version) } } sort.Ints(intVersions) return FacadeDescription{ Name: name, Versions: intVersions, } }
func (c *bootstrapCommand) SetFlags(f *gnuflag.FlagSet) { f.Var(constraints.ConstraintsValue{Target: &c.Constraints}, "constraints", "set model constraints") f.Var(constraints.ConstraintsValue{Target: &c.BootstrapConstraints}, "bootstrap-constraints", "specify bootstrap machine constraints") f.StringVar(&c.BootstrapSeries, "bootstrap-series", "", "specify the series of the bootstrap machine") if featureflag.Enabled(feature.ImageMetadata) { f.StringVar(&c.BootstrapImage, "bootstrap-image", "", "specify the image of the bootstrap machine") } f.BoolVar(&c.UploadTools, "upload-tools", false, "upload local version of tools before bootstrapping") f.StringVar(&c.MetadataSource, "metadata-source", "", "local path to use as tools and/or metadata source") f.StringVar(&c.Placement, "to", "", "a placement directive indicating an instance to bootstrap") f.BoolVar(&c.KeepBrokenEnvironment, "keep-broken", false, "do not destroy the model if bootstrap fails") f.BoolVar(&c.AutoUpgrade, "auto-upgrade", false, "upgrade to the latest patch release tools on first bootstrap") f.StringVar(&c.AgentVersionParam, "agent-version", "", "the version of tools to use for Juju agents") }
func (s *BaseSubnetSuite) SetUpTest(c *gc.C) { // If any post-MVP command suite enabled the flag, keep it. hasFeatureFlag := featureflag.Enabled(feature.PostNetCLIMVP) s.FakeJujuXDGDataHomeSuite.SetUpTest(c) if hasFeatureFlag { s.FakeJujuXDGDataHomeSuite.SetFeatureFlags(feature.PostNetCLIMVP) } s.api = NewStubAPI() c.Assert(s.api, gc.NotNil) // All subcommand suites embedding this one should initialize // s.command immediately after calling this method! }
// NewSuperCommand creates the "subnet" supercommand and registers the // subcommands that it supports. func NewSuperCommand() cmd.Command { subnetCmd := cmd.NewSuperCommand(cmd.SuperCommandParams{ Name: "subnet", Doc: strings.TrimSpace(commandDoc), UsagePrefix: "juju", Purpose: "manage subnets", }) subnetCmd.Register(envcmd.Wrap(&AddCommand{})) subnetCmd.Register(envcmd.Wrap(&ListCommand{})) if featureflag.Enabled(feature.PostNetCLIMVP) { // The following commands are not part of the MVP. subnetCmd.Register(envcmd.Wrap(&CreateCommand{})) subnetCmd.Register(envcmd.Wrap(&RemoveCommand{})) } return subnetCmd }
func (s *flagSuite) TestEnabled(c *gc.C) { c.Assert(featureflag.Enabled(""), jc.IsTrue) c.Assert(featureflag.Enabled(" "), jc.IsTrue) c.Assert(featureflag.Enabled("magic"), jc.IsFalse) s.PatchEnvironment("JUJU_TESTING_FEATURE", "MAGIC") featureflag.SetFlagsFromEnvironment("JUJU_TESTING_FEATURE") c.Assert(featureflag.Enabled("magic"), jc.IsTrue) c.Assert(featureflag.Enabled("Magic"), jc.IsTrue) c.Assert(featureflag.Enabled(" MAGIC "), jc.IsTrue) }
func (s *flagWinSuite) TestEnabled(c *gc.C) { c.Assert(featureflag.Enabled(""), jc.IsTrue) c.Assert(featureflag.Enabled(" "), jc.IsTrue) c.Assert(featureflag.Enabled("magic"), jc.IsFalse) s.k.SetStringValue("JUJU_TESTING_FEATURE", "MAGIC") featureflag.SetFlagsFromRegistry(regKey, "JUJU_TESTING_FEATURE") c.Assert(featureflag.Enabled("magic"), jc.IsTrue) c.Assert(featureflag.Enabled("Magic"), jc.IsTrue) c.Assert(featureflag.Enabled(" MAGIC "), jc.IsTrue) }
// NewSuperCommand creates the "space" supercommand and registers the // subcommands that it supports. func NewSuperCommand() cmd.Command { spaceCmd := cmd.NewSuperCommand(cmd.SuperCommandParams{ Name: "space", Doc: strings.TrimSpace(commandDoc), UsagePrefix: "juju", Purpose: "manage network spaces", }) spaceCmd.Register(newCreateCommand()) spaceCmd.Register(newListCommand()) if featureflag.Enabled(feature.PostNetCLIMVP) { // The following commands are not part of the MVP. spaceCmd.Register(newRemoveCommand()) spaceCmd.Register(newUpdateCommand()) spaceCmd.Register(newRenameCommand()) } return spaceCmd }
func (c *bootstrapCommand) SetFlags(f *gnuflag.FlagSet) { f.Var(constraints.ConstraintsValue{Target: &c.Constraints}, "constraints", "Set model constraints") f.Var(constraints.ConstraintsValue{Target: &c.BootstrapConstraints}, "bootstrap-constraints", "Specify bootstrap machine constraints") f.StringVar(&c.BootstrapSeries, "bootstrap-series", "", "Specify the series of the bootstrap machine") if featureflag.Enabled(feature.ImageMetadata) { f.StringVar(&c.BootstrapImage, "bootstrap-image", "", "Specify the image of the bootstrap machine") } f.BoolVar(&c.UploadTools, "upload-tools", false, "Upload local version of tools before bootstrapping") f.StringVar(&c.MetadataSource, "metadata-source", "", "Local path to use as tools and/or metadata source") f.StringVar(&c.Placement, "to", "", "Placement directive indicating an instance to bootstrap") f.BoolVar(&c.KeepBrokenEnvironment, "keep-broken", false, "Do not destroy the model if bootstrap fails") f.BoolVar(&c.AutoUpgrade, "auto-upgrade", false, "Upgrade to the latest patch release tools on first bootstrap") f.StringVar(&c.AgentVersionParam, "agent-version", "", "Version of tools to use for Juju agents") f.StringVar(&c.CredentialName, "credential", "", "Credentials to use when bootstrapping") f.Var(&c.config, "config", "Specify a controller configuration file, or one or more configuration\n options\n (--config config.yaml [--config key=value ...])") f.StringVar(&c.hostedModelName, "d", defaultHostedModelName, "Name of the default hosted model for the controller") f.StringVar(&c.hostedModelName, "default-model", defaultHostedModelName, "Name of the default hosted model for the controller") f.BoolVar(&c.noGUI, "no-gui", false, "Do not install the Juju GUI in the controller when bootstrapping") }
// NewSuperCommand creates the metadata plugin supercommand and registers the // subcommands that it supports. func NewSuperCommand() cmd.Command { metadatacmd := cmd.NewSuperCommand(cmd.SuperCommandParams{ Name: "metadata", UsagePrefix: "juju", Doc: metadataDoc, Purpose: "tools for generating and validating image and tools metadata", Log: &cmd.Log{}}) metadatacmd.Register(newValidateImageMetadataCommand()) metadatacmd.Register(newImageMetadataCommand()) metadatacmd.Register(newToolsMetadataCommand()) metadatacmd.Register(newValidateToolsMetadataCommand()) metadatacmd.Register(newSignMetadataCommand()) if featureflag.Enabled(feature.ImageMetadata) { metadatacmd.Register(newListImagesCommand()) metadatacmd.Register(newAddImageMetadataCommand()) metadatacmd.Register(newDeleteImageMetadataCommand()) } return metadatacmd }
func (c *bootstrapCommand) SetFlags(f *gnuflag.FlagSet) { c.ModelCommandBase.SetFlags(f) f.StringVar(&c.ConstraintsStr, "constraints", "", "Set model constraints") f.StringVar(&c.BootstrapConstraintsStr, "bootstrap-constraints", "", "Specify bootstrap machine constraints") f.StringVar(&c.BootstrapSeries, "bootstrap-series", "", "Specify the series of the bootstrap machine") if featureflag.Enabled(feature.ImageMetadata) { f.StringVar(&c.BootstrapImage, "bootstrap-image", "", "Specify the image of the bootstrap machine") } f.BoolVar(&c.BuildAgent, "build-agent", false, "Build local version of agent binary before bootstrapping") f.StringVar(&c.MetadataSource, "metadata-source", "", "Local path to use as tools and/or metadata source") f.StringVar(&c.Placement, "to", "", "Placement directive indicating an instance to bootstrap") f.BoolVar(&c.KeepBrokenEnvironment, "keep-broken", false, "Do not destroy the model if bootstrap fails") f.BoolVar(&c.AutoUpgrade, "auto-upgrade", false, "Upgrade to the latest patch release tools on first bootstrap") f.StringVar(&c.AgentVersionParam, "agent-version", "", "Version of tools to use for Juju agents") f.StringVar(&c.CredentialName, "credential", "", "Credentials to use when bootstrapping") f.Var(&c.config, "config", "Specify a controller configuration file, or one or more configuration\n options\n (--config config.yaml [--config key=value ...])") f.StringVar(&c.hostedModelName, "d", defaultHostedModelName, "Name of the default hosted model for the controller") f.StringVar(&c.hostedModelName, "default-model", defaultHostedModelName, "Name of the default hosted model for the controller") f.BoolVar(&c.noGUI, "no-gui", false, "Do not install the Juju GUI in the controller when bootstrapping") f.BoolVar(&c.showClouds, "clouds", false, "Print the available clouds which can be used to bootstrap a Juju environment") f.StringVar(&c.showRegionsForCloud, "regions", "", "Print the available regions for the specified cloud") }
// addRequiredPackages is defined on the AdvancedPackagingConfig interface. func (cfg *ubuntuCloudConfig) addRequiredPackages() { packages := []string{ "curl", "cpu-checker", // TODO(axw) 2014-07-02 #1277359 // Don't install bridge-utils in cloud-init; // leave it to the networker worker. "bridge-utils", "cloud-utils", "tmux", } if featureflag.Enabled(feature.DeveloperMode) { packages = append(packages, "socat") } // The required packages need to come from the correct repo. // For precise, that might require an explicit --target-release parameter. // We cannot just pass packages below, because // this will generate install commands which older // versions of cloud-init (e.g. 0.6.3 in precise) will // interpret incorrectly (see bug http://pad.lv/1424777). for _, pack := range packages { if config.SeriesRequiresCloudArchiveTools(cfg.series) && cfg.pacconfer.IsCloudArchivePackage(pack) { // On precise, we need to pass a --target-release entry in // pieces (as "packages") for it to work: // --target-release, precise-updates/cloud-tools, // package-name. All these 3 entries are needed so // cloud-init 0.6.3 can generate the correct apt-get // install command line for "package-name". args := cfg.pacconfer.ApplyCloudArchiveTarget(pack) for _, arg := range args { cfg.AddPackage(arg) } } else { cfg.AddPackage(pack) } } }
// NewSuperCommand creates the environment supercommand and registers the // subcommands that it supports. func NewSuperCommand() cmd.Command { environmentCmd := cmd.NewSuperCommand(cmd.SuperCommandParams{ Name: "environment", Doc: commandDoc, UsagePrefix: "juju", Purpose: "manage environments", }) environmentCmd.Register(newGetCommand()) environmentCmd.Register(newSetCommand()) environmentCmd.Register(newUnsetCommand()) environmentCmd.Register(&JenvCommand{}) environmentCmd.Register(newRetryProvisioningCommand()) environmentCmd.Register(newEnvSetConstraintsCommand()) environmentCmd.Register(newEnvGetConstraintsCommand()) if featureflag.Enabled(feature.JES) { environmentCmd.Register(newShareCommand()) environmentCmd.Register(newUnshareCommand()) environmentCmd.Register(newUsersCommand()) environmentCmd.Register(newDestroyCommand()) } return environmentCmd }
// NewSuperCommand returns a new backups super-command. func NewSuperCommand() cmd.Command { if featureflag.Enabled(feature.JES) { backupsDoc = jesBackupsDoc } backupsCmd := Command{ SuperCommand: *cmd.NewSuperCommand( cmd.SuperCommandParams{ Name: "backups", Doc: backupsDoc, UsagePrefix: "juju", Purpose: backupsPurpose, }, ), } backupsCmd.Register(newCreateCommand()) backupsCmd.Register(newInfoCommand()) backupsCmd.Register(newListCommand()) backupsCmd.Register(newDownloadCommand()) backupsCmd.Register(newUploadCommand()) backupsCmd.Register(newRemoveCommand()) backupsCmd.Register(newRestoreCommand()) return &backupsCmd }
// registerCommands registers commands in the specified registry. func registerCommands(r commandRegistry, ctx *cmd.Context) { // Creation commands. r.Register(newBootstrapCommand()) r.Register(newDeployCommand()) r.Register(newAddRelationCommand()) // Destruction commands. r.Register(newRemoveRelationCommand()) r.Register(newRemoveServiceCommand()) r.Register(newRemoveUnitCommand()) r.Register(newDestroyEnvironmentCommand()) // Reporting commands. r.Register(status.NewStatusCommand()) r.Register(newSwitchCommand()) r.Register(newEndpointCommand()) r.Register(newAPIInfoCommand()) r.Register(status.NewStatusHistoryCommand()) // Error resolution and debugging commands. r.Register(newRunCommand()) r.Register(newSCPCommand()) r.Register(newSSHCommand()) r.Register(newResolvedCommand()) r.Register(newDebugLogCommand()) r.Register(newDebugHooksCommand()) // Configuration commands. r.Register(newInitCommand()) r.RegisterDeprecated(common.NewGetConstraintsCommand(), twoDotOhDeprecation("environment get-constraints or service get-constraints")) r.RegisterDeprecated(common.NewSetConstraintsCommand(), twoDotOhDeprecation("environment set-constraints or service set-constraints")) r.Register(newExposeCommand()) r.Register(newSyncToolsCommand()) r.Register(newUnexposeCommand()) r.Register(newUpgradeJujuCommand()) r.Register(newUpgradeCharmCommand()) // Charm publishing commands. r.Register(newPublishCommand()) // Charm tool commands. r.Register(newHelpToolCommand()) // Manage backups. r.Register(backups.NewSuperCommand()) // Manage authorized ssh keys. r.Register(newAuthorizedKeysCommand()) // Manage users and access r.Register(user.NewSuperCommand()) // Manage cached images r.Register(cachedimages.NewSuperCommand()) // Manage machines r.Register(machine.NewSuperCommand()) r.RegisterSuperAlias("add-machine", "machine", "add", twoDotOhDeprecation("machine add")) r.RegisterSuperAlias("remove-machine", "machine", "remove", twoDotOhDeprecation("machine remove")) r.RegisterSuperAlias("destroy-machine", "machine", "remove", twoDotOhDeprecation("machine remove")) r.RegisterSuperAlias("terminate-machine", "machine", "remove", twoDotOhDeprecation("machine remove")) // Mangage environment r.Register(environment.NewSuperCommand()) r.RegisterSuperAlias("get-environment", "environment", "get", twoDotOhDeprecation("environment get")) r.RegisterSuperAlias("get-env", "environment", "get", twoDotOhDeprecation("environment get")) r.RegisterSuperAlias("set-environment", "environment", "set", twoDotOhDeprecation("environment set")) r.RegisterSuperAlias("set-env", "environment", "set", twoDotOhDeprecation("environment set")) r.RegisterSuperAlias("unset-environment", "environment", "unset", twoDotOhDeprecation("environment unset")) r.RegisterSuperAlias("unset-env", "environment", "unset", twoDotOhDeprecation("environment unset")) r.RegisterSuperAlias("retry-provisioning", "environment", "retry-provisioning", twoDotOhDeprecation("environment retry-provisioning")) // Manage and control actions r.Register(action.NewSuperCommand()) // Manage state server availability r.Register(newEnsureAvailabilityCommand()) // Manage and control services r.Register(service.NewSuperCommand()) r.RegisterSuperAlias("add-unit", "service", "add-unit", twoDotOhDeprecation("service add-unit")) r.RegisterSuperAlias("get", "service", "get", twoDotOhDeprecation("service get")) r.RegisterSuperAlias("set", "service", "set", twoDotOhDeprecation("service set")) r.RegisterSuperAlias("unset", "service", "unset", twoDotOhDeprecation("service unset")) // Operation protection commands r.Register(block.NewSuperBlockCommand()) r.Register(block.NewUnblockCommand()) // Manage storage r.Register(storage.NewSuperCommand()) // Manage spaces r.Register(space.NewSuperCommand()) // Manage subnets r.Register(subnet.NewSuperCommand()) // Manage systems if featureflag.Enabled(feature.JES) { r.Register(system.NewSuperCommand()) r.RegisterSuperAlias("systems", "system", "list", nil) // Add top level aliases of the same name as the subcommands. r.RegisterSuperAlias("environments", "system", "environments", nil) r.RegisterSuperAlias("login", "system", "login", nil) r.RegisterSuperAlias("create-environment", "system", "create-environment", nil) r.RegisterSuperAlias("create-env", "system", "create-env", nil) } }
// AddressAllocationEnabled is a shortcut for checking if the AddressAllocation // feature flag is enabled. The providerType is used to distinguish between MAAS // and other providers that still support the legacy address allocation (EC2 and // Dummy) until the support can be removed across the board. func AddressAllocationEnabled(providerType string) bool { if providerType == provider.MAAS { return false } return featureflag.Enabled(feature.AddressAllocation) }
func (a *UnitAgent) APIWorkers() (_ worker.Worker, err error) { agentConfig := a.CurrentConfig() dataDir := agentConfig.DataDir() hookLock, err := cmdutil.HookExecutionLock(dataDir) if err != nil { return nil, err } st, entity, err := OpenAPIState(agentConfig, a) if err != nil { return nil, err } unitTag, err := names.ParseUnitTag(entity.Tag()) if err != nil { return nil, errors.Trace(err) } // Ensure that the environment uuid is stored in the agent config. // Luckily the API has it recorded for us after we connect. if agentConfig.Environment().Id() == "" { err := a.ChangeConfig(func(setter agent.ConfigSetter) error { environTag, err := st.EnvironTag() if err != nil { return errors.Annotate(err, "no environment uuid set on api") } return setter.Migrate(agent.MigrateParams{ Environment: environTag, }) }) if err != nil { logger.Warningf("unable to save environment uuid: %v", err) // Not really fatal, just annoying. } } defer func() { if err != nil { st.Close() reportClosedUnitAPI(st) } }() // Before starting any workers, ensure we record the Juju version this unit // agent is running. currentTools := &tools.Tools{Version: version.Current} apiStateUpgrader := a.getUpgrader(st) if err := apiStateUpgrader.SetVersion(agentConfig.Tag().String(), currentTools.Version); err != nil { return nil, errors.Annotate(err, "cannot set unit agent version") } runner := worker.NewRunner(cmdutil.ConnectionIsFatal(logger, st), cmdutil.MoreImportant) // start proxyupdater first to ensure proxy settings are correct runner.StartWorker("proxyupdater", func() (worker.Worker, error) { return proxyupdater.New(st.Environment(), false), nil }) if feature.IsDbLogEnabled() { runner.StartWorker("logsender", func() (worker.Worker, error) { return logsender.New(a.bufferedLogs, agentConfig.APIInfo()), nil }) } runner.StartWorker("upgrader", func() (worker.Worker, error) { return upgrader.NewAgentUpgrader( st.Upgrader(), agentConfig, agentConfig.UpgradedToVersion(), func() bool { return false }, a.initialAgentUpgradeCheckComplete, ), nil }) runner.StartWorker("logger", func() (worker.Worker, error) { return workerlogger.NewLogger(st.Logger(), agentConfig), nil }) runner.StartWorker("uniter", func() (worker.Worker, error) { uniterFacade, err := st.Uniter() if err != nil { return nil, errors.Trace(err) } uniterParams := uniter.UniterParams{ uniterFacade, unitTag, leadership.NewClient(st), dataDir, hookLock, uniter.NewMetricsTimerChooser(), uniter.NewUpdateStatusTimer(), nil, } return uniter.NewUniter(&uniterParams), nil }) runner.StartWorker("apiaddressupdater", func() (worker.Worker, error) { uniterFacade, err := st.Uniter() if err != nil { return nil, errors.Trace(err) } return apiaddressupdater.NewAPIAddressUpdater(uniterFacade, a), nil }) if !featureflag.Enabled(feature.DisableRsyslog) { runner.StartWorker("rsyslog", func() (worker.Worker, error) { return cmdutil.NewRsyslogConfigWorker(st.Rsyslog(), agentConfig, rsyslog.RsyslogModeForwarding) }) } return cmdutil.NewCloseWorker(logger, runner, st), nil }
func (srv *Server) run(lis net.Listener) { defer srv.tomb.Done() defer srv.wg.Wait() // wait for any outstanding requests to complete. srv.wg.Add(1) go func() { err := srv.mongoPinger() srv.tomb.Kill(err) srv.wg.Done() }() // for pat based handlers, they are matched in-order of being // registered, first match wins. So more specific ones have to be // registered first. mux := pat.New() // For backwards compatibility we register all the old paths handleAll(mux, "/environment/:envuuid/log", &debugLogHandler{ httpHandler: httpHandler{ssState: srv.state}, logDir: srv.logDir}, ) if featureflag.Enabled(feature.DbLog) { handleAll(mux, "/environment/:envuuid/logsink", &logSinkHandler{ httpHandler: httpHandler{ssState: srv.state}, }, ) } handleAll(mux, "/environment/:envuuid/charms", &charmsHandler{ httpHandler: httpHandler{ssState: srv.state}, dataDir: srv.dataDir}, ) // TODO: We can switch from handleAll to mux.Post/Get/etc for entries // where we only want to support specific request methods. However, our // tests currently assert that errors come back as application/json and // pat only does "text/plain" responses. handleAll(mux, "/environment/:envuuid/tools", &toolsUploadHandler{toolsHandler{ httpHandler{ssState: srv.state}, }}, ) handleAll(mux, "/environment/:envuuid/tools/:version", &toolsDownloadHandler{toolsHandler{ httpHandler{ssState: srv.state}, }}, ) handleAll(mux, "/environment/:envuuid/backups", &backupHandler{httpHandler{ ssState: srv.state, strictValidation: true, stateServerEnvOnly: true, }}, ) handleAll(mux, "/environment/:envuuid/api", http.HandlerFunc(srv.apiHandler)) handleAll(mux, "/environment/:envuuid/images/:kind/:series/:arch/:filename", &imagesDownloadHandler{ httpHandler: httpHandler{ssState: srv.state}, dataDir: srv.dataDir}, ) // For backwards compatibility we register all the old paths handleAll(mux, "/log", &debugLogHandler{ httpHandler: httpHandler{ssState: srv.state}, logDir: srv.logDir}, ) handleAll(mux, "/charms", &charmsHandler{ httpHandler: httpHandler{ssState: srv.state}, dataDir: srv.dataDir}, ) handleAll(mux, "/tools", &toolsUploadHandler{toolsHandler{ httpHandler{ssState: srv.state}, }}, ) handleAll(mux, "/tools/:version", &toolsDownloadHandler{toolsHandler{ httpHandler{ssState: srv.state}, }}, ) handleAll(mux, "/", http.HandlerFunc(srv.apiHandler)) go func() { // The error from http.Serve is not interesting. http.Serve(lis, mux) }() <-srv.tomb.Dying() lis.Close() }
// registerCommands registers commands in the specified registry. // EnvironCommands must be wrapped with an envCmdWrapper. func registerCommands(r commandRegistry, ctx *cmd.Context) { wrapEnvCommand := func(c envcmd.EnvironCommand) cmd.Command { return envCmdWrapper{envcmd.Wrap(c), ctx} } // Creation commands. r.Register(wrapEnvCommand(&BootstrapCommand{})) r.Register(wrapEnvCommand(&DeployCommand{})) r.Register(wrapEnvCommand(&AddRelationCommand{})) // Destruction commands. r.Register(wrapEnvCommand(&RemoveRelationCommand{})) r.Register(wrapEnvCommand(&RemoveServiceCommand{})) r.Register(wrapEnvCommand(&RemoveUnitCommand{})) r.Register(&DestroyEnvironmentCommand{}) // Reporting commands. r.Register(wrapEnvCommand(&StatusCommand{})) r.Register(&SwitchCommand{}) r.Register(wrapEnvCommand(&EndpointCommand{})) r.Register(wrapEnvCommand(&APIInfoCommand{})) r.Register(wrapEnvCommand(&StatusHistoryCommand{})) // Error resolution and debugging commands. r.Register(wrapEnvCommand(&RunCommand{})) r.Register(wrapEnvCommand(&SCPCommand{})) r.Register(wrapEnvCommand(&SSHCommand{})) r.Register(wrapEnvCommand(&ResolvedCommand{})) r.Register(wrapEnvCommand(&DebugLogCommand{})) r.Register(wrapEnvCommand(&DebugHooksCommand{})) // Configuration commands. r.Register(&InitCommand{}) r.RegisterDeprecated(wrapEnvCommand(&common.GetConstraintsCommand{}), twoDotOhDeprecation("environment get-constraints or service get-constraints")) r.RegisterDeprecated(wrapEnvCommand(&common.SetConstraintsCommand{}), twoDotOhDeprecation("environment set-constraints or service set-constraints")) r.Register(wrapEnvCommand(&ExposeCommand{})) r.Register(wrapEnvCommand(&SyncToolsCommand{})) r.Register(wrapEnvCommand(&UnexposeCommand{})) r.Register(wrapEnvCommand(&UpgradeJujuCommand{})) r.Register(wrapEnvCommand(&UpgradeCharmCommand{})) // Charm publishing commands. r.Register(wrapEnvCommand(&PublishCommand{})) // Charm tool commands. r.Register(&HelpToolCommand{}) // Manage backups. r.Register(backups.NewCommand()) // Manage authorized ssh keys. r.Register(NewAuthorizedKeysCommand()) // Manage users and access r.Register(user.NewSuperCommand()) // Manage cached images r.Register(cachedimages.NewSuperCommand()) // Manage machines r.Register(machine.NewSuperCommand()) r.RegisterSuperAlias("add-machine", "machine", "add", twoDotOhDeprecation("machine add")) r.RegisterSuperAlias("remove-machine", "machine", "remove", twoDotOhDeprecation("machine remove")) r.RegisterSuperAlias("destroy-machine", "machine", "remove", twoDotOhDeprecation("machine remove")) r.RegisterSuperAlias("terminate-machine", "machine", "remove", twoDotOhDeprecation("machine remove")) // Mangage environment r.Register(environment.NewSuperCommand()) r.RegisterSuperAlias("get-environment", "environment", "get", twoDotOhDeprecation("environment get")) r.RegisterSuperAlias("get-env", "environment", "get", twoDotOhDeprecation("environment get")) r.RegisterSuperAlias("set-environment", "environment", "set", twoDotOhDeprecation("environment set")) r.RegisterSuperAlias("set-env", "environment", "set", twoDotOhDeprecation("environment set")) r.RegisterSuperAlias("unset-environment", "environment", "unset", twoDotOhDeprecation("environment unset")) r.RegisterSuperAlias("unset-env", "environment", "unset", twoDotOhDeprecation("environment unset")) r.RegisterSuperAlias("retry-provisioning", "environment", "retry-provisioning", twoDotOhDeprecation("environment retry-provisioning")) // Manage and control actions r.Register(action.NewSuperCommand()) // Manage state server availability r.Register(wrapEnvCommand(&EnsureAvailabilityCommand{})) // Manage and control services r.Register(service.NewSuperCommand()) r.RegisterSuperAlias("add-unit", "service", "add-unit", twoDotOhDeprecation("service add-unit")) r.RegisterSuperAlias("get", "service", "get", twoDotOhDeprecation("service get")) r.RegisterSuperAlias("set", "service", "set", twoDotOhDeprecation("service set")) r.RegisterSuperAlias("unset", "service", "unset", twoDotOhDeprecation("service unset")) // Operation protection commands r.Register(block.NewSuperBlockCommand()) r.Register(wrapEnvCommand(&block.UnblockCommand{})) // Manage storage r.Register(storage.NewSuperCommand()) // Manage systems if featureflag.Enabled(feature.JES) { r.Register(system.NewSuperCommand()) r.RegisterSuperAlias("systems", "system", "list", nil) r.RegisterSuperAlias("environments", "system", "environments", nil) } }
// AddressAllocationEnabled is a shortcut for checking if the // AddressAllocation feature flag is enabled. func AddressAllocationEnabled() bool { return featureflag.Enabled(feature.AddressAllocation) }
// registerCommands registers commands in the specified registry. func registerCommands(r commandRegistry, ctx *cmd.Context) { // Creation commands. r.Register(newBootstrapCommand()) r.Register(application.NewAddRelationCommand()) // Destruction commands. r.Register(application.NewRemoveRelationCommand()) r.Register(application.NewRemoveServiceCommand()) r.Register(application.NewRemoveUnitCommand()) // Reporting commands. r.Register(status.NewStatusCommand()) r.Register(newSwitchCommand()) r.Register(status.NewStatusHistoryCommand()) // Error resolution and debugging commands. r.Register(newRunCommand()) r.Register(newSCPCommand()) r.Register(newSSHCommand()) r.Register(newResolvedCommand()) r.Register(newDebugLogCommand()) r.Register(newDebugHooksCommand()) // Configuration commands. r.Register(model.NewModelGetConstraintsCommand()) r.Register(model.NewModelSetConstraintsCommand()) r.Register(newSyncToolsCommand()) r.Register(newUpgradeJujuCommand(nil)) r.Register(application.NewUpgradeCharmCommand()) // Charm tool commands. r.Register(newHelpToolCommand()) r.Register(charmcmd.NewSuperCommand()) // Manage backups. r.Register(backups.NewCreateCommand()) r.Register(backups.NewDownloadCommand()) r.Register(backups.NewShowCommand()) r.Register(backups.NewListCommand()) r.Register(backups.NewRemoveCommand()) r.Register(backups.NewRestoreCommand()) r.Register(backups.NewUploadCommand()) // Manage authorized ssh keys. r.Register(NewAddKeysCommand()) r.Register(NewRemoveKeysCommand()) r.Register(NewImportKeysCommand()) r.Register(NewListKeysCommand()) // Manage users and access r.Register(user.NewAddCommand()) r.Register(user.NewChangePasswordCommand()) r.Register(user.NewShowUserCommand()) r.Register(user.NewListCommand()) r.Register(user.NewEnableCommand()) r.Register(user.NewDisableCommand()) r.Register(user.NewLoginCommand()) r.Register(user.NewLogoutCommand()) r.Register(user.NewRemoveCommand()) r.Register(user.NewWhoAmICommand()) // Manage cached images r.Register(cachedimages.NewRemoveCommand()) r.Register(cachedimages.NewListCommand()) // Manage machines r.Register(machine.NewAddCommand()) r.Register(machine.NewRemoveCommand()) r.Register(machine.NewListMachinesCommand()) r.Register(machine.NewShowMachineCommand()) // Manage model r.Register(model.NewConfigCommand()) r.Register(model.NewDefaultsCommand()) r.Register(model.NewRetryProvisioningCommand()) r.Register(model.NewDestroyCommand()) r.Register(model.NewGrantCommand()) r.Register(model.NewRevokeCommand()) r.Register(model.NewShowCommand()) if featureflag.Enabled(feature.Migration) { r.Register(newMigrateCommand()) } if featureflag.Enabled(feature.DeveloperMode) { r.Register(model.NewDumpCommand()) r.Register(model.NewDumpDBCommand()) } // Manage and control actions r.Register(action.NewStatusCommand()) r.Register(action.NewRunCommand()) r.Register(action.NewShowOutputCommand()) r.Register(action.NewListCommand()) // Manage controller availability r.Register(newEnableHACommand()) // Manage and control services r.Register(application.NewAddUnitCommand()) r.Register(application.NewConfigCommand()) r.Register(application.NewDefaultDeployCommand()) r.Register(application.NewExposeCommand()) r.Register(application.NewUnexposeCommand()) r.Register(application.NewServiceGetConstraintsCommand()) r.Register(application.NewServiceSetConstraintsCommand()) // Operation protection commands r.Register(block.NewDisableCommand()) r.Register(block.NewListCommand()) r.Register(block.NewEnableCommand()) // Manage storage r.Register(storage.NewAddCommand()) r.Register(storage.NewListCommand()) r.Register(storage.NewPoolCreateCommand()) r.Register(storage.NewPoolListCommand()) r.Register(storage.NewShowCommand()) // Manage spaces r.Register(space.NewAddCommand()) r.Register(space.NewListCommand()) if featureflag.Enabled(feature.PostNetCLIMVP) { r.Register(space.NewRemoveCommand()) r.Register(space.NewUpdateCommand()) r.Register(space.NewRenameCommand()) } // Manage subnets r.Register(subnet.NewAddCommand()) r.Register(subnet.NewListCommand()) if featureflag.Enabled(feature.PostNetCLIMVP) { r.Register(subnet.NewCreateCommand()) r.Register(subnet.NewRemoveCommand()) } // Manage controllers r.Register(controller.NewAddModelCommand()) r.Register(controller.NewDestroyCommand()) r.Register(controller.NewListModelsCommand()) r.Register(controller.NewKillCommand()) r.Register(controller.NewListControllersCommand()) r.Register(controller.NewRegisterCommand()) r.Register(controller.NewUnregisterCommand(jujuclient.NewFileClientStore())) r.Register(controller.NewEnableDestroyControllerCommand()) r.Register(controller.NewShowControllerCommand()) r.Register(controller.NewGetConfigCommand()) // Debug Metrics r.Register(metricsdebug.New()) r.Register(metricsdebug.NewCollectMetricsCommand()) r.Register(setmeterstatus.New()) // Manage clouds and credentials r.Register(cloud.NewUpdateCloudsCommand()) r.Register(cloud.NewListCloudsCommand()) r.Register(cloud.NewListRegionsCommand()) r.Register(cloud.NewShowCloudCommand()) r.Register(cloud.NewAddCloudCommand()) r.Register(cloud.NewRemoveCloudCommand()) r.Register(cloud.NewListCredentialsCommand()) r.Register(cloud.NewDetectCredentialsCommand()) r.Register(cloud.NewSetDefaultRegionCommand()) r.Register(cloud.NewSetDefaultCredentialCommand()) r.Register(cloud.NewAddCredentialCommand()) r.Register(cloud.NewRemoveCredentialCommand()) r.Register(cloud.NewUpdateCredentialCommand()) // Juju GUI commands. r.Register(gui.NewGUICommand()) r.Register(gui.NewUpgradeGUICommand()) // Commands registered elsewhere. for _, newCommand := range registeredCommands { command := newCommand() r.Register(command) } for _, newCommand := range registeredEnvCommands { command := newCommand() r.Register(modelcmd.Wrap(command)) } rcmd.RegisterAll(r) }
func init() { if featureflag.Enabled(feature.LegacyUpstart) { maybeSystemd = service.InitSystemUpstart } }
// Manifold will depend. type ManifoldConfig util.AgentApiManifoldConfig // Manifold returns a dependency manifold that runs an rsyslog // worker, using the resource names defined in the supplied config. func Manifold(config ManifoldConfig) dependency.Manifold { return util.AgentApiManifold(util.AgentApiManifoldConfig(config), newWorker) } // newWorker exists to wrap NewRsyslogConfigWorker in a format convenient for an // AgentApiManifold. // TODO(fwereade) 2015-05-11 Eventually, the method should be the sole accessible // package factory function -- as part of the manifold -- and all tests should // thus be routed through it. var newWorker = func(a agent.Agent, apiCaller base.APICaller) (worker.Worker, error) { if featureflag.Enabled(feature.DisableRsyslog) { logger.Warningf("rsyslog manifold disabled by feature flag") return nil, dependency.ErrMissing } agentConfig := a.CurrentConfig() tag := agentConfig.Tag() namespace := agentConfig.Value(agent.Namespace) addrs, err := agentConfig.APIAddresses() if err != nil { return nil, err } return NewRsyslogConfigWorker( rsyslog.NewState(apiCaller), RsyslogModeForwarding, tag,
// IsDbLogEnabled returns true if logging to MongoDB should be enabled // based on the dbLog or JES feature flags. func IsDbLogEnabled() bool { return featureflag.Enabled(dbLog) || featureflag.Enabled(JES) }