Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add pkr plugin check cmd from packer core #85

Merged
merged 12 commits into from
Oct 11, 2021
5 changes: 5 additions & 0 deletions cmd/packer-sdc/internal/plugincheck/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
## `plugin-check`

`plugin-check` will check wether a plugin binary seems to work with packer.

Use: `packer-sdc plugin-check packer-plugin-happy-cloud`
111 changes: 111 additions & 0 deletions cmd/packer-sdc/internal/plugincheck/cmd.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
package plugincheck

import (
_ "embed"
"encoding/json"
"fmt"
"log"
"os/exec"
"strings"

"github.com/pkg/errors"
)

var (
//go:embed README.md
readme string
)

type Command struct {
}

func (cmd *Command) Help() string {
return "\n" + readme
}

func (cmd *Command) Run(args []string) int {
if err := cmd.run(args); err != nil {
log.Printf("%v", err)
return 1
}
return 0
}

func (cmd *Command) run(args []string) error {

if len(args) != 1 {
cmd.Help()
return errors.New("plugincheck takes on plugin binary name as argument.\n" +
azr marked this conversation as resolved.
Show resolved Hide resolved
"ex: 'packer-plugin-happycloud'. Check will be run on the binary.")
}

pluginName := args[0]

if isOldPlugin(pluginName) {
fmt.Printf("\n[WARNING] Plugin is named with old prefix `packer-[builder|provisioner|post-processor]-{name})`. " +
"These will be detected but Packer cannot install them automatically. " +
"The plugin must be a multi-component plugin named packer-plugin-{name} to be installable through the `packer init` command.\n" +
"See docs at: https://www.packer.io/docs/plugins.\n")
return nil
}

if err := checkPluginName(pluginName); err != nil {
return err
}

output, err := exec.Command(pluginName, "describe").Output()
if err != nil {
return errors.Wrap(err, "failed to describe plugin")
nywilken marked this conversation as resolved.
Show resolved Hide resolved
}

desc := pluginDescription{}
err = json.Unmarshal(output, &desc)
if err != nil {
return errors.Wrap(err, "failed to json.Unmarshal plugin description")
}
if len(desc.Version) == 0 {
return errors.New("Version needs to be set")
}
if len(desc.SDKVersion) == 0 {
return errors.New("SDKVersion needs to be set")
}
if len(desc.APIVersion) == 0 {
return errors.New("APIVersion needs to be set")
}

if len(desc.Builders) == 0 && len(desc.PostProcessors) == 0 && len(desc.Datasources) == 0 {
return errors.New("this plugin defines no component.")
}
return nil
}

type pluginDescription struct {
Version string `json:"version"`
SDKVersion string `json:"sdk_version"`
APIVersion string `json:"api_version"`
Builders []string `json:"builders"`
PostProcessors []string `json:"post_processors"`
Datasources []string `json:"datasources"`
}

func isOldPlugin(pluginName string) bool {
return strings.HasPrefix(pluginName, "packer-builder-") ||
strings.HasPrefix(pluginName, "packer-provisioner-") ||
strings.HasPrefix(pluginName, "packer-post-processor-")
}

// checkPluginName checks for the possible valid names for a plugin,
// packer-plugin-* or packer-[builder|provisioner|post-processor]-*. If the name
// is prefixed with `packer-[builder|provisioner|post-processor]-`, packer won't
// be able to install it, therefore a WARNING will be shown.
func checkPluginName(name string) error {
if strings.HasPrefix(name, "packer-plugin-") {
return nil
}

return fmt.Errorf("plugin name is not valid")
}

func (cmd *Command) Synopsis() string {
return "Tell wether a plugin release looks valid for Packer."
}
4 changes: 4 additions & 0 deletions cmd/packer-sdc/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"os"

mapstructure_to_hcl2 "github.com/hashicorp/packer-plugin-sdk/cmd/packer-sdc/internal/mapstructure-to-hcl2"
"github.com/hashicorp/packer-plugin-sdk/cmd/packer-sdc/internal/plugincheck"
"github.com/hashicorp/packer-plugin-sdk/cmd/packer-sdc/internal/renderdocs"
struct_markdown "github.com/hashicorp/packer-plugin-sdk/cmd/packer-sdc/internal/struct-markdown"
"github.com/hashicorp/packer-plugin-sdk/version"
Expand Down Expand Up @@ -37,6 +38,9 @@ func main() {
"renderdocs": func() (cli.Command, error) {
return &renderdocs.Command{}, nil
},
"plugin-check": func() (cli.Command, error) {
return &plugincheck.Command{}, nil
},
}

exitStatus, err := c.Run()
Expand Down