tanzu-cli icon indicating copy to clipboard operation
tanzu-cli copied to clipboard

Avoid uselessly trying to migrate plugins

Open marckhouzam opened this issue 1 year ago • 2 comments

What this PR does / why we need it

The only time we need to migrate context-scope plugins is after moving from a CLI < 1.3 to a newer one. This PR makes use of the existing global initializer to do this migration once, for all contexts.

This avoids an unnecessary slow down for every CLI commands, especially shell completion which should be as fast as possible. We can see an improvement of 30% to 40% in speed for basic shell completion commands.

Note:

  1. before this PR, context-scoped plugins would be migrated only for the active context; this means that when another context becomes active, it may also need to have its plugins migrated
  2. also before this PR, context-scope plugins that have been migrated will then always be shown as standalone plugins, even if their context is made inactive
  3. with this PR, since we only run the plugin migration once, we must migrate the context-scoped plugins for all contexts immediately. This is a slight change in behaviour because context-scoped plugins for an inactive (and possibly old context) will now appear as standalone plugins right away for the new CLI. Since this new behaviour is similar to point 2 above, I feel it is acceptable

Which issue(s) this PR fixes

Fixes N/A

Describe testing done for PR

Test with a CLI 1.2 and a CLI using this PR. We install context-scope plugins and make sure they are migrated as expected.

$ tanzu1.2 version
version: v1.2.0
buildDate: 2024-02-07
sha: f3abe62e
arch: arm64

$ tz version
version: v1.6.0-dev
buildDate: 2024-11-28
sha: 05e593e30
arch: arm64

# Install the context-scope plugins
$ tanzu1.2 context use tkg1
[i] Successfully activated context 'tkg1' of type 'kubernetes'.
[i] Checking for required plugins for context 'tkg1'...
[i] The following plugins will be installed for context 'tkg1' of contextType 'kubernetes':
  NAME                TARGET      VERSION
  cluster             kubernetes  v0.31.1
  feature             kubernetes  v0.31.1
  kubernetes-release  kubernetes  v0.31.1
[i] Installed plugin 'cluster:v0.31.1' with target 'kubernetes' (from cache)
[i] Installed plugin 'feature:v0.31.1' with target 'kubernetes' (from cache)
[i] Installed plugin 'kubernetes-release:v0.31.1' with target 'kubernetes' (from cache)
[i] Successfully installed all required plugins

# Confirm they are in the Catalog under the old serverPlugins section
$ grep -A4 serverPlugin ~/.cache/tanzu/catalog.yaml
serverPlugins:
    tkg1:
        cluster_kubernetes: /Users/kmarc/Library/Application Support/tanzu-cli/cluster/v0.31.1_9d63b407fc78ad86f00342ae920589b3e0eba4282a01b547e0cee9188f338a77_kubernetes
        feature_kubernetes: /Users/kmarc/Library/Application Support/tanzu-cli/feature/v0.31.1_8c38d6db1c0cd2cd0b894cd46bbd4ffdb89e3b21df496f7df943aa57188780c7_kubernetes
        kubernetes-release_kubernetes: /Users/kmarc/Library/Application Support/tanzu-cli/kubernetes-release/v0.31.1_b4c395c7b469c048968c57314ae901e84cbd6606222da227a50a84a8e2a8aa69_kubernetes

# Run a command of the newer CLI to see the global initializer run
# Notice also that the cluster, feature, kubernetes-release plugins are shown in the list
# with the recommended column as expected; this shows they have been migrated
$ tz plugin list
Some initialization of the CLI is required.
Let's set things up for you.  This will just take a few seconds.

Refreshing the 27 installed plugins...

