packer/command/plugins_remove.go
Lucas Bajolet d47cbe7f48 command: remove SHA256SUM file on plugin removal
When a user invokes `packer plugins remove', the plugin binary gets
removed, but not the corresponding SHA256SUM file.

This patch changes this so that when a binary is removed, so is its
SHA256SUM file.
2023-10-26 12:49:36 -04:00

108 lines
2.6 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package command
import (
"context"
"crypto/sha256"
"fmt"
"os"
"runtime"
"strings"
"github.com/hashicorp/go-version"
"github.com/hashicorp/packer/hcl2template/addrs"
plugingetter "github.com/hashicorp/packer/packer/plugin-getter"
"github.com/mitchellh/cli"
)
type PluginsRemoveCommand struct {
Meta
}
func (c *PluginsRemoveCommand) Synopsis() string {
return "Remove Packer plugins [matching a version]"
}
func (c *PluginsRemoveCommand) Help() string {
helpText := `
Usage: packer plugins remove <plugin> [<version constraint>]
This command will remove all Packer plugins matching the version constraint
for the current OS and architecture.
When the version is omitted all installed versions will be removed.
Ex: packer plugins remove github.com/hashicorp/happycloud v1.2.3
`
return strings.TrimSpace(helpText)
}
func (c *PluginsRemoveCommand) Run(args []string) int {
ctx, cleanup := handleTermInterrupt(c.Ui)
defer cleanup()
return c.RunContext(ctx, args)
}
func (c *PluginsRemoveCommand) RunContext(buildCtx context.Context, args []string) int {
if len(args) < 1 || len(args) > 2 {
return cli.RunResultHelp
}
opts := plugingetter.ListInstallationsOptions{
FromFolders: c.Meta.CoreConfig.Components.PluginConfig.KnownPluginFolders,
BinaryInstallationOptions: plugingetter.BinaryInstallationOptions{
OS: runtime.GOOS,
ARCH: runtime.GOARCH,
Checksummers: []plugingetter.Checksummer{
{Type: "sha256", Hash: sha256.New()},
},
},
}
if runtime.GOOS == "windows" && opts.Ext == "" {
opts.BinaryInstallationOptions.Ext = ".exe"
}
plugin, diags := addrs.ParsePluginSourceString(args[0])
if diags.HasErrors() {
c.Ui.Error(diags.Error())
return 1
}
// a plugin requirement that matches them all
pluginRequirement := plugingetter.Requirement{
Identifier: plugin,
}
if len(args) > 1 {
constraints, err := version.NewConstraint(args[1])
if err != nil {
c.Ui.Error(err.Error())
return 1
}
pluginRequirement.VersionConstraints = constraints
}
installations, err := pluginRequirement.ListInstallations(opts)
if err != nil {
c.Ui.Error(err.Error())
return 1
}
for _, installation := range installations {
if err := os.Remove(installation.BinaryPath); err != nil {
c.Ui.Error(err.Error())
return 1
}
shasumFile := fmt.Sprintf("%s_SHA256SUM", installation.BinaryPath)
if err := os.Remove(shasumFile); err != nil {
c.Ui.Error(fmt.Sprintf("failed to remove %s: %s", shasumFile, err))
c.Ui.Error("You may need to remove it manually")
}
c.Ui.Message(installation.BinaryPath)
}
return 0
}