// registerPublicCommands adds the resources-related commands // to the "juju" supercommand. func (r resources) registerPublicCommands() { if !markRegistered(resource.ComponentName, "public-commands") { return } charmcmd.RegisterSubCommand(func(spec charmcmd.CharmstoreSpec) jujucmd.Command { base := charmcmd.NewCommandBase(spec) resBase := &resourceadapters.CharmCmdBase{base} return cmd.NewListCharmResourcesCommand(resBase) }) commands.RegisterEnvCommand(func() modelcmd.ModelCommand { return cmd.NewUploadCommand(cmd.UploadDeps{ NewClient: func(c *cmd.UploadCommand) (cmd.UploadClient, error) { return resourceadapters.NewAPIClient(c.NewAPIRoot) }, OpenResource: func(s string) (cmd.ReadSeekCloser, error) { return os.Open(s) }, }) }) commands.RegisterEnvCommand(func() modelcmd.ModelCommand { return cmd.NewShowServiceCommand(cmd.ShowServiceDeps{ NewClient: func(c *cmd.ShowServiceCommand) (cmd.ShowServiceClient, error) { return resourceadapters.NewAPIClient(c.NewAPIRoot) }, }) }) }
// registerPublicCommands adds the resources-related commands // to the "juju" supercommand. func (r resources) registerPublicCommands() { if !markRegistered(resource.ComponentName, "public-commands") { return } charmcmd.RegisterSubCommand(cmd.NewListCharmResourcesCommand()) commands.RegisterEnvCommand(func() modelcmd.ModelCommand { return cmd.NewUploadCommand(cmd.UploadDeps{ NewClient: func(c *cmd.UploadCommand) (cmd.UploadClient, error) { apiRoot, err := c.NewAPIRoot() if err != nil { return nil, errors.Trace(err) } return resourceadapters.NewAPIClient(apiRoot) }, OpenResource: func(s string) (cmd.ReadSeekCloser, error) { return os.Open(s) }, }) }) commands.RegisterEnvCommand(func() modelcmd.ModelCommand { return cmd.NewShowServiceCommand(cmd.ShowServiceDeps{ NewClient: func(c *cmd.ShowServiceCommand) (cmd.ShowServiceClient, error) { apiRoot, err := c.NewAPIRoot() if err != nil { return nil, errors.Trace(err) } return resourceadapters.NewAPIClient(apiRoot) }, }) }) }
func getResources(serviceID string, newAPIRoot func() (api.Connection, error)) (map[string]resource.Resource, error) { resclient, err := resourceadapters.NewAPIClient(newAPIRoot) if err != nil { return nil, errors.Trace(err) } svcs, err := resclient.ListResources([]string{serviceID}) if err != nil { return nil, errors.Trace(err) } // ListResources guarantees a number of values returned == number of // services passed in. return resource.AsMap(svcs[0].Resources), nil }
// NewUpgradeCharmCommand returns a command which upgrades application's charm. func NewUpgradeCharmCommand() cmd.Command { cmd := &upgradeCharmCommand{ DeployResources: resourceadapters.DeployResources, ResolveCharm: resolveCharm, NewCharmAdder: newCharmAdder, NewCharmClient: func(conn api.Connection) CharmClient { return charms.NewClient(conn) }, NewCharmUpgradeClient: func(conn api.Connection) CharmUpgradeClient { return application.NewClient(conn) }, NewModelConfigGetter: func(conn api.Connection) ModelConfigGetter { return modelconfig.NewClient(conn) }, NewResourceLister: func(conn api.Connection) (ResourceLister, error) { resclient, err := resourceadapters.NewAPIClient(conn) if err != nil { return nil, err } return resclient, nil }, } return modelcmd.Wrap(cmd) }
// upgradeCharm upgrades the charm for the given application to the given charm id. // If the application is already deployed using the given charm id, do nothing. // This function returns an error if the existing charm and the target one are // incompatible, meaning an upgrade from one to the other is not allowed. func (h *bundleHandler) upgradeCharm( api DeployAPI, applicationName string, chID charmstore.CharmID, csMac *macaroon.Macaroon, resources map[string]string, ) error { id := chID.URL.String() existing, err := h.api.GetCharmURL(applicationName) if err != nil { return errors.Annotatef(err, "cannot retrieve info for application %q", applicationName) } if existing.String() == id { h.log.Infof("reusing application %s (charm: %s)", applicationName, id) return nil } url, err := charm.ParseURL(id) if err != nil { return errors.Annotatef(err, "cannot parse charm URL %q", id) } chID.URL = url if url.WithRevision(-1).Path() != existing.WithRevision(-1).Path() { return errors.Errorf("bundle charm %q is incompatible with existing charm %q", id, existing) } charmsClient := charms.NewClient(api) resourceLister, err := resourceadapters.NewAPIClient(api) if err != nil { return errors.Trace(err) } filtered, err := getUpgradeResources(charmsClient, resourceLister, applicationName, url, resources) if err != nil { return errors.Trace(err) } var resNames2IDs map[string]string if len(filtered) != 0 { resNames2IDs, err = resourceadapters.DeployResources( applicationName, chID, csMac, resources, filtered, api, ) if err != nil { return errors.Trace(err) } } cfg := application.SetCharmConfig{ ApplicationName: applicationName, CharmID: chID, ResourceIDs: resNames2IDs, } if err := h.api.SetCharm(cfg); err != nil { return errors.Annotatef(err, "cannot upgrade charm to %q", id) } h.log.Infof("upgraded charm for existing application %s (from %s to %s)", applicationName, existing, id) for resName := range resNames2IDs { h.log.Infof("added resource %s", resName) } return nil }