Initialization done!
==
  NAME                  DESCRIPTION                                                                       TARGET      INSTALLED           RECOMMENDED  STATUS
  apply                 Apply a resource file                                                             operations  v0.6.5                           installed
  apps                  Applications on Kubernetes                                                        kubernetes  v0.13.2                          installed
  appsv2                Applications on Tanzu Platform                                                    global      v0.21.2-dirty                    installed
  build                 Generate app image from source code                                               global      v0.16.0                          installed
  builder               Build Tanzu components                                                            global      v1.5.0                           installed
  cluster               Kubernetes cluster operations                                                     kubernetes  v0.31.1             v0.31.1      installed
  cluster               Plugin for operating clusters in the organization                                 operations  v0.11.6                          installed
  clustergroup          A group of Kubernetes clusters                                                    operations  v0.7.5                           installed
  domain                tanzu-cli domain plugin                                                           global      v0.1.0                           installed
  domain-binding        tanzu-cli domain binding plugin                                                   global      v0.1.4                           installed
  egress                Provides crud operations for egresspoints                                         global      v0.0.5                           installed
  ekscluster            ekscluster plugin is used to provision and manage the tmc eks clusters.           operations  v0.6.5                           installed
  feature               Operate on features and featuregates                                              kubernetes  v0.31.1             v0.31.1      installed
  kubectl-plugin        Provides the kubectl functionality                                                global      v0.0.0                           installed
  kubernetes-release    Kubernetes release operations                                                     kubernetes  v0.31.1             v0.31.1      installed
  kubetool              Invokes any binary after setting KUBECONFIG to match the tanzu CLI                global      v0.0.0                           installed
  management-cluster    A registered Management cluster                                                   operations  v0.6.5                           installed
  package               tanzu package management                                                          kubernetes  v0.35.8                          installed
  policy                Policy management for resources                                                   operations  v0.6.5                           installed
  project               Create, view, list, use and delete Tanzu projects.                                global      v0.0.0-dev-7741e5e               installed
  provider-eks-cluster  provider-eks-cluster plugin is used to manage and unmanage tmc provider eks       operations  v0.6.5                           installed
                        clusters
  rbac                  Tanzu Platform Role-Based Access Control                                          global      v0.0.0-dev-cde9be5               installed
  resource              manage resources in a Kubernetes cluster                                          global      v0.5.1                           installed
  secret                Tanzu secret management                                                           kubernetes  v0.33.5                          installed
  services              Commands for working with services, classes and claims                            kubernetes  v0.14.0                          installed
  space                 Tanzu space lifecycle management                                                  global      v0.4.0                           installed
  telemetry             configure cluster-wide settings for vmware tanzu telemetry                        global      v1.1.0                           installed

# Confirm the old serverPlugin section is gone
$ grep -A4 serverPlugin ~/.cache/tanzu/catalog.yaml
$

# Recreate the old serverPlugins section by reinstalling the context-scope
# plugins with the old CLI
$ tanzu1.2 context use tkg1
[i] Successfully activated context 'tkg1' of type 'kubernetes'.
[i] Checking for required plugins for context 'tkg1'...
[i] The following plugins will be installed for context 'tkg1' of contextType 'kubernetes':
  NAME                TARGET      VERSION
  cluster             kubernetes  v0.31.1
  feature             kubernetes  v0.31.1
  kubernetes-release  kubernetes  v0.31.1
[i] Installed plugin 'cluster:v0.31.1' with target 'kubernetes' (from cache)
[i] Installed plugin 'feature:v0.31.1' with target 'kubernetes' (from cache)
[i] Installed plugin 'kubernetes-release:v0.31.1' with target 'kubernetes' (from cache)
[i] Successfully installed all required plugins
$
$ grep -A4 serverPlugin ~/.cache/tanzu/catalog.yaml
serverPlugins:
    tkg1:
        cluster_kubernetes: /Users/kmarc/Library/Application Support/tanzu-cli/cluster/v0.31.1_9d63b407fc78ad86f00342ae920589b3e0eba4282a01b547e0cee9188f338a77_kubernetes
        feature_kubernetes: /Users/kmarc/Library/Application Support/tanzu-cli/feature/v0.31.1_8c38d6db1c0cd2cd0b894cd46bbd4ffdb89e3b21df496f7df943aa57188780c7_kubernetes
        kubernetes-release_kubernetes: /Users/kmarc/Library/Application Support/tanzu-cli/kubernetes-release/v0.31.1_b4c395c7b469c048968c57314ae901e84cbd6606222da227a50a84a8e2a8aa69_kubernetes

