From a08bb230d4cff37bd5fa686eb1fc606f9e6022ea Mon Sep 17 00:00:00 2001 From: Lucas Bajolet Date: Fri, 2 Feb 2024 10:34:52 -0500 Subject: [PATCH] plugins: add a release only flag to Discover Since we now support loading pre-releases, we also want Packer to be able to ignore them by user demand, so we put in place the infrastructure to modulate this. --- command/build.go | 2 +- command/init_test.go | 2 +- command/plugins_install_test.go | 2 +- command/validate.go | 2 +- hcl2template/plugin.go | 5 +++-- packer/core.go | 4 ++-- packer/plugin-getter/plugins.go | 11 ++++++++++- packer/plugin.go | 3 ++- packer/plugin_discover_test.go | 14 +++++++------- packer/run_interfaces.go | 2 +- 10 files changed, 29 insertions(+), 18 deletions(-) diff --git a/command/build.go b/command/build.go index c0a4d8c01..abc8b33e2 100644 --- a/command/build.go +++ b/command/build.go @@ -91,7 +91,7 @@ func (c *BuildCommand) RunContext(buildCtx context.Context, cla *BuildArgs) int return ret } - diags := packerStarter.DetectPluginBinaries() + diags := packerStarter.DetectPluginBinaries(false) ret = writeDiags(c.Ui, nil, diags) if ret != 0 { return ret diff --git a/command/init_test.go b/command/init_test.go index ad501f151..343f1257b 100644 --- a/command/init_test.go +++ b/command/init_test.go @@ -263,7 +263,7 @@ func TestInitCommand_Run(t *testing.T) { Meta: tt.Meta, } - if err := c.CoreConfig.Components.PluginConfig.Discover(); err != nil { + if err := c.CoreConfig.Components.PluginConfig.Discover(false); err != nil { t.Fatalf("Failed to discover plugins: %s", err) } diff --git a/command/plugins_install_test.go b/command/plugins_install_test.go index e8ad08fd4..32f7f96f0 100644 --- a/command/plugins_install_test.go +++ b/command/plugins_install_test.go @@ -147,7 +147,7 @@ func TestPluginsInstallCommand_Run(t *testing.T) { Meta: tt.Meta, } - if err := c.CoreConfig.Components.PluginConfig.Discover(); err != nil { + if err := c.CoreConfig.Components.PluginConfig.Discover(false); err != nil { t.Fatalf("Failed to discover plugins: %s", err) } diff --git a/command/validate.go b/command/validate.go index 9747dabf9..cd56c4f3d 100644 --- a/command/validate.go +++ b/command/validate.go @@ -65,7 +65,7 @@ func (c *ValidateCommand) RunContext(ctx context.Context, cla *ValidateArgs) int return 0 } - diags := packerStarter.DetectPluginBinaries() + diags := packerStarter.DetectPluginBinaries(false) ret = writeDiags(c.Ui, nil, diags) if ret != 0 { return ret diff --git a/hcl2template/plugin.go b/hcl2template/plugin.go index 6a66aa610..c0f94e3f9 100644 --- a/hcl2template/plugin.go +++ b/hcl2template/plugin.go @@ -54,9 +54,9 @@ func (cfg *PackerConfig) PluginRequirements() (plugingetter.Requirements, hcl.Di return reqs, diags } -func (cfg *PackerConfig) DetectPluginBinaries() hcl.Diagnostics { +func (cfg *PackerConfig) DetectPluginBinaries(releaseOnly bool) hcl.Diagnostics { // Do first pass to discover all the installed plugins - err := cfg.parser.PluginConfig.Discover() + err := cfg.parser.PluginConfig.Discover(releaseOnly) if err != nil { return (hcl.Diagnostics{}).Append(&hcl.Diagnostic{ Severity: hcl.DiagError, @@ -76,6 +76,7 @@ func (cfg *PackerConfig) DetectPluginBinaries() hcl.Diagnostics { Checksummers: []plugingetter.Checksummer{ {Type: "sha256", Hash: sha256.New()}, }, + ReleasesOnly: releaseOnly, }, } diff --git a/packer/core.go b/packer/core.go index 0f3ea9c9c..369ead37f 100644 --- a/packer/core.go +++ b/packer/core.go @@ -135,10 +135,10 @@ func NewCore(c *CoreConfig) *Core { // DetectPluginBinaries is used to load required plugins from the template, // since it is unsupported in JSON, this is essentially a no-op. -func (c *Core) DetectPluginBinaries() hcl.Diagnostics { +func (c *Core) DetectPluginBinaries(releaseOnly bool) hcl.Diagnostics { var diags hcl.Diagnostics - err := c.components.PluginConfig.Discover() + err := c.components.PluginConfig.Discover(releaseOnly) if err != nil { diags = diags.Append(&hcl.Diagnostic{ Severity: hcl.DiagError, diff --git a/packer/plugin-getter/plugins.go b/packer/plugin-getter/plugins.go index fae1809e0..3271a868d 100644 --- a/packer/plugin-getter/plugins.go +++ b/packer/plugin-getter/plugins.go @@ -60,6 +60,10 @@ type BinaryInstallationOptions struct { Ext string Checksummers []Checksummer + + // ReleasesOnly may be set by commands like validate or build, and + // forces Packer to not consider plugin pre-releases. + ReleasesOnly bool } type ListInstallationsOptions struct { @@ -154,13 +158,18 @@ func (pr Requirement) ListInstallations(opts ListInstallationsOptions) (InstallL // versionsStr now looks like v1.2.3_x5.1 or amazon_v1.2.3_x5.1 parts := strings.SplitN(versionsStr, "_", 2) pluginVersionStr, protocolVerionStr := parts[0], parts[1] - _, err = version.NewVersion(pluginVersionStr) + ver, err := version.NewVersion(pluginVersionStr) if err != nil { // could not be parsed, ignoring the file log.Printf("found %q with an incorrect %q version, ignoring it. %v", path, pluginVersionStr, err) continue } + if ver.Prerelease() != "" && opts.ReleasesOnly { + log.Printf("ignoring pre-release plugin %q", path) + continue + } + matches := pluginVersionRegex.FindStringSubmatch(pluginVersionStr) if matches == nil { log.Printf("invalid version found: %q, ignoring", pluginVersionStr) diff --git a/packer/plugin.go b/packer/plugin.go index c6d4c1259..96ff96734 100644 --- a/packer/plugin.go +++ b/packer/plugin.go @@ -49,7 +49,7 @@ var extractPluginBasename = regexp.MustCompile("^packer-plugin-([^_]+)") // found plugins, in that order. // Hence, the priority order is the reverse of the search order - i.e., the // CWD has the highest priority. -func (c *PluginConfig) Discover() error { +func (c *PluginConfig) Discover(releasesOnly bool) error { if c.Builders == nil { c.Builders = MapOfBuilder{} } @@ -81,6 +81,7 @@ func (c *PluginConfig) Discover() error { Checksummers: []plugingetter.Checksummer{ {Type: "sha256", Hash: sha256.New()}, }, + ReleasesOnly: releasesOnly, }, }) if err != nil { diff --git a/packer/plugin_discover_test.go b/packer/plugin_discover_test.go index 3eca150d8..0644a6cf5 100644 --- a/packer/plugin_discover_test.go +++ b/packer/plugin_discover_test.go @@ -33,7 +33,7 @@ func TestDiscoverReturnsIfMagicCookieSet(t *testing.T) { t.Setenv(pluginsdk.MagicCookieKey, pluginsdk.MagicCookieValue) - err := config.Discover() + err := config.Discover(false) if err != nil { t.Fatalf("Should not have errored: %s", err) } @@ -48,7 +48,7 @@ func TestMultiPlugin_describe(t *testing.T) { pluginDir := os.Getenv("PACKER_PLUGIN_PATH") defer os.RemoveAll(pluginDir) c := PluginConfig{} - err := c.Discover() + err := c.Discover(false) if err != nil { t.Fatalf("error discovering plugins; %s", err.Error()) } @@ -88,7 +88,7 @@ func TestMultiPlugin_describe_installed(t *testing.T) { defer os.RemoveAll(pluginDir) c := PluginConfig{} - err := c.Discover() + err := c.Discover(false) if err != nil { t.Fatalf("error discovering plugins; %s", err.Error()) } @@ -151,7 +151,7 @@ func TestMultiPlugin_describe_installed_for_invalid(t *testing.T) { defer os.RemoveAll(pluginDir) c := PluginConfig{} - err := c.Discover() + err := c.Discover(false) if err != nil { t.Fatalf("error discovering plugins; %s", err.Error()) } @@ -195,7 +195,7 @@ func TestMultiPlugin_defaultName(t *testing.T) { defer os.RemoveAll(pluginDir) c := PluginConfig{} - err := c.Discover() + err := c.Discover(false) if err != nil { t.Fatalf("error discovering plugins; %s ; mocks are %#v", err.Error(), defaultNameMock) } @@ -226,7 +226,7 @@ func TestMultiPlugin_IgnoreChecksumFile(t *testing.T) { } c := PluginConfig{} - err = c.Discover() + err = c.Discover(false) if err != nil { t.Fatalf("error discovering plugins; %s ; mocks are %#v", err.Error(), defaultNameMock) } @@ -244,7 +244,7 @@ func TestMultiPlugin_defaultName_each_plugin_type(t *testing.T) { defer os.RemoveAll(pluginDir) c := PluginConfig{} - err := c.Discover() + err := c.Discover(false) if err != nil { t.Fatal("Should not have error because pluginsdk.DEFAULT_NAME is used twice but only once per plugin type.") } diff --git a/packer/run_interfaces.go b/packer/run_interfaces.go index 07829e629..3257d47fe 100644 --- a/packer/run_interfaces.go +++ b/packer/run_interfaces.go @@ -43,7 +43,7 @@ type InitializeOptions struct { type PluginBinaryDetector interface { // DetectPluginBinaries is used only for HCL2 templates, and loads required // plugins if specified. - DetectPluginBinaries() hcl.Diagnostics + DetectPluginBinaries(releaseOnly bool) hcl.Diagnostics } // The Handler handles all Packer things. This interface reflects the Packer