forked from vmware-tanzu/tanzu-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Setup global initializer for missing central config file (vmware-tanz…
…u#723) The concept of global initializers is added to allow the CLI to prepare its data on certain conditions (triggers). The commit also uses one such initializer to fix a plugin cache that is missing the central_config.yaml file.
- Loading branch information
1 parent
1f579b3
commit 28a3418
Showing
20 changed files
with
791 additions
and
28 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
// Copyright 2024 VMware, Inc. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package centralconfig | ||
|
||
import ( | ||
"io" | ||
"os" | ||
"path/filepath" | ||
|
||
kerrors "k8s.io/apimachinery/pkg/util/errors" | ||
|
||
"github.com/vmware-tanzu/tanzu-cli/pkg/common" | ||
"github.com/vmware-tanzu/tanzu-cli/pkg/constants" | ||
"github.com/vmware-tanzu/tanzu-cli/pkg/discovery" | ||
"github.com/vmware-tanzu/tanzu-cli/pkg/globalinit" | ||
"github.com/vmware-tanzu/tanzu-plugin-runtime/config" | ||
) | ||
|
||
// The Central Configuration feature uses a central_config.yaml file that gets downloaded | ||
// along with the plugin inventory cache and is stored in the cache. Older versions of the | ||
// CLI (< 1.3.0) do not include this file in the cache. It is therefore possible that | ||
// the plugin inventory cache was setup by an older version of the CLI and is missing | ||
// the central_config.yaml file. In such a case, the digest of the cache will still indicate | ||
// that the latest plugin inventory is present and the content of the cache will not be refreshed | ||
// until the plugin inventory data changes in the central repo itself. In such a case, to be able | ||
// to benefit from the central configuration feature once the CLI is upgraded to >= 1.3.0 | ||
// we need to fix the cache. This initializer checks if the central_config.yaml file is | ||
// present in the cache and if not, it invalidates the cache. | ||
|
||
func init() { | ||
globalinit.RegisterInitializer("Central Config Initializer", triggerForInventoryCacheInvalidation, invalidateInventoryCache) | ||
} | ||
|
||
// triggerForInventoryCacheInvalidation returns true if the central_config.yaml file is missing | ||
// in the plugin inventory cache. | ||
func triggerForInventoryCacheInvalidation() bool { | ||
sources, err := config.GetCLIDiscoverySources() | ||
if err != nil { | ||
// No discovery source | ||
return false | ||
} | ||
|
||
for _, source := range sources { | ||
centralConfigFile := filepath.Join(common.DefaultCacheDir, common.PluginInventoryDirName, source.OCI.Name, constants.CentralConfigFileName) | ||
|
||
if _, err := os.Stat(centralConfigFile); os.IsNotExist(err) { | ||
// As soon as we find a source that doesn't have a central_config.yaml file, | ||
// we need to perform some initialization. | ||
return true | ||
} | ||
} | ||
// If we get here, then all sources have a central_config.yaml file | ||
return false | ||
} | ||
|
||
// invalidateInventoryCache performs the required actions | ||
func invalidateInventoryCache(_ io.Writer) error { | ||
sources, err := config.GetCLIDiscoverySources() | ||
if err != nil { | ||
// No discovery source | ||
return nil | ||
} | ||
|
||
var errorList []error | ||
for _, source := range sources { | ||
centralConfigFile := filepath.Join(common.DefaultCacheDir, common.PluginInventoryDirName, source.OCI.Name, constants.CentralConfigFileName) | ||
|
||
if _, err := os.Stat(centralConfigFile); os.IsNotExist(err) { | ||
// This source doesn't have a central_config.yaml file, | ||
// we need to invalidate its plugin inventory cache. | ||
err = discovery.RefreshDiscoveryDatabaseForSource(source, discovery.WithForceInvalidation()) | ||
if err != nil { | ||
errorList = append(errorList, err) | ||
} | ||
} | ||
} | ||
return kerrors.NewAggregate(errorList) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
// Copyright 2024 VMware, Inc. All Rights Reserved. | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
package centralconfig | ||
|
||
import ( | ||
"fmt" | ||
"os" | ||
"path/filepath" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
|
||
"github.com/vmware-tanzu/tanzu-cli/pkg/common" | ||
"github.com/vmware-tanzu/tanzu-cli/pkg/constants" | ||
"github.com/vmware-tanzu/tanzu-plugin-runtime/config" | ||
"github.com/vmware-tanzu/tanzu-plugin-runtime/config/types" | ||
) | ||
|
||
func TestTriggerForInventoryCacheInvalidation(t *testing.T) { | ||
tcs := []struct { | ||
name string | ||
numDiscoveries int | ||
missingCentralConfig []bool | ||
expectedToTrigger bool | ||
}{ | ||
{ | ||
name: "No discovery sources", | ||
numDiscoveries: 0, | ||
expectedToTrigger: false, | ||
}, | ||
{ | ||
name: "One discovery source with central config", | ||
numDiscoveries: 1, | ||
missingCentralConfig: []bool{false}, | ||
expectedToTrigger: false, | ||
}, | ||
{ | ||
name: "One discovery source with missing central config", | ||
numDiscoveries: 1, | ||
missingCentralConfig: []bool{true}, | ||
expectedToTrigger: true, | ||
}, | ||
{ | ||
name: "Two discovery sources both with central config", | ||
numDiscoveries: 2, | ||
missingCentralConfig: []bool{false, false}, | ||
expectedToTrigger: false, | ||
}, | ||
{ | ||
name: "Two discovery sources with only one missing central config", | ||
numDiscoveries: 2, | ||
missingCentralConfig: []bool{false, true}, | ||
expectedToTrigger: true, | ||
}, | ||
} | ||
|
||
configFile, err := os.CreateTemp("", "config") | ||
assert.Nil(t, err) | ||
os.Setenv("TANZU_CONFIG", configFile.Name()) | ||
|
||
configFileNG, err := os.CreateTemp("", "config_ng") | ||
assert.Nil(t, err) | ||
os.Setenv("TANZU_CONFIG_NEXT_GEN", configFileNG.Name()) | ||
|
||
defer func() { | ||
os.Unsetenv("TANZU_CONFIG") | ||
os.Unsetenv("TANZU_CONFIG_NEXT_GEN") | ||
os.RemoveAll(configFile.Name()) | ||
os.RemoveAll(configFileNG.Name()) | ||
}() | ||
|
||
for _, tc := range tcs { | ||
t.Run(tc.name, func(t *testing.T) { | ||
// Create a cache directory for the plugin inventory and the central config file | ||
cacheDir, err := os.MkdirTemp("", "test-cache-dir") | ||
assert.Nil(t, err) | ||
|
||
common.DefaultCacheDir = cacheDir | ||
|
||
// Create the discovery sources | ||
var discoveries []types.PluginDiscovery | ||
for i := 0; i < tc.numDiscoveries; i++ { | ||
discName := fmt.Sprintf("discovery%d", i) | ||
discoveries = append(discoveries, types.PluginDiscovery{ | ||
OCI: &types.OCIDiscovery{ | ||
Name: discName, | ||
}, | ||
}) | ||
|
||
// Create the directory for this discovery source | ||
centralCfgDir := filepath.Join(common.DefaultCacheDir, common.PluginInventoryDirName, discName) | ||
err = os.MkdirAll(centralCfgDir, 0755) | ||
assert.Nil(t, err) | ||
|
||
// Create the central config file if needed by the test | ||
if !tc.missingCentralConfig[i] { | ||
centralCfgFile := filepath.Join(centralCfgDir, constants.CentralConfigFileName) | ||
file, err := os.Create(centralCfgFile) | ||
assert.Nil(t, err) | ||
assert.NotNil(t, file) | ||
file.Close() | ||
} | ||
} | ||
|
||
err = config.SetCLIDiscoverySources(discoveries) | ||
assert.Nil(t, err) | ||
|
||
assert.Equal(t, triggerForInventoryCacheInvalidation(), tc.expectedToTrigger) | ||
|
||
os.RemoveAll(cacheDir) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.