# Now uninstall the 3 context-scope plugins to get an empty serverPlugins section
$ tanzu1.2 plugin uninstall cluster -t k8s
Uninstalling plugin 'cluster' for target 'kubernetes'. Are you sure? [y/N]: y
[i] Uninstalling plugin 'cluster' for target 'kubernetes'
[i] Uninstalling plugin 'cluster' for target 'kubernetes'
[ok] successfully uninstalled plugin 'cluster'
$ tanzu1.2 plugin uninstall kubernetes-release -y -t k8s
[i] Uninstalling plugin 'kubernetes-release' for target 'kubernetes'
[i] Uninstalling plugin 'kubernetes-release' for target 'kubernetes'
[ok] successfully uninstalled plugin 'kubernetes-release'
$ tanzu1.2 plugin uninstall feature -y -t k8s
[i] Uninstalling plugin 'feature' for target 'kubernetes'
[i] Uninstalling plugin 'feature' for target 'kubernetes'
[ok] successfully uninstalled plugin 'feature'
$
$ grep -A4 serverPlugin ~/.cache/tanzu/catalog.yaml
serverPlugins:
    tkg1: {}

# Use the new CLI and notice the cluster, feature, kubernetes-release plugins
# are listed as uninstalled as expected
$ tz plugin list
Some initialization of the CLI is required.
Let's set things up for you.  This will just take a few seconds.

Refreshing the 24 installed plugins...

Initialization done!
==
  NAME                  DESCRIPTION                                                                       TARGET      INSTALLED           RECOMMENDED  STATUS
  apply                 Apply a resource file                                                             operations  v0.6.5                           installed
  apps                  Applications on Kubernetes                                                        kubernetes  v0.13.2                          installed
  appsv2                Applications on Tanzu Platform                                                    global      v0.21.2-dirty                    installed
  build                 Generate app image from source code                                               global      v0.16.0                          installed
  builder               Build Tanzu components                                                            global      v1.5.0                           installed
  cluster               Kubernetes cluster operations                                                     kubernetes                      v0.31.1      not installed
  cluster               Plugin for operating clusters in the organization                                 operations  v0.11.6                          installed
  clustergroup          A group of Kubernetes clusters                                                    operations  v0.7.5                           installed
  domain                tanzu-cli domain plugin                                                           global      v0.1.0                           installed
  domain-binding        tanzu-cli domain binding plugin                                                   global      v0.1.4                           installed
  egress                Provides crud operations for egresspoints                                         global      v0.0.5                           installed
  ekscluster            ekscluster plugin is used to provision and manage the tmc eks clusters.           operations  v0.6.5                           installed
  feature               Operate on features and featuregates                                              kubernetes                      v0.31.1      not installed
  kubectl-plugin        Provides the kubectl functionality                                                global      v0.0.0                           installed
  kubernetes-release    Kubernetes release operations                                                     kubernetes                      v0.31.1      not installed
  kubetool              Invokes any binary after setting KUBECONFIG to match the tanzu CLI                global      v0.0.0                           installed
  management-cluster    A registered Management cluster                                                   operations  v0.6.5                           installed
  package               tanzu package management                                                          kubernetes  v0.35.8                          installed
  policy                Policy management for resources                                                   operations  v0.6.5                           installed
  project               Create, view, list, use and delete Tanzu projects.                                global      v0.0.0-dev-7741e5e               installed
  provider-eks-cluster  provider-eks-cluster plugin is used to manage and unmanage tmc provider eks       operations  v0.6.5                           installed
                        clusters
  rbac                  Tanzu Platform Role-Based Access Control                                          global      v0.0.0-dev-cde9be5               installed
  resource              manage resources in a Kubernetes cluster                                          global      v0.5.1                           installed
  secret                Tanzu secret management                                                           kubernetes  v0.33.5                          installed
  services              Commands for working with services, classes and claims                            kubernetes  v0.14.0                          installed
  space                 Tanzu space lifecycle management                                                  global      v0.4.0                           installed
  telemetry             configure cluster-wide settings for vmware tanzu telemetry                        global      v1.1.0                           installed

Note: As shown above, some recommended plugins have not been installed or are outdated. To install them please run 'tanzu plugin sync'.

# Confirm the serverPlugin section is properly removed
$ grep -A4 serverPlugin ~/.cache/tanzu/catalog.yaml
$

