From 4b00a81bf3bb64b119cc3541bd3c7260c006beda Mon Sep 17 00:00:00 2001 From: Lucas Bajolet Date: Mon, 15 Jan 2024 14:41:25 -0500 Subject: [PATCH] packer: remove directory slices from structs Since we'll only look in the plugin directory, and not from multiple sources now, for installing/listing plugins, we can simplify the structures which used to accept multiple directories so they only accept one. --- command/init.go | 4 +- command/plugins_install.go | 9 +- command/plugins_installed.go | 2 +- command/plugins_remove.go | 2 +- command/plugins_required.go | 2 +- hcl2template/plugin.go | 2 +- packer/plugin-getter/plugins.go | 209 +++++++++++++-------------- packer/plugin-getter/plugins_test.go | 136 ++--------------- packer/plugin.go | 9 +- packer/plugin_discover_test.go | 50 +++---- 10 files changed, 150 insertions(+), 275 deletions(-) diff --git a/command/init.go b/command/init.go index 3c7cfea09..2d8a19377 100644 --- a/command/init.go +++ b/command/init.go @@ -76,7 +76,7 @@ for more info.`) } opts := plugingetter.ListInstallationsOptions{ - FromFolders: []string{c.Meta.CoreConfig.Components.PluginConfig.PluginDirectory}, + PluginDirectory: c.Meta.CoreConfig.Components.PluginConfig.PluginDirectory, BinaryInstallationOptions: plugingetter.BinaryInstallationOptions{ OS: runtime.GOOS, ARCH: runtime.GOARCH, @@ -132,7 +132,7 @@ for more info.`) } newInstall, err := pluginRequirement.InstallLatest(plugingetter.InstallOptions{ - InFolders: opts.FromFolders, + PluginDirectory: opts.PluginDirectory, BinaryInstallationOptions: opts.BinaryInstallationOptions, Getters: getters, Force: cla.Force, diff --git a/command/plugins_install.go b/command/plugins_install.go index c63ff2afa..123457920 100644 --- a/command/plugins_install.go +++ b/command/plugins_install.go @@ -121,7 +121,7 @@ func (c *PluginsInstallCommand) ParseArgs(args []string) (*PluginsInstallArgs, i func (c *PluginsInstallCommand) RunContext(buildCtx context.Context, args *PluginsInstallArgs) int { opts := plugingetter.ListInstallationsOptions{ - FromFolders: []string{c.Meta.CoreConfig.Components.PluginConfig.PluginDirectory}, + PluginDirectory: c.Meta.CoreConfig.Components.PluginConfig.PluginDirectory, BinaryInstallationOptions: plugingetter.BinaryInstallationOptions{ OS: runtime.GOOS, ARCH: runtime.GOARCH, @@ -176,7 +176,7 @@ func (c *PluginsInstallCommand) RunContext(buildCtx context.Context, args *Plugi } newInstall, err := pluginRequirement.InstallLatest(plugingetter.InstallOptions{ - InFolders: opts.FromFolders, + PluginDirectory: opts.PluginDirectory, BinaryInstallationOptions: opts.BinaryInstallationOptions, Getters: getters, Force: args.Force, @@ -201,10 +201,7 @@ func (c *PluginsInstallCommand) RunContext(buildCtx context.Context, args *Plugi } func (c *PluginsInstallCommand) InstallFromBinary(opts plugingetter.ListInstallationsOptions, pluginIdentifier *addrs.Plugin, args *PluginsInstallArgs) int { - // As with the other commands, we get the last plugin directory as it - // has precedence over the others, and is where we'll install the - // plugins to. - pluginDir := opts.FromFolders[len(opts.FromFolders)-1] + pluginDir := opts.PluginDirectory var err error diff --git a/command/plugins_installed.go b/command/plugins_installed.go index 55e47f989..9652572da 100644 --- a/command/plugins_installed.go +++ b/command/plugins_installed.go @@ -43,7 +43,7 @@ func (c *PluginsInstalledCommand) Run(args []string) int { func (c *PluginsInstalledCommand) RunContext(buildCtx context.Context) int { opts := plugingetter.ListInstallationsOptions{ - FromFolders: []string{c.Meta.CoreConfig.Components.PluginConfig.PluginDirectory}, + PluginDirectory: c.Meta.CoreConfig.Components.PluginConfig.PluginDirectory, BinaryInstallationOptions: plugingetter.BinaryInstallationOptions{ OS: runtime.GOOS, ARCH: runtime.GOARCH, diff --git a/command/plugins_remove.go b/command/plugins_remove.go index 6da314107..7b29ffa7b 100644 --- a/command/plugins_remove.go +++ b/command/plugins_remove.go @@ -52,7 +52,7 @@ func (c *PluginsRemoveCommand) RunContext(buildCtx context.Context, args []strin } opts := plugingetter.ListInstallationsOptions{ - FromFolders: []string{c.Meta.CoreConfig.Components.PluginConfig.PluginDirectory}, + PluginDirectory: c.Meta.CoreConfig.Components.PluginConfig.PluginDirectory, BinaryInstallationOptions: plugingetter.BinaryInstallationOptions{ OS: runtime.GOOS, ARCH: runtime.GOARCH, diff --git a/command/plugins_required.go b/command/plugins_required.go index fd8513808..7ba301dcf 100644 --- a/command/plugins_required.go +++ b/command/plugins_required.go @@ -84,7 +84,7 @@ func (c *PluginsRequiredCommand) RunContext(buildCtx context.Context, cla *Plugi } opts := plugingetter.ListInstallationsOptions{ - FromFolders: []string{c.Meta.CoreConfig.Components.PluginConfig.PluginDirectory}, + PluginDirectory: c.Meta.CoreConfig.Components.PluginConfig.PluginDirectory, BinaryInstallationOptions: plugingetter.BinaryInstallationOptions{ OS: runtime.GOOS, ARCH: runtime.GOARCH, diff --git a/hcl2template/plugin.go b/hcl2template/plugin.go index de8549f38..15358573d 100644 --- a/hcl2template/plugin.go +++ b/hcl2template/plugin.go @@ -56,7 +56,7 @@ func (cfg *PackerConfig) PluginRequirements() (plugingetter.Requirements, hcl.Di func (cfg *PackerConfig) DetectPluginBinaries() hcl.Diagnostics { opts := plugingetter.ListInstallationsOptions{ - FromFolders: []string{cfg.parser.PluginConfig.PluginDirectory}, + PluginDirectory: cfg.parser.PluginConfig.PluginDirectory, BinaryInstallationOptions: plugingetter.BinaryInstallationOptions{ OS: runtime.GOOS, ARCH: runtime.GOARCH, diff --git a/packer/plugin-getter/plugins.go b/packer/plugin-getter/plugins.go index d6f52ebcc..1aa7834d1 100644 --- a/packer/plugin-getter/plugins.go +++ b/packer/plugin-getter/plugins.go @@ -58,9 +58,8 @@ type BinaryInstallationOptions struct { } type ListInstallationsOptions struct { - // FromFolders where plugins could be installed. Paths should be absolute for - // safety but can also be relative. - FromFolders []string + // The directory in which to look for when installing plugins + PluginDirectory string BinaryInstallationOptions } @@ -105,84 +104,84 @@ func (pr Requirement) ListInstallations(opts ListInstallationsOptions) (InstallL FilenamePrefix := pr.FilenamePrefix() filenameSuffix := opts.FilenameSuffix() log.Printf("[TRACE] listing potential installations for %q that match %q. %#v", pr.Identifier, pr.VersionConstraints, opts) - for _, knownFolder := range opts.FromFolders { - glob := "" - if pr.Identifier == nil { - glob = filepath.Join(knownFolder, "*", "*", "*", FilenamePrefix+"*"+filenameSuffix) - } else { - glob = filepath.Join(knownFolder, pr.Identifier.Hostname, pr.Identifier.Namespace, pr.Identifier.Type, FilenamePrefix+"*"+filenameSuffix) - } - matches, err := filepath.Glob(glob) - if err != nil { - return nil, fmt.Errorf("ListInstallations: %q failed to list binaries in folder: %v", pr.Identifier.String(), err) - } - for _, path := range matches { - fname := filepath.Base(path) - if fname == "." { - continue - } - - // base name could look like packer-plugin-amazon_v1.2.3_x5.1_darwin_amd64.exe - versionsStr := strings.TrimPrefix(fname, FilenamePrefix) - versionsStr = strings.TrimSuffix(versionsStr, filenameSuffix) - - if pr.Identifier == nil { - if idx := strings.Index(versionsStr, "_"); idx > 0 { - versionsStr = versionsStr[idx+1:] - } - } - - // 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] - pv, 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 - } - - // no constraint means always pass, this will happen for implicit - // plugin requirements and when we list all plugins. - if !pr.VersionConstraints.Check(pv) { - log.Printf("[TRACE] version %q of file %q does not match constraint %q", pluginVersionStr, path, pr.VersionConstraints.String()) - continue - } - - if err := opts.CheckProtocolVersion(protocolVerionStr); err != nil { - log.Printf("[NOTICE] binary %s requires protocol version %s that is incompatible "+ - "with this version of Packer. %s", path, protocolVerionStr, err) - continue - } - - checksumOk := false - for _, checksummer := range opts.Checksummers { - - cs, err := checksummer.GetCacheChecksumOfFile(path) - if err != nil { - log.Printf("[TRACE] GetChecksumOfFile(%q) failed: %v", path, err) - continue - } - - if err := checksummer.ChecksumFile(cs, path); err != nil { - log.Printf("[TRACE] ChecksumFile(%q) failed: %v", path, err) - continue - } - checksumOk = true - break - } - if !checksumOk { - log.Printf("[TRACE] No checksum found for %q ignoring possibly unsafe binary", path) - continue - } - - res = append(res, &Installation{ - BinaryPath: path, - Version: pluginVersionStr, - }) - } + glob := "" + if pr.Identifier == nil { + glob = filepath.Join(opts.PluginDirectory, "*", "*", "*", FilenamePrefix+"*"+filenameSuffix) + } else { + glob = filepath.Join(opts.PluginDirectory, pr.Identifier.Hostname, pr.Identifier.Namespace, pr.Identifier.Type, FilenamePrefix+"*"+filenameSuffix) } + + matches, err := filepath.Glob(glob) + if err != nil { + return nil, fmt.Errorf("ListInstallations: %q failed to list binaries in folder: %v", pr.Identifier.String(), err) + } + for _, path := range matches { + fname := filepath.Base(path) + if fname == "." { + continue + } + + // base name could look like packer-plugin-amazon_v1.2.3_x5.1_darwin_amd64.exe + versionsStr := strings.TrimPrefix(fname, FilenamePrefix) + versionsStr = strings.TrimSuffix(versionsStr, filenameSuffix) + + if pr.Identifier == nil { + if idx := strings.Index(versionsStr, "_"); idx > 0 { + versionsStr = versionsStr[idx+1:] + } + } + + // 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] + pv, 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 + } + + // no constraint means always pass, this will happen for implicit + // plugin requirements and when we list all plugins. + if !pr.VersionConstraints.Check(pv) { + log.Printf("[TRACE] version %q of file %q does not match constraint %q", pluginVersionStr, path, pr.VersionConstraints.String()) + continue + } + + if err := opts.CheckProtocolVersion(protocolVerionStr); err != nil { + log.Printf("[NOTICE] binary %s requires protocol version %s that is incompatible "+ + "with this version of Packer. %s", path, protocolVerionStr, err) + continue + } + + checksumOk := false + for _, checksummer := range opts.Checksummers { + + cs, err := checksummer.GetCacheChecksumOfFile(path) + if err != nil { + log.Printf("[TRACE] GetChecksumOfFile(%q) failed: %v", path, err) + continue + } + + if err := checksummer.ChecksumFile(cs, path); err != nil { + log.Printf("[TRACE] ChecksumFile(%q) failed: %v", path, err) + continue + } + checksumOk = true + break + } + if !checksumOk { + log.Printf("[TRACE] No checksum found for %q ignoring possibly unsafe binary", path) + continue + } + + res = append(res, &Installation{ + BinaryPath: path, + Version: pluginVersionStr, + }) + } + return res, nil } @@ -224,9 +223,8 @@ type InstallOptions struct { // Different means to get releases, sha256 and binary files. Getters []Getter - // Any downloaded binary and checksum file will be put in the last possible - // folder of this list. - InFolders []string + // The directory in which the plugins should be installed + PluginDirectory string // Forces installation of the plugin, even if already installed. Force bool @@ -481,7 +479,7 @@ func (pr *Requirement) InstallLatest(opts InstallOptions) (*Installation, error) outputFolder := filepath.Join( // Pick last folder as it's the one with the highest priority - opts.InFolders[len(opts.InFolders)-1], + opts.PluginDirectory, // add expected full path filepath.Join(pr.Identifier.Parts()...), ) @@ -549,36 +547,33 @@ func (pr *Requirement) InstallLatest(opts InstallOptions) (*Installation, error) expectedZipFilename := checksum.Filename expectedBinaryFilename := strings.TrimSuffix(expectedZipFilename, filepath.Ext(expectedZipFilename)) + opts.BinaryInstallationOptions.Ext - for _, outputFolder := range opts.InFolders { - potentialOutputFilename := filepath.Join( - outputFolder, - filepath.Join(pr.Identifier.Parts()...), - expectedBinaryFilename, - ) - for _, potentialChecksumer := range opts.Checksummers { - // First check if a local checksum file is already here in the expected - // download folder. Here we want to download a binary so we only check - // for an existing checksum file from the folder we want to download - // into. - cs, err := potentialChecksumer.GetCacheChecksumOfFile(potentialOutputFilename) - if err == nil && len(cs) > 0 { - localChecksum := &FileChecksum{ - Expected: cs, - Checksummer: potentialChecksumer, - } + outputFileName := filepath.Join( + outputFolder, + expectedBinaryFilename, + ) + for _, potentialChecksumer := range opts.Checksummers { + // First check if a local checksum file is already here in the expected + // download folder. Here we want to download a binary so we only check + // for an existing checksum file from the folder we want to download + // into. + cs, err := potentialChecksumer.GetCacheChecksumOfFile(outputFileName) + if err == nil && len(cs) > 0 { + localChecksum := &FileChecksum{ + Expected: cs, + Checksummer: potentialChecksumer, + } - log.Printf("[TRACE] found a pre-exising %q checksum file", potentialChecksumer.Type) - // if outputFile is there and matches the checksum: do nothing more. - if err := localChecksum.ChecksumFile(localChecksum.Expected, potentialOutputFilename); err == nil && !opts.Force { - log.Printf("[INFO] %s v%s plugin is already correctly installed in %q", pr.Identifier, version, potentialOutputFilename) - return nil, nil // success - } + log.Printf("[TRACE] found a pre-exising %q checksum file", potentialChecksumer.Type) + // if outputFile is there and matches the checksum: do nothing more. + if err := localChecksum.ChecksumFile(localChecksum.Expected, outputFileName); err == nil && !opts.Force { + log.Printf("[INFO] %s v%s plugin is already correctly installed in %q", pr.Identifier, version, outputFileName) + return nil, nil // success } } } // The last folder from the installation list is where we will install. - outputFileName := filepath.Join(outputFolder, expectedBinaryFilename) + outputFileName = filepath.Join(outputFolder, expectedBinaryFilename) // create directories if need be if err := os.MkdirAll(outputFolder, 0755); err != nil { diff --git a/packer/plugin-getter/plugins_test.go b/packer/plugin-getter/plugins_test.go index e13f8cb38..1f58e3496 100644 --- a/packer/plugin-getter/plugins_test.go +++ b/packer/plugin-getter/plugins_test.go @@ -78,10 +78,7 @@ func TestPlugin_ListInstallations(t *testing.T) { // empty }, ListInstallationsOptions{ - []string{ - pluginFolderOne, - pluginFolderTwo, - }, + pluginFolderOne, BinaryInstallationOptions{ OS: "windows", ARCH: "amd64", Ext: ".exe", @@ -119,22 +116,6 @@ func TestPlugin_ListInstallations(t *testing.T) { Version: "v4.5.8", BinaryPath: filepath.Join(pluginFolderOne, "github.com", "hashicorp", "google", "packer-plugin-google_v4.5.8_x5.0_windows_amd64.exe"), }, - { - Version: "v4.5.6", - BinaryPath: filepath.Join(pluginFolderTwo, "github.com", "hashicorp", "google", "packer-plugin-google_v4.5.6_x5.0_windows_amd64.exe"), - }, - { - Version: "v4.5.9", - BinaryPath: filepath.Join(pluginFolderTwo, "github.com", "hashicorp", "google", "packer-plugin-google_v4.5.9_x5.0_windows_amd64.exe"), - }, - { - Version: "v4.5.6", - BinaryPath: filepath.Join(pluginFolderTwo, "github.com", "hashicorp copy", "google", "packer-plugin-google_v4.5.6_x5.0_windows_amd64.exe"), - }, - { - Version: "v4.5.9", - BinaryPath: filepath.Join(pluginFolderTwo, "github.com", "hashicorp copy", "google", "packer-plugin-google_v4.5.9_x5.0_windows_amd64.exe"), - }, }, }, @@ -144,10 +125,7 @@ func TestPlugin_ListInstallations(t *testing.T) { Identifier: "github.com/hashicorp/amazon", }, ListInstallationsOptions{ - []string{ - pluginFolderOne, - pluginFolderTwo, - }, + pluginFolderOne, BinaryInstallationOptions{ APIVersionMajor: "5", APIVersionMinor: "0", OS: "darwin", ARCH: "amd64", @@ -181,10 +159,7 @@ func TestPlugin_ListInstallations(t *testing.T) { Identifier: "github.com/hashicorp/amazon", }, ListInstallationsOptions{ - []string{ - pluginFolderOne, - pluginFolderTwo, - }, + pluginFolderOne, BinaryInstallationOptions{ APIVersionMajor: "5", APIVersionMinor: "1", OS: "darwin", ARCH: "amd64", @@ -214,10 +189,6 @@ func TestPlugin_ListInstallations(t *testing.T) { Version: "v1.2.5", BinaryPath: filepath.Join(pluginFolderOne, "github.com", "hashicorp", "amazon", "packer-plugin-amazon_v1.2.5_x5.0_darwin_amd64"), }, - { - Version: "v1.2.6", - BinaryPath: filepath.Join(pluginFolderTwo, "github.com", "hashicorp", "amazon", "packer-plugin-amazon_v1.2.6_x5.1_darwin_amd64"), - }, }, }, { @@ -226,10 +197,7 @@ func TestPlugin_ListInstallations(t *testing.T) { Identifier: "github.com/hashicorp/amazon", }, ListInstallationsOptions{ - []string{ - pluginFolderOne, - pluginFolderTwo, - }, + pluginFolderOne, BinaryInstallationOptions{ APIVersionMajor: "5", APIVersionMinor: "0", OS: "windows", ARCH: "amd64", @@ -258,61 +226,13 @@ func TestPlugin_ListInstallations(t *testing.T) { }, }, }, - { - "windows_google_multifolder", - fields{ - Identifier: "github.com/hashicorp/google", - }, - ListInstallationsOptions{ - []string{ - pluginFolderOne, - pluginFolderTwo, - }, - BinaryInstallationOptions{ - APIVersionMajor: "5", APIVersionMinor: "0", - OS: "windows", ARCH: "amd64", - Ext: ".exe", - Checksummers: []Checksummer{ - { - Type: "sha256", - Hash: sha256.New(), - }, - }, - }, - }, - false, - []*Installation{ - { - Version: "v4.5.6", - BinaryPath: filepath.Join(pluginFolderOne, "github.com", "hashicorp", "google", "packer-plugin-google_v4.5.6_x5.0_windows_amd64.exe"), - }, - { - Version: "v4.5.7", - BinaryPath: filepath.Join(pluginFolderOne, "github.com", "hashicorp", "google", "packer-plugin-google_v4.5.7_x5.0_windows_amd64.exe"), - }, - { - Version: "v4.5.8", - BinaryPath: filepath.Join(pluginFolderOne, "github.com", "hashicorp", "google", "packer-plugin-google_v4.5.8_x5.0_windows_amd64.exe"), - }, - { - Version: "v4.5.6", - BinaryPath: filepath.Join(pluginFolderTwo, "github.com", "hashicorp", "google", "packer-plugin-google_v4.5.6_x5.0_windows_amd64.exe"), - }, - { - Version: "v4.5.9", - BinaryPath: filepath.Join(pluginFolderTwo, "github.com", "hashicorp", "google", "packer-plugin-google_v4.5.9_x5.0_windows_amd64.exe"), - }, - }, - }, { "test nil identifier - multiple plugins with same version", fields{ Identifier: "", }, ListInstallationsOptions{ - []string{ - pluginFolderThree, - }, + pluginFolderThree, BinaryInstallationOptions{ APIVersionMajor: "5", APIVersionMinor: "0", OS: "linux", ARCH: "amd64", @@ -398,11 +318,7 @@ func TestRequirement_InstallLatest(t *testing.T) { }, }, }, - []string{ - pluginFolderWrongChecksums, - pluginFolderOne, - pluginFolderTwo, - }, + pluginFolderOne, false, BinaryInstallationOptions{ APIVersionMajor: "5", APIVersionMinor: "0", @@ -435,11 +351,7 @@ func TestRequirement_InstallLatest(t *testing.T) { }, }, }, - []string{ - pluginFolderWrongChecksums, - pluginFolderOne, - pluginFolderTwo, - }, + pluginFolderOne, false, BinaryInstallationOptions{ APIVersionMajor: "5", APIVersionMinor: "1", @@ -481,11 +393,7 @@ func TestRequirement_InstallLatest(t *testing.T) { }, }, }, - []string{ - pluginFolderWrongChecksums, - pluginFolderOne, - pluginFolderTwo, - }, + pluginFolderOne, false, BinaryInstallationOptions{ APIVersionMajor: "5", APIVersionMinor: "0", @@ -529,11 +437,7 @@ func TestRequirement_InstallLatest(t *testing.T) { }, }, }, - []string{ - pluginFolderWrongChecksums, - pluginFolderOne, - pluginFolderTwo, - }, + pluginFolderTwo, false, BinaryInstallationOptions{ APIVersionMajor: "6", APIVersionMinor: "1", @@ -580,11 +484,7 @@ func TestRequirement_InstallLatest(t *testing.T) { }, }, }, - []string{ - pluginFolderWrongChecksums, - pluginFolderOne, - pluginFolderTwo, - }, + pluginFolderTwo, false, BinaryInstallationOptions{ APIVersionMajor: "6", APIVersionMinor: "1", @@ -631,11 +531,7 @@ func TestRequirement_InstallLatest(t *testing.T) { }, }, }, - []string{ - pluginFolderWrongChecksums, - pluginFolderOne, - pluginFolderTwo, - }, + pluginFolderTwo, false, BinaryInstallationOptions{ APIVersionMajor: "6", APIVersionMinor: "1", @@ -676,11 +572,7 @@ func TestRequirement_InstallLatest(t *testing.T) { }, }, }, - []string{ - pluginFolderWrongChecksums, - pluginFolderOne, - pluginFolderTwo, - }, + pluginFolderTwo, false, BinaryInstallationOptions{ APIVersionMajor: "6", APIVersionMinor: "1", @@ -720,9 +612,7 @@ func TestRequirement_InstallLatest(t *testing.T) { }, }, }, - []string{ - pluginFolderWrongChecksums, - }, + pluginFolderTwo, false, BinaryInstallationOptions{ APIVersionMajor: "6", APIVersionMinor: "1", diff --git a/packer/plugin.go b/packer/plugin.go index 246a7e1fe..3fd404d7a 100644 --- a/packer/plugin.go +++ b/packer/plugin.go @@ -67,6 +67,10 @@ func (c *PluginConfig) Discover() error { return nil } + if c.PluginDirectory == "" { + c.PluginDirectory, _ = PluginFolder() + } + if err := c.discoverInstalledComponents(c.PluginDirectory); err != nil { return err } @@ -120,7 +124,6 @@ func (c *PluginConfig) discoverSingle(glob string) (map[string]string, error) { // After the split the plugin name is "baz". pluginName = strings.SplitN(pluginName, "_", 2)[0] - log.Printf("[INFO] Discovered potential plugin: %s = %s", pluginName, match) pluginPath, err := filepath.Abs(match) if err != nil { pluginPath = match @@ -284,12 +287,12 @@ func (c *PluginConfig) discoverInstalledComponents(path string) error { for _, checksummer := range binInstallOpts.Checksummers { cs, err := checksummer.GetCacheChecksumOfFile(pluginPath) if err != nil { - log.Printf("[TRACE] GetChecksumOfFile(%q) failed: %v", pluginPath, err) + log.Printf("[TRACE] GetChecksumOfFile(%q) failed: %v\n", pluginPath, err) continue } if err := checksummer.ChecksumFile(cs, pluginPath); err != nil { - log.Printf("[TRACE] ChecksumFile(%q) failed: %v", pluginPath, err) + log.Printf("[TRACE] ChecksumFile(%q) failed: %v\n", pluginPath, err) continue } checksumOk = true diff --git a/packer/plugin_discover_test.go b/packer/plugin_discover_test.go index 6dbe8589b..472f9d6e0 100644 --- a/packer/plugin_discover_test.go +++ b/packer/plugin_discover_test.go @@ -57,25 +57,25 @@ func TestMultiPlugin_describe(t *testing.T) { expectedBuilderName := mockPluginName + "-" + mockBuilderName if !c.Builders.Has(expectedBuilderName) { - t.Fatalf("expected to find builder %q", expectedBuilderName) + t.Errorf("expected to find builder %q", expectedBuilderName) } } for mockProvisionerName := range plugin.Provisioners { expectedProvisionerName := mockPluginName + "-" + mockProvisionerName if !c.Provisioners.Has(expectedProvisionerName) { - t.Fatalf("expected to find builder %q", expectedProvisionerName) + t.Errorf("expected to find builder %q", expectedProvisionerName) } } for mockPostProcessorName := range plugin.PostProcessors { expectedPostProcessorName := mockPluginName + "-" + mockPostProcessorName if !c.PostProcessors.Has(expectedPostProcessorName) { - t.Fatalf("expected to find post-processor %q", expectedPostProcessorName) + t.Errorf("expected to find post-processor %q", expectedPostProcessorName) } } for mockDatasourceName := range plugin.Datasources { expectedDatasourceName := mockPluginName + "-" + mockDatasourceName if !c.DataSources.Has(expectedDatasourceName) { - t.Fatalf("expected to find datasource %q", expectedDatasourceName) + t.Errorf("expected to find datasource %q", expectedDatasourceName) } } } @@ -207,40 +207,20 @@ func TestMultiPlugin_defaultName(t *testing.T) { } } -// no T.Parallel using os.Chdir -func TestMultiPlugin_CWD(t *testing.T) { - createMockPlugins(t, defaultNameMock) - pluginDir := os.Getenv("PACKER_PLUGIN_PATH") - defer os.RemoveAll(pluginDir) - // Unset PACKER_PLUGIN_PATH to test CWD loading - os.Unsetenv("PACKER_PLUGIN_PATH") - if err := os.Chdir(pluginDir); err != nil { - t.Fatalf("failed to change directory to test loading from CWD: %s", err) - } - c := PluginConfig{} - err := c.Discover() - if err != nil { - t.Fatalf("error discovering plugins; %s ; mocks are %#v", err.Error(), defaultNameMock) - } - expectedBuilderNames := []string{"foo-bar", "foo-baz", "foo"} - for _, mockBuilderName := range expectedBuilderNames { - if !c.Builders.Has(mockBuilderName) { - t.Fatalf("expected to find builder %q; builders is %#v", mockBuilderName, c.Builders) - } - } -} - func TestMultiPlugin_IgnoreChecksumFile(t *testing.T) { createMockPlugins(t, defaultNameMock) pluginDir := os.Getenv("PACKER_PLUGIN_PATH") defer os.RemoveAll(pluginDir) - csFile, err := generateMockChecksumFile(filepath.Join(pluginDir, "packer-plugin-foo")) + fooPluginName := fmt.Sprintf("packer-plugin-foo_v1.0.0_x5.0_%s_%s", runtime.GOOS, runtime.GOARCH) + fooPluginPath := filepath.Join(pluginDir, "github.com", "hashicorp", "foo", fooPluginName) + csFile, err := generateMockChecksumFile(fooPluginPath) if err != nil { t.Fatal(err.Error()) } + // Copy plugin contents into checksum file to validate that it is not only skipped but that it never gets loaded - if err := os.Rename(filepath.Join(pluginDir, "packer-plugin-foo"), csFile); err != nil { + if err := os.Rename(fooPluginPath, csFile); err != nil { t.Fatalf("failed to rename plugin bin file to checkfum file needed for test: %s", err) } @@ -395,7 +375,13 @@ func createMockPlugins(t *testing.T, plugins map[string]pluginsdk.Set) { shPath := MustHaveCommand(t, "bash") for name := range plugins { - plugin := path.Join(pluginDir, "packer-plugin-"+name) + pluginName := fmt.Sprintf("packer-plugin-%s_v1.0.0_x5.0_%s_%s", name, runtime.GOOS, runtime.GOARCH) + pluginSubDir := fmt.Sprintf("github.com/hashicorp/%s", name) + err := os.MkdirAll(path.Join(pluginDir, pluginSubDir), 0755) + if err != nil { + t.Fatalf("failed to create plugin hierarchy: %s", err) + } + plugin := path.Join(pluginDir, pluginSubDir, pluginName) t.Logf("creating fake plugin %s", plugin) fileContent := "" fileContent = fmt.Sprintf("#!%s\n", shPath) @@ -405,6 +391,10 @@ func createMockPlugins(t *testing.T, plugins map[string]pluginsdk.Set) { if err := os.WriteFile(plugin, []byte(fileContent), os.ModePerm); err != nil { t.Fatalf("failed to create fake plugin binary: %v", err) } + + if _, err := generateMockChecksumFile(plugin); err != nil { + t.Fatalf("failed to create fake plugin binary checksum file: %v", err) + } } } t.Setenv("PACKER_PLUGIN_PATH", pluginDir)