Skip to content

Commit

Permalink
Sync Single Target Plugins Only
Browse files Browse the repository at this point in the history
This pull request updates existing functionality as follows:

1. For 'tanzu plugin sync', a new optional '--target' parameter has been added. If a user provides a value for '--target', the sync operation is performed only for the specified target, not for all active contexts.

2. 'tanzu context create' now performs 'plugin sync' only for the newly created context, not for all active contexts.

3. 'tanzu context use' now triggers 'plugin sync' only for the context being set as active, not for all currently active contexts.
  • Loading branch information
Chandra Pamuluri committed Oct 5, 2023
1 parent 64cee83 commit f1e1f3c
Show file tree
Hide file tree
Showing 6 changed files with 331 additions and 15 deletions.
8 changes: 4 additions & 4 deletions pkg/command/context.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,13 +200,13 @@ func createCtx(_ *cobra.Command, args []string) (err error) {
}

// Sync all required plugins
_ = syncContextPlugins()
_ = syncContextPlugins(ctx.Target)

return nil
}

func syncContextPlugins() error {
err := pluginmanager.SyncPlugins()
func syncContextPlugins(target configtypes.Target) error {
err := pluginmanager.SyncPluginsForTarget(target)
if err != nil {
log.Warningf("unable to automatically sync the plugins from target context. Please run 'tanzu plugin sync' command to sync plugins manually, error: '%v'", err.Error())
}
Expand Down Expand Up @@ -898,7 +898,7 @@ func useCtx(_ *cobra.Command, args []string) error {
}

// Sync all required plugins
_ = syncContextPlugins()
_ = syncContextPlugins(ctx.Target)

return nil
}
Expand Down
12 changes: 11 additions & 1 deletion pkg/command/plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ func newPluginCmd() *cobra.Command {
upgradePluginCmd.Flags().StringVarP(&targetStr, "target", "t", "", targetFlagDesc)
deletePluginCmd.Flags().StringVarP(&targetStr, "target", "t", "", targetFlagDesc)
describePluginCmd.Flags().StringVarP(&targetStr, "target", "t", "", targetFlagDesc)
targetFlagDescForSync := fmt.Sprintf("sync plugins only for specific target (%s)", common.TargetList)
syncPluginCmd.Flags().StringVarP(&targetStr, "target", "t", "", targetFlagDescForSync)

installPluginCmd.MarkFlagsMutuallyExclusive("group", "local")
installPluginCmd.MarkFlagsMutuallyExclusive("group", "local-source")
Expand Down Expand Up @@ -382,7 +384,15 @@ func newSyncPluginCmd() *cobra.Command {
Long: `Installs all plugins recommended by the active contexts.
Plugins installed with this command will only be available while the context remains active.`,
RunE: func(cmd *cobra.Command, args []string) (err error) {
err = pluginmanager.SyncPlugins()
if targetStr != "" {
if !configtypes.IsValidTarget(targetStr, false, true) {
return errors.New(invalidTargetMsg)
}
err = pluginmanager.SyncPluginsForTarget(getTarget())
} else {
err = pluginmanager.SyncPlugins()
}

if err != nil {
return err
}
Expand Down
66 changes: 58 additions & 8 deletions pkg/pluginmanager/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,20 +160,27 @@ func GetAdditionalTestPluginDiscoveries() []configtypes.PluginDiscovery {
return testDiscoveries
}

// DiscoverServerPlugins returns the available plugins associated all the active contexts
// DiscoverServerPlugins returns the available discovered plugins associated with all active contexts
func DiscoverServerPlugins() ([]discovery.Discovered, error) {
var plugins []discovery.Discovered
var errList []error

currentContextMap, err := configlib.GetAllCurrentContextsMap()
if err != nil {
return nil, err
}
if len(currentContextMap) == 0 {
return plugins, nil
contexts := make([]*configtypes.Context, 0)
for _, context := range currentContextMap {
contexts = append(contexts, context)
}
return DiscoverServerPluginsForGivenContexts(contexts)
}

for _, context := range currentContextMap {
// DiscoverServerPluginsForGivenContexts returns the available discovered plugins associated with specific contexts
func DiscoverServerPluginsForGivenContexts(contexts []*configtypes.Context) ([]discovery.Discovered, error) {
var plugins []discovery.Discovered
var errList []error
if len(contexts) == 0 {
return plugins, nil
}
for _, context := range contexts {
var discoverySources []configtypes.PluginDiscovery
discoverySources = append(discoverySources, context.DiscoverySources...)
discoverySources = append(discoverySources, defaultDiscoverySourceBasedOnContext(context)...)
Expand Down Expand Up @@ -989,7 +996,50 @@ func SyncPlugins() error {
if err != nil {
errList = append(errList, err)
}
if installedPlugins, err := pluginsupplier.GetInstalledServerPlugins(); err == nil {
err = installDiscoveredContextPlugins(plugins)
if err != nil {
errList = append(errList, err)
}
err = kerrors.NewAggregate(errList)
if err != nil {
return err
}
return nil
}

// SyncPluginsForTarget installs the plugins for given target
func SyncPluginsForTarget(target configtypes.Target) error {
currentContextMap, err := configlib.GetAllCurrentContextsMap()
if err != nil {
return err
}
ctx, ok := currentContextMap[target]
if !ok {
return fmt.Errorf("there is no active context for the target %v ", target)
}
log.Infof("Checking for required plugins for context %s...", ctx.Name)
errList := make([]error, 0)
plugins, err := DiscoverServerPluginsForGivenContexts([]*configtypes.Context{ctx})
if err != nil {
errList = append(errList, err)
}
err = installDiscoveredContextPlugins(plugins)
if err != nil {
errList = append(errList, err)
}
err = kerrors.NewAggregate(errList)
if err != nil {
return err
}
return nil
}

// installDiscoveredContextPlugins installs the given context scope plugins
func installDiscoveredContextPlugins(plugins []discovery.Discovered) error {
var errList []error
var err error
var installedPlugins []cli.PluginInfo
if installedPlugins, err = pluginsupplier.GetInstalledServerPlugins(); err == nil {
setAvailablePluginsStatus(plugins, installedPlugins)
}

Expand Down
81 changes: 81 additions & 0 deletions pkg/pluginmanager/manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,87 @@ func Test_SyncPlugins(t *testing.T) {
}
}

// Test_SyncPlugins_ForK8SSpecificTarget tests to sync plugins for k8s specific target only
func Test_SyncPlugins_ForK8SSpecificTarget(t *testing.T) {
assertions := assert.New(t)

defer setupPluginSourceForTesting()()
execCommand = fakeInfoExecCommand
defer func() { execCommand = exec.Command }()

// Get the server plugins (they are not installed yet)
serverPlugins, err := DiscoverServerPlugins()
assertions.NotNil(err)
// There is an error for the kubernetes discovery since we don't have a cluster
// but other server plugins will be found, so we use those
assertions.Contains(err.Error(), `Failed to load Kubeconfig file from "config"`)
assertions.Equal(len(expectedDiscoveredContextPlugins), len(serverPlugins))
var k8sTargetPlugins []*discovery.Discovered
for _, edp := range expectedDiscoveredContextPlugins {
p := findDiscoveredPlugin(serverPlugins, edp.Name, edp.Target)
assertions.NotNil(p)
assertions.Equal(common.PluginStatusNotInstalled, p.Status)
if p.Target == configtypes.TargetK8s {
k8sTargetPlugins = append(k8sTargetPlugins, p)
}
}

// Sync all available plugins
err = SyncPluginsForTarget(configtypes.TargetK8s)
assertions.NotNil(err)
// There is an error for the kubernetes discovery since we don't have a cluster
// but other server plugins will be found, so we use those
assertions.Contains(err.Error(), `Failed to load Kubeconfig file from "config"`)

installedServerPlugins, err := pluginsupplier.GetInstalledServerPlugins()
assertions.Nil(err)
assertions.Equal(len(installedServerPlugins), len(k8sTargetPlugins))

for _, isp := range installedServerPlugins {
p := findDiscoveredPlugin(serverPlugins, isp.Name, isp.Target)
assertions.NotNil(p)
}
}

// Test_SyncPlugins_ForTMCSpecificTarget tests to sync plugins for tmc specific target only
func Test_SyncPlugins_ForTMCSpecificTarget(t *testing.T) {
assertions := assert.New(t)

defer setupPluginSourceForTesting()()
execCommand = fakeInfoExecCommand
defer func() { execCommand = exec.Command }()

// Get the server plugins (they are not installed yet)
serverPlugins, err := DiscoverServerPlugins()
assertions.NotNil(err)
// There is an error for the kubernetes discovery since we don't have a cluster
// but other server plugins will be found, so we use those
assertions.Contains(err.Error(), `Failed to load Kubeconfig file from "config"`)
assertions.Equal(len(expectedDiscoveredContextPlugins), len(serverPlugins))
var tmcTargetPlugins []*discovery.Discovered
for _, edp := range expectedDiscoveredContextPlugins {
p := findDiscoveredPlugin(serverPlugins, edp.Name, edp.Target)
assertions.NotNil(p)
assertions.Equal(common.PluginStatusNotInstalled, p.Status)
if p.Target == configtypes.TargetTMC {
tmcTargetPlugins = append(tmcTargetPlugins, p)
}
}

// Sync all available plugins
err = SyncPluginsForTarget(configtypes.TargetTMC)
assertions.Nil(err)

installedServerPlugins, err := pluginsupplier.GetInstalledServerPlugins()
assertions.Nil(err)
assertions.Equal(len(installedServerPlugins), len(tmcTargetPlugins))

for _, isp := range installedServerPlugins {
p := findDiscoveredPlugin(serverPlugins, isp.Name, isp.Target)
assertions.NotNil(p)
}
}

func Test_setAvailablePluginsStatus(t *testing.T) {
assertions := assert.New(t)

Expand Down
1 change: 0 additions & 1 deletion test/e2e/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,6 @@ TANZU_CLI_E2E_AIRGAPPED_REPO_WITH_AUTH_PASSWORD = testpassword
endif



# Set the plugin group name for the plugins used to execute E2E test cases.
E2E_TEST_USE_PLGINS_FROM_PLUGIN_GROUP_FOR_TMC ?= vmware-tmc/tmc-user:v9.9.9
E2E_TEST_USE_PLGINS_FROM_PLUGIN_GROUP_FOR_K8S ?= vmware-tkg/default:v9.9.9
Expand Down
Loading

0 comments on commit f1e1f3c

Please sign in to comment.