updated vendor
This commit is contained in:
+29
-8
@@ -19,6 +19,7 @@ import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
@@ -158,18 +159,27 @@ func LoadDir(dirname string) (Plugin, error) {
|
||||
return pm.CreatePlugin(dirname, m)
|
||||
}
|
||||
|
||||
// LoadAll loads all plugins found beneath the base directory.
|
||||
func LogIgnorePluginLoadErrorFilterFunc(pluginYAML string, err error) error {
|
||||
slog.Warn("failed to load plugin (ignoring)", slog.String("plugin_yaml", pluginYAML), slog.Any("error", err))
|
||||
return nil
|
||||
}
|
||||
|
||||
// errorFilterFunc is a function that can filter errors during plugin loading
|
||||
type ErrorFilterFunc func(string, error) error
|
||||
|
||||
// LoadAllDir load all plugins found beneath the base directory, using the provided error filter to determine whether to fail on individual plugin load errors.
|
||||
//
|
||||
// This scans only one directory level.
|
||||
func LoadAll(basedir string) ([]Plugin, error) {
|
||||
var plugins []Plugin
|
||||
// We want basedir/*/plugin.yaml
|
||||
func LoadAllDir(basedir string, errorFilter ErrorFilterFunc) ([]Plugin, error) {
|
||||
// We want <basedir>/*/plugin.yaml
|
||||
scanpath := filepath.Join(basedir, "*", PluginFileName)
|
||||
matches, err := filepath.Glob(scanpath)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to search for plugins in %q: %w", scanpath, err)
|
||||
}
|
||||
|
||||
plugins := make([]Plugin, 0, len(matches))
|
||||
|
||||
// empty dir should load
|
||||
if len(matches) == 0 {
|
||||
return plugins, nil
|
||||
@@ -179,9 +189,12 @@ func LoadAll(basedir string) ([]Plugin, error) {
|
||||
dir := filepath.Dir(yamlFile)
|
||||
p, err := LoadDir(dir)
|
||||
if err != nil {
|
||||
return plugins, err
|
||||
if errNew := errorFilter(yamlFile, err); errNew != nil {
|
||||
return plugins, errNew
|
||||
}
|
||||
} else {
|
||||
plugins = append(plugins, p)
|
||||
}
|
||||
plugins = append(plugins, p)
|
||||
}
|
||||
return plugins, detectDuplicates(plugins)
|
||||
}
|
||||
@@ -193,8 +206,12 @@ type findFunc func(pluginsDir string) ([]Plugin, error)
|
||||
type filterFunc func(Plugin) bool
|
||||
|
||||
// FindPlugins returns a list of plugins that match the descriptor
|
||||
// Errors loading a plugin are ignored with a warning
|
||||
func FindPlugins(pluginsDirs []string, descriptor Descriptor) ([]Plugin, error) {
|
||||
return findPlugins(pluginsDirs, LoadAll, makeDescriptorFilter(descriptor))
|
||||
loadAllIgnoreErrors := func(pluginsDir string) ([]Plugin, error) {
|
||||
return LoadAllDir(pluginsDir, LogIgnorePluginLoadErrorFilterFunc)
|
||||
}
|
||||
return findPlugins(pluginsDirs, loadAllIgnoreErrors, makeDescriptorFilter(descriptor))
|
||||
}
|
||||
|
||||
// findPlugins is the internal implementation that uses the find and filter functions
|
||||
@@ -237,7 +254,11 @@ func makeDescriptorFilter(descriptor Descriptor) filterFunc {
|
||||
|
||||
// FindPlugin returns a single plugin that matches the descriptor
|
||||
func FindPlugin(dirs []string, descriptor Descriptor) (Plugin, error) {
|
||||
plugins, err := FindPlugins(dirs, descriptor)
|
||||
loadAllIgnoreErrors := func(pluginsDir string) ([]Plugin, error) {
|
||||
return LoadAllDir(pluginsDir, LogIgnorePluginLoadErrorFilterFunc)
|
||||
}
|
||||
|
||||
plugins, err := findPlugins(dirs, loadAllIgnoreErrors, makeDescriptorFilter(descriptor))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
+18
-5
@@ -19,9 +19,17 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/Masterminds/semver/v3"
|
||||
|
||||
"helm.sh/helm/v4/internal/plugin/schema"
|
||||
)
|
||||
|
||||
// isValidSemver checks if the given string is a valid semantic version
|
||||
func isValidSemver(v string) bool {
|
||||
_, err := semver.StrictNewVersion(v)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// Metadata of a plugin, converted from the "on-disk" legacy or v1 plugin.yaml
|
||||
// Specifically, Config and RuntimeConfig are converted to their respective types based on the plugin type and runtime
|
||||
type Metadata struct {
|
||||
@@ -57,24 +65,29 @@ func (m Metadata) Validate() error {
|
||||
errs = append(errs, fmt.Errorf("invalid plugin name %q: must contain only a-z, A-Z, 0-9, _ and -", m.Name))
|
||||
}
|
||||
|
||||
// Require version to be valid semver if specified
|
||||
if m.Version != "" && !isValidSemver(m.Version) {
|
||||
errs = append(errs, fmt.Errorf("invalid plugin version %q: must be valid semver", m.Version))
|
||||
}
|
||||
|
||||
if m.APIVersion == "" {
|
||||
errs = append(errs, fmt.Errorf("empty APIVersion"))
|
||||
errs = append(errs, errors.New("empty APIVersion"))
|
||||
}
|
||||
|
||||
if m.Type == "" {
|
||||
errs = append(errs, fmt.Errorf("empty type field"))
|
||||
errs = append(errs, errors.New("empty type field"))
|
||||
}
|
||||
|
||||
if m.Runtime == "" {
|
||||
errs = append(errs, fmt.Errorf("empty runtime field"))
|
||||
errs = append(errs, errors.New("empty runtime field"))
|
||||
}
|
||||
|
||||
if m.Config == nil {
|
||||
errs = append(errs, fmt.Errorf("missing config field"))
|
||||
errs = append(errs, errors.New("missing config field"))
|
||||
}
|
||||
|
||||
if m.RuntimeConfig == nil {
|
||||
errs = append(errs, fmt.Errorf("missing runtimeConfig field"))
|
||||
errs = append(errs, errors.New("missing runtimeConfig field"))
|
||||
}
|
||||
|
||||
// Validate the config itself
|
||||
|
||||
@@ -16,6 +16,7 @@ limitations under the License.
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode"
|
||||
@@ -71,14 +72,19 @@ func (m *MetadataLegacy) Validate() error {
|
||||
if !validPluginName.MatchString(m.Name) {
|
||||
return fmt.Errorf("invalid plugin name %q: must contain only a-z, A-Z, 0-9, _ and -", m.Name)
|
||||
}
|
||||
|
||||
if m.Version != "" && !isValidSemver(m.Version) {
|
||||
return fmt.Errorf("invalid plugin version %q: must be valid semver", m.Version)
|
||||
}
|
||||
|
||||
m.Usage = sanitizeString(m.Usage)
|
||||
|
||||
if len(m.PlatformCommand) > 0 && len(m.Command) > 0 {
|
||||
return fmt.Errorf("both platformCommand and command are set")
|
||||
return errors.New("both platformCommand and command are set")
|
||||
}
|
||||
|
||||
if len(m.PlatformHooks) > 0 && len(m.Hooks) > 0 {
|
||||
return fmt.Errorf("both platformHooks and hooks are set")
|
||||
return errors.New("both platformHooks and hooks are set")
|
||||
}
|
||||
|
||||
// Validate downloader plugins
|
||||
|
||||
+11
-3
@@ -16,6 +16,7 @@ limitations under the License.
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
@@ -48,7 +49,14 @@ type MetadataV1 struct {
|
||||
|
||||
func (m *MetadataV1) Validate() error {
|
||||
if !validPluginName.MatchString(m.Name) {
|
||||
return fmt.Errorf("invalid plugin `name`")
|
||||
return errors.New("invalid plugin `name`")
|
||||
}
|
||||
|
||||
if m.Version == "" {
|
||||
return errors.New("plugin `version` is required")
|
||||
}
|
||||
if !isValidSemver(m.Version) {
|
||||
return fmt.Errorf("invalid plugin `version` %q: must be valid semver", m.Version)
|
||||
}
|
||||
|
||||
if m.APIVersion != "v1" {
|
||||
@@ -56,11 +64,11 @@ func (m *MetadataV1) Validate() error {
|
||||
}
|
||||
|
||||
if m.Type == "" {
|
||||
return fmt.Errorf("`type` missing")
|
||||
return errors.New("`type` missing")
|
||||
}
|
||||
|
||||
if m.Runtime == "" {
|
||||
return fmt.Errorf("`runtime` missing")
|
||||
return errors.New("`runtime` missing")
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -117,8 +117,8 @@ func (r *SubprocessPluginRuntime) InvokeWithEnv(main string, argv []string, env
|
||||
cmd.Env = slices.Clone(os.Environ())
|
||||
cmd.Env = append(
|
||||
cmd.Env,
|
||||
fmt.Sprintf("HELM_PLUGIN_NAME=%s", r.metadata.Name),
|
||||
fmt.Sprintf("HELM_PLUGIN_DIR=%s", r.pluginDir))
|
||||
"HELM_PLUGIN_NAME="+r.metadata.Name,
|
||||
"HELM_PLUGIN_DIR="+r.pluginDir)
|
||||
cmd.Env = append(cmd.Env, env...)
|
||||
|
||||
cmd.Stdin = stdin
|
||||
|
||||
@@ -24,6 +24,7 @@ import (
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"strconv"
|
||||
|
||||
"helm.sh/helm/v4/internal/plugin/schema"
|
||||
)
|
||||
@@ -63,7 +64,7 @@ func (r *SubprocessPluginRuntime) runGetter(input *Input) (*Output, error) {
|
||||
env["HELM_PLUGIN_DIR"] = r.pluginDir
|
||||
env["HELM_PLUGIN_USERNAME"] = msg.Options.Username
|
||||
env["HELM_PLUGIN_PASSWORD"] = msg.Options.Password
|
||||
env["HELM_PLUGIN_PASS_CREDENTIALS_ALL"] = fmt.Sprintf("%t", msg.Options.PassCredentialsAll)
|
||||
env["HELM_PLUGIN_PASS_CREDENTIALS_ALL"] = strconv.FormatBool(msg.Options.PassCredentialsAll)
|
||||
|
||||
command, args, err := PrepareCommands(d.PlatformCommand, false, []string{}, env)
|
||||
if err != nil {
|
||||
|
||||
+2
-1
@@ -14,6 +14,7 @@
|
||||
package schema
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
)
|
||||
@@ -55,7 +56,7 @@ type ConfigGetterV1 struct {
|
||||
|
||||
func (c *ConfigGetterV1) Validate() error {
|
||||
if len(c.Protocols) == 0 {
|
||||
return fmt.Errorf("getter has no protocols")
|
||||
return errors.New("getter has no protocols")
|
||||
}
|
||||
for i, protocol := range c.Protocols {
|
||||
if protocol == "" {
|
||||
|
||||
+1
-1
@@ -23,7 +23,7 @@ import (
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/ProtonMail/go-crypto/openpgp/clearsign" //nolint
|
||||
"github.com/ProtonMail/go-crypto/openpgp/clearsign"
|
||||
|
||||
"helm.sh/helm/v4/pkg/helmpath"
|
||||
)
|
||||
|
||||
@@ -16,7 +16,7 @@ limitations under the License.
|
||||
package plugin
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"errors"
|
||||
"os"
|
||||
"runtime"
|
||||
"strings"
|
||||
@@ -80,7 +80,7 @@ func getPlatformCommand(cmds []PlatformCommand) ([]string, []string) {
|
||||
func PrepareCommands(cmds []PlatformCommand, expandArgs bool, extraArgs []string, env map[string]string) (string, []string, error) {
|
||||
cmdParts, args := getPlatformCommand(cmds)
|
||||
if len(cmdParts) == 0 || cmdParts[0] == "" {
|
||||
return "", nil, fmt.Errorf("no plugin command is applicable")
|
||||
return "", nil, errors.New("no plugin command is applicable")
|
||||
}
|
||||
envMappingFunc := func(key string) string {
|
||||
return env[key]
|
||||
|
||||
+1
-1
@@ -33,7 +33,7 @@ func VerifyPlugin(archiveData, provData []byte, filename, keyring string) (*prov
|
||||
return sig.Verify(archiveData, provData, filename)
|
||||
}
|
||||
|
||||
// isTarball checks if a file has a tarball extension
|
||||
// IsTarball checks if a file has a tarball extension
|
||||
func IsTarball(filename string) bool {
|
||||
return filepath.Ext(filename) == ".gz" || filepath.Ext(filename) == ".tgz"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user