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.
This commit is contained in:
Lucas Bajolet 2024-01-15 14:41:25 -05:00 committed by Lucas Bajolet
parent 664700d0c0
commit 4b00a81bf3
10 changed files with 150 additions and 275 deletions

View file

@ -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,

View file

@ -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

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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 {

View file

@ -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",

View file

@ -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

View file

@ -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)