# Install the context-scope plugins again but using plugin sync with the old CLI
$ tanzu plugin sync
[i] Plugin sync will be performed for context: 'tkg1'
[i] Checking for required plugins for context 'tkg1'...
[i] The following plugins will be installed for context 'tkg1' of contextType 'kubernetes':
  NAME                TARGET      VERSION
  cluster             kubernetes  v0.31.1
  feature             kubernetes  v0.31.1
  kubernetes-release  kubernetes  v0.31.1
[i] Installed plugin 'cluster:v0.31.1' with target 'kubernetes' (from cache)
[i] Installed plugin 'feature:v0.31.1' with target 'kubernetes' (from cache)
[i] Installed plugin 'kubernetes-release:v0.31.1' with target 'kubernetes' (from cache)
[i] Successfully installed all required plugins
[ok] Done

# Now change context so that the tkg context which specifies the
# context-scope plugins is no longer active
$ tanzu context use Tanzu_Platform_for_K8s_SaaS_-_Internal_1
[i] Successfully activated context 'Tanzu_Platform_for_K8s_SaaS_-_Internal_1' of type 'tanzu' (Project: bagreda).
[i] Checking for required plugins for context 'Tanzu_Platform_for_K8s_SaaS_-_Internal_1'...
[i] All required plugins are already installed and up-to-date

# Run the new CLI and notice that the cluster, feature, kubernetes-release plugins
# are properly migrated even though their context was not active.
# This is important because the migration will not be run again.
$ tz plugin list
Some initialization of the CLI is required.
Let's set things up for you.  This will just take a few seconds.

Refreshing the 27 installed plugins...

Initialization done!
==
  NAME                  DESCRIPTION                                                                       TARGET      INSTALLED           STATUS
  apply                 Apply a resource file                                                             operations  v0.6.5              installed
  apps                  Applications on Kubernetes                                                        kubernetes  v0.13.2             installed
  appsv2                Applications on Tanzu Platform                                                    global      v0.21.2-dirty       installed
  build                 Generate app image from source code                                               global      v0.16.0             installed
  builder               Build Tanzu components                                                            global      v1.5.0              installed
  cluster               Kubernetes cluster operations                                                     kubernetes  v0.31.1             installed
  cluster               Plugin for operating clusters in the organization                                 operations  v0.11.6             installed
  clustergroup          A group of Kubernetes clusters                                                    operations  v0.7.5              installed
  domain                tanzu-cli domain plugin                                                           global      v0.1.0              installed
  domain-binding        tanzu-cli domain binding plugin                                                   global      v0.1.4              installed
  egress                Provides crud operations for egresspoints                                         global      v0.0.5              installed
  ekscluster            ekscluster plugin is used to provision and manage the tmc eks clusters.           operations  v0.6.5              installed
  feature               Operate on features and featuregates                                              kubernetes  v0.31.1             installed
  kubectl-plugin        Provides the kubectl functionality                                                global      v0.0.0              installed
  kubernetes-release    Kubernetes release operations                                                     kubernetes  v0.31.1             installed
  kubetool              Invokes any binary after setting KUBECONFIG to match the tanzu CLI                global      v0.0.0              installed
  management-cluster    A registered Management cluster                                                   operations  v0.6.5              installed
  package               tanzu package management                                                          kubernetes  v0.35.8             installed
  policy                Policy management for resources                                                   operations  v0.6.5              installed
  project               Create, view, list, use and delete Tanzu projects.                                global      v0.0.0-dev-7741e5e  installed
  provider-eks-cluster  provider-eks-cluster plugin is used to manage and unmanage tmc provider eks       operations  v0.6.5              installed
                        clusters
  rbac                  Tanzu Platform Role-Based Access Control                                          global      v0.0.0-dev-cde9be5  installed
  resource              manage resources in a Kubernetes cluster                                          global      v0.5.1              installed
  secret                Tanzu secret management                                                           kubernetes  v0.33.5             installed
  services              Commands for working with services, classes and claims                            kubernetes  v0.14.0             installed
  space                 Tanzu space lifecycle management                                                  global      v0.4.0              installed
  telemetry             configure cluster-wide settings for vmware tanzu telemetry                        global      v1.1.0              installed
