diff --git a/command/cli.go b/command/cli.go index 4ad80440f0e..2dfc57dbd0d 100644 --- a/command/cli.go +++ b/command/cli.go @@ -104,6 +104,7 @@ type BuildArgs struct { func (ia *InitArgs) AddFlagSets(flags *flag.FlagSet) { flags.BoolVar(&ia.Upgrade, "upgrade", false, "upgrade any present plugin to the highest allowed version.") + flags.BoolVar(&ia.Force, "force", false, "force installation of a plugin, even if already installed") ia.MetaArgs.AddFlagSets(flags) } @@ -112,6 +113,7 @@ func (ia *InitArgs) AddFlagSets(flags *flag.FlagSet) { type InitArgs struct { MetaArgs Upgrade bool + Force bool } // PluginsRequiredArgs represents a parsed cli line for a `packer plugins required ` diff --git a/command/init.go b/command/init.go index 71332d57d25..68b2cbe469a 100644 --- a/command/init.go +++ b/command/init.go @@ -130,6 +130,7 @@ for more info.`) InFolders: opts.FromFolders, BinaryInstallationOptions: opts.BinaryInstallationOptions, Getters: getters, + Force: cla.Force, }) if err != nil { c.Ui.Error(fmt.Sprintf("Failed getting the %q plugin:", pluginRequirement.Identifier)) @@ -163,6 +164,8 @@ Options: version, if there is a new higher one. Note that this still takes into consideration the version constraint of the config. + -force Forces installation of plugins, even if already + installed. ` return strings.TrimSpace(helpText) diff --git a/command/plugins_install.go b/command/plugins_install.go index 16c21154de7..1ecb7cdf262 100644 --- a/command/plugins_install.go +++ b/command/plugins_install.go @@ -50,6 +50,7 @@ Options: installs the plugin where a normal invocation would, but will not try to download it from a web server, but instead directly install the binary for Packer to be able to load it later on. + - force: forces installation of a plugin, even if it is already there. ` return strings.TrimSpace(helpText) @@ -72,10 +73,12 @@ type PluginsInstallArgs struct { PluginName string PluginPath string Version string + Force bool } func (pa *PluginsInstallArgs) AddFlagSets(flags *flag.FlagSet) { flags.StringVar(&pa.PluginPath, "path", "", "install the plugin from a specific path") + flags.BoolVar(&pa.Force, "force", false, "force installation of a plugin, even if already installed") pa.MetaArgs.AddFlagSets(flags) } @@ -168,6 +171,7 @@ func (c *PluginsInstallCommand) RunContext(buildCtx context.Context, args *Plugi InFolders: opts.FromFolders, BinaryInstallationOptions: opts.BinaryInstallationOptions, Getters: getters, + Force: args.Force, }) if err != nil { diff --git a/packer/plugin-getter/plugins.go b/packer/plugin-getter/plugins.go index f6ca5c4abfe..590c9672d27 100644 --- a/packer/plugin-getter/plugins.go +++ b/packer/plugin-getter/plugins.go @@ -244,6 +244,9 @@ type InstallOptions struct { // folder of this list. InFolders []string + // Forces installation of the plugin, even if already installed. + Force bool + BinaryInstallationOptions } @@ -582,7 +585,7 @@ func (pr *Requirement) InstallLatest(opts InstallOptions) (*Installation, error) 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 { + 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 } diff --git a/packer/plugin-getter/plugins_test.go b/packer/plugin-getter/plugins_test.go index dfb28767067..513f2c4993b 100644 --- a/packer/plugin-getter/plugins_test.go +++ b/packer/plugin-getter/plugins_test.go @@ -349,6 +349,7 @@ func TestRequirement_InstallLatest(t *testing.T) { pluginFolderOne, pluginFolderTwo, }, + false, BinaryInstallationOptions{ APIVersionMajor: "5", APIVersionMinor: "0", OS: "darwin", ARCH: "amd64", @@ -385,6 +386,7 @@ func TestRequirement_InstallLatest(t *testing.T) { pluginFolderOne, pluginFolderTwo, }, + false, BinaryInstallationOptions{ APIVersionMajor: "5", APIVersionMinor: "1", OS: "darwin", ARCH: "amd64", @@ -430,6 +432,7 @@ func TestRequirement_InstallLatest(t *testing.T) { pluginFolderOne, pluginFolderTwo, }, + false, BinaryInstallationOptions{ APIVersionMajor: "5", APIVersionMinor: "0", OS: "darwin", ARCH: "amd64", @@ -477,6 +480,7 @@ func TestRequirement_InstallLatest(t *testing.T) { pluginFolderOne, pluginFolderTwo, }, + false, BinaryInstallationOptions{ APIVersionMajor: "6", APIVersionMinor: "1", OS: "darwin", ARCH: "amd64", @@ -527,6 +531,7 @@ func TestRequirement_InstallLatest(t *testing.T) { pluginFolderOne, pluginFolderTwo, }, + false, BinaryInstallationOptions{ APIVersionMajor: "6", APIVersionMinor: "1", OS: "darwin", ARCH: "amd64", @@ -577,6 +582,7 @@ func TestRequirement_InstallLatest(t *testing.T) { pluginFolderOne, pluginFolderTwo, }, + false, BinaryInstallationOptions{ APIVersionMajor: "6", APIVersionMinor: "1", OS: "linux", ARCH: "amd64", @@ -621,6 +627,7 @@ func TestRequirement_InstallLatest(t *testing.T) { pluginFolderOne, pluginFolderTwo, }, + false, BinaryInstallationOptions{ APIVersionMajor: "6", APIVersionMinor: "1", OS: "darwin", ARCH: "amd64", @@ -662,6 +669,7 @@ func TestRequirement_InstallLatest(t *testing.T) { []string{ pluginFolderWrongChecksums, }, + false, BinaryInstallationOptions{ APIVersionMajor: "6", APIVersionMinor: "1", OS: "darwin", ARCH: "amd64",