From 90c73b83e6c3f993a9c64a4e9b6eb0361527cb81 Mon Sep 17 00:00:00 2001 From: Aldo Lacuku Date: Wed, 3 Apr 2024 12:25:14 +0200 Subject: [PATCH] fix(ci): support release of plugins with same prefix Cases such k8saudit and k8saudit-gke need special handling when pushing artifacts. Signed-off-by: Aldo Lacuku --- build/registry/pkg/oci/configLayer.go | 49 +++++++++++++++----------- build/registry/pkg/oci/oci.go | 38 +++++++++++--------- build/registry/pkg/oci/requirements.go | 15 -------- 3 files changed, 50 insertions(+), 52 deletions(-) diff --git a/build/registry/pkg/oci/configLayer.go b/build/registry/pkg/oci/configLayer.go index 4e19e522..e759ed1b 100644 --- a/build/registry/pkg/oci/configLayer.go +++ b/build/registry/pkg/oci/configLayer.go @@ -23,6 +23,9 @@ import ( "os" "strings" + "github.com/falcosecurity/plugin-sdk-go/pkg/loader" + "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins" + "github.com/falcosecurity/falcoctl/pkg/oci" "github.com/falcosecurity/plugins/build/registry/pkg/common" ) @@ -78,7 +81,25 @@ func rulesfileConfig(name, version, filePath string) (*oci.ArtifactConfig, error return cfg, nil } -func pluginConfig(name, version, filePath string) (*oci.ArtifactConfig, error) { +func pluginConfig(name, version string, pluginInfo *plugins.Info) (*oci.ArtifactConfig, error) { + // Check that the name we got from the registry.yaml is the same as the embedded one in the plugin at build time. + if name != pluginInfo.Name { + return nil, fmt.Errorf("mismatch between name in registry.yaml (%q) and name found in plugin shared object (%q)", name, pluginInfo.Name) + } + + cfg := &oci.ArtifactConfig{ + Name: name, + Version: version, + Dependencies: nil, + Requirements: nil, + } + + _ = cfg.SetRequirement(common.PluginAPIVersion, pluginInfo.RequiredAPIVersion) + + return cfg, nil +} + +func pluginInfo(filePath string) (*plugins.Info, error) { // Create temp dir. tmpDir, err := os.MkdirTemp("", "registry-oci-") if err != nil { @@ -90,32 +111,18 @@ func pluginConfig(name, version, filePath string) (*oci.ArtifactConfig, error) { return nil, err } - cfg := &oci.ArtifactConfig{ - Name: name, - Version: version, - Dependencies: nil, - Requirements: nil, - } - for _, file := range files { // skip files that are not a shared library such as README files. if !strings.HasSuffix(file, ".so") { continue } - // Get the requirement for the given file. - req, err := pluginRequirement(file) - if err != nil && !errors.Is(err, ErrReqNotFound) { - return nil, err - } - // If found add it to the requirements list. - if err == nil { - _ = cfg.SetRequirement(req.Name, req.Version) + // Get the plugin info. + plugin, err := loader.NewPlugin(file) + if err != nil { + return nil, fmt.Errorf("unable to open plugin %q: %w", file, err) } + return plugin.Info(), nil } - if cfg.Requirements == nil { - return nil, fmt.Errorf("no requirements found for plugin %q", filePath) - } - - return cfg, nil + return nil, fmt.Errorf("no plugin found in archive %q", filePath) } diff --git a/build/registry/pkg/oci/oci.go b/build/registry/pkg/oci/oci.go index 116aa322..3ebf8d9d 100644 --- a/build/registry/pkg/oci/oci.go +++ b/build/registry/pkg/oci/oci.go @@ -26,6 +26,8 @@ import ( "runtime" "strings" + "github.com/falcosecurity/plugin-sdk-go/pkg/sdk/plugins" + "github.com/falcosecurity/plugins/build/registry/pkg/common" "github.com/blang/semver" @@ -198,6 +200,7 @@ func handlePlugin(ctx context.Context, cfg *config, plugin *registry.Plugin, oci var err error var filepaths, platforms, tags []string var version string + var infoP *plugins.Info // Build the reference for the artifact. ref := refFromPluginEntry(cfg, plugin, false) @@ -212,6 +215,18 @@ func handlePlugin(ctx context.Context, cfg *config, plugin *registry.Plugin, oci } if amd64Build != "" { + if infoP, err = pluginInfo(filepath.Join(pluginsAMD64, amd64Build)); err != nil { + return nil, err + } + + // Check that the plugin has the same name as the one we got from the registry.yaml. + // If not, we skip it. It could happen that plugins share the same prefix, example k8saudit, k8saudit-gke. + if infoP.Name != plugin.Name { + // buildName func returned a wrong path starting from the plugin name found in registry.yaml. + klog.Warningf("skipping plugin since there is a mismatch in plugin name (%q) and plugin info name(%q)", plugin.Name, infoP.Name) + return nil, nil + } + filepaths = append(filepaths, filepath.Join(pluginsAMD64, amd64Build)) platforms = append(platforms, amd64Platform) } @@ -242,24 +257,15 @@ func handlePlugin(ctx context.Context, cfg *config, plugin *registry.Plugin, oci return nil, err } - // current platform where the CI is running. - platform := currentPlatform() - for i, p := range platforms { - // We need to get the plugin that have been built for the same platform as the one where we are loading it. - if p == platform { - configLayer, err = pluginConfig(plugin.Name, version, filepaths[i]) - if err != nil { - klog.Errorf("unable to generate config file: %v", err) - return nil, err - } - break - } - continue + if infoP == nil { + klog.Warningf("no config layer generated for plugin %q: the plugins has not been build for the current platform %q", plugin.Name, currentPlatform()) + return nil, nil } - if configLayer == nil { - klog.Warningf("no config layer generated for plugin %q: the plugins has not been build for the current platform %q", plugin.Name, platform) - return nil, nil + configLayer, err = pluginConfig(plugin.Name, version, infoP) + if err != nil { + klog.Errorf("unable to generate config file: %v", err) + return nil, err } klog.Infof("pushing plugin to remote repo with ref %q and tags %q", ref, tags) diff --git a/build/registry/pkg/oci/requirements.go b/build/registry/pkg/oci/requirements.go index ee94e40f..a9f99a98 100644 --- a/build/registry/pkg/oci/requirements.go +++ b/build/registry/pkg/oci/requirements.go @@ -27,7 +27,6 @@ import ( "github.com/blang/semver" "github.com/falcosecurity/falcoctl/pkg/oci" - "github.com/falcosecurity/plugin-sdk-go/pkg/loader" "github.com/falcosecurity/plugins/build/registry/pkg/common" ) @@ -87,17 +86,3 @@ func rulesfileRequirement(filePath string) (*oci.ArtifactRequirement, error) { Version: reqVer.String(), }, nil } - -// pluginRequirement given a plugin as a shared library it loads it and gets the api version -// required by the plugin. -func pluginRequirement(filePath string) (*oci.ArtifactRequirement, error) { - plugin, err := loader.NewPlugin(filePath) - if err != nil { - return nil, fmt.Errorf("unable to open plugin %q: %w", filePath, err) - } - - return &oci.ArtifactRequirement{ - Name: common.PluginAPIVersion, - Version: plugin.Info().RequiredAPIVersion, - }, nil -}