$ grep -A4 serverPlugin ~/.cache/tanzu/catalog.yaml

Now, confirm that CLI is faster. Before the PR we see a speed normally just above 0.20 seconds.

$ time tz version>/dev/null
/Users/kmarc/bin/tanzu version > /dev/null  0.24s user 0.03s system 137% cpu 0.199 total
$ time tz version>/dev/null
/Users/kmarc/bin/tanzu version > /dev/null  0.26s user 0.03s system 136% cpu 0.214 total
$ time tz version>/dev/null
/Users/kmarc/bin/tanzu version > /dev/null  0.25s user 0.03s system 141% cpu 0.195 total
$ time tz version>/dev/null
/Users/kmarc/bin/tanzu version > /dev/null  0.26s user 0.03s system 130% cpu 0.227 total
$ time tz version>/dev/null
/Users/kmarc/bin/tanzu version > /dev/null  0.26s user 0.03s system 140% cpu 0.208 total
$ time tz version>/dev/null
/Users/kmarc/bin/tanzu version > /dev/null  0.24s user 0.02s system 137% cpu 0.189 total
$ time tz version>/dev/null
/Users/kmarc/bin/tanzu version > /dev/null  0.25s user 0.03s system 130% cpu 0.211 total

With the PR we see a time closer to 0.14 which is a 30% improvement

$ time tz version>/dev/null
/Users/kmarc/bin/tanzu version > /dev/null  0.12s user 0.02s system 116% cpu 0.123 total
$ time tz version>/dev/null
/Users/kmarc/bin/tanzu version > /dev/null  0.12s user 0.02s system 77% cpu 0.185 total
$ time tz version>/dev/null
/Users/kmarc/bin/tanzu version > /dev/null  0.12s user 0.02s system 115% cpu 0.120 total
$ time tz version>/dev/null
/Users/kmarc/bin/tanzu version > /dev/null  0.12s user 0.02s system 101% cpu 0.141 total
$ time tz version>/dev/null
/Users/kmarc/bin/tanzu version > /dev/null  0.13s user 0.02s system 111% cpu 0.133 total
$ time tz version>/dev/null
/Users/kmarc/bin/tanzu version > /dev/null  0.12s user 0.02s system 108% cpu 0.134 total
$ time tz version>/dev/null
/Users/kmarc/bin/tanzu version > /dev/null  0.12s user 0.02s system 120% cpu 0.121 total

Release note

Speed up CLI by avoiding unnecessary writing to the Catalog of plugins

Additional information

Special notes for your reviewers

On my M1 machine I see these speed results:

I repeatedly run time tz __complete '' > /dev/null to test shell completion responsiveness.

With 1 context: v1.2.0 -> ~0.18 secs v1.3.0 -> ~0.18 secs v1.4.1 -> ~0.16 secs v1.5.1 -> ~0.17 secs main (92c98e8b8) -> ~0.17 secs with this PR -> ~0.10 secs

So we see a significant improvement. It makes basic shell completion blazingly fast.

marckhouzam avatar Nov 28 '24 03:11 marckhouzam

Thanks for the clear explanation. Looks like a good bit of optimization.

with this PR, since we only run the plugin migration once, we must migrate the context-scoped plugins for all contexts immediately. This is a slight change in behaviour because context-scoped plugins for an inactive (and possibly old context) will now appear as standalone plugins right away for the new CLI. Since this new behaviour is similar to point 2 above, I feel it is acceptable

On point 3, I am not sure whether there was some nuance behind the way it was done before this change. Interested to hear @anujc25's take on this.

vuil avatar Dec 03 '24 18:12 vuil

On point 3, I am not sure whether there was some nuance behind the way it was done before this change. Interested to hear @anujc25's take on this.

Yes. This seems like the correct thing to do. I added a TODO to update the implementation this way because the globalinitializer approach was not available when I implemented this context-scoped plugin to standalone plugin migration. See the existing TODO below.

// Migrate context-scoped plugins as standalone plugin if required // TODO(anujc): Think on how to invoke this function just once after the newer version // of the CLI gets installed as we just need to do this migration once

anujc25 avatar Dec 04 '24 12:12 anujc25