mirror of
https://github.com/hashicorp/packer.git
synced 2026-09-28 02:34:02 -04:00
backport of commit 38f95d30d8
This commit is contained in:
@@ -0,0 +1,181 @@
|
||||
package plugin
|
||||
|
||||
import (
|
||||
_ "embed"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/go-multierror"
|
||||
amazonacc "github.com/hashicorp/packer-plugin-amazon/builder/ebs/acceptance"
|
||||
"github.com/hashicorp/packer-plugin-sdk/acctest"
|
||||
"github.com/hashicorp/packer/hcl2template/addrs"
|
||||
)
|
||||
|
||||
//go:embed test-fixtures/basic_amazon_bundled.pkr.hcl
|
||||
var basicAmazonBundledEbsTemplate string
|
||||
|
||||
func TestAccBuildBundledPlugins(t *testing.T) {
|
||||
plugin := addrs.Plugin{
|
||||
Hostname: "github.com",
|
||||
Namespace: "hashicorp",
|
||||
Type: "amazon",
|
||||
}
|
||||
testCase := &acctest.PluginTestCase{
|
||||
Name: "amazon-ebs_bundled_test",
|
||||
Setup: func() error {
|
||||
return cleanupPluginInstallation(plugin)
|
||||
},
|
||||
Teardown: func() error {
|
||||
helper := amazonacc.AMIHelper{
|
||||
Region: "us-east-1",
|
||||
Name: "packer-plugin-bundled-amazon-ebs-test",
|
||||
}
|
||||
return helper.CleanUpAmi()
|
||||
},
|
||||
Template: basicAmazonBundledEbsTemplate,
|
||||
Type: "amazon-ebs",
|
||||
Init: false,
|
||||
Check: func(buildCommand *exec.Cmd, logfile string) error {
|
||||
if buildCommand.ProcessState != nil {
|
||||
if buildCommand.ProcessState.ExitCode() != 0 {
|
||||
return fmt.Errorf("Bad exit code. Logfile: %s", logfile)
|
||||
}
|
||||
}
|
||||
|
||||
rawLogs, err := os.ReadFile(logfile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read logs: %s", err)
|
||||
}
|
||||
|
||||
var errs error
|
||||
|
||||
logs := string(rawLogs)
|
||||
|
||||
if !strings.Contains(logs, "Warning: Bundled plugins used") {
|
||||
errs = multierror.Append(errs, errors.New("expected warning about bundled plugins used, did not find it"))
|
||||
}
|
||||
|
||||
if !strings.Contains(logs, "Then run 'packer init' to manage installation of the plugins") {
|
||||
errs = multierror.Append(errs, errors.New("expected suggestion about packer init in logs, did not find it."))
|
||||
}
|
||||
|
||||
return errs
|
||||
},
|
||||
}
|
||||
|
||||
acctest.TestPlugin(t, testCase)
|
||||
}
|
||||
|
||||
//go:embed test-fixtures/basic_amazon_with_required_plugins.pkr.hcl
|
||||
var basicAmazonRequiredPluginEbsTemplate string
|
||||
|
||||
func TestAccBuildBundledPluginsWithRequiredPlugins(t *testing.T) {
|
||||
plugin := addrs.Plugin{
|
||||
Hostname: "github.com",
|
||||
Namespace: "hashicorp",
|
||||
Type: "amazon",
|
||||
}
|
||||
testCase := &acctest.PluginTestCase{
|
||||
Name: "amazon-ebs_with_required_plugins_test",
|
||||
Setup: func() error {
|
||||
return cleanupPluginInstallation(plugin)
|
||||
},
|
||||
Teardown: func() error {
|
||||
helper := amazonacc.AMIHelper{
|
||||
Region: "us-east-1",
|
||||
Name: "packer-plugin-required-plugin-amazon-ebs-test",
|
||||
}
|
||||
return helper.CleanUpAmi()
|
||||
},
|
||||
Template: basicAmazonRequiredPluginEbsTemplate,
|
||||
Type: "amazon-ebs",
|
||||
Init: false,
|
||||
Check: func(buildCommand *exec.Cmd, logfile string) error {
|
||||
if buildCommand.ProcessState != nil {
|
||||
if buildCommand.ProcessState.ExitCode() != 1 {
|
||||
return fmt.Errorf("Bad exit code. Logfile: %s", logfile)
|
||||
}
|
||||
}
|
||||
|
||||
rawLogs, err := os.ReadFile(logfile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read logs: %s", err)
|
||||
}
|
||||
|
||||
var errs error
|
||||
|
||||
logs := string(rawLogs)
|
||||
|
||||
if strings.Contains(logs, "Warning: Bundled plugins used") {
|
||||
errs = multierror.Append(errs, errors.New("did not expect warning about bundled plugins used"))
|
||||
}
|
||||
|
||||
if !strings.Contains(logs, "Missing plugins") {
|
||||
errs = multierror.Append(errs, errors.New("expected error about plugins required and not installed, did not find it"))
|
||||
}
|
||||
|
||||
return errs
|
||||
},
|
||||
}
|
||||
|
||||
acctest.TestPlugin(t, testCase)
|
||||
}
|
||||
|
||||
//go:embed test-fixtures/basic_amazon_bundled.json
|
||||
var basicAmazonBundledEbsTemplateJSON string
|
||||
|
||||
func TestAccBuildBundledPluginsJSON(t *testing.T) {
|
||||
plugin := addrs.Plugin{
|
||||
Hostname: "github.com",
|
||||
Namespace: "hashicorp",
|
||||
Type: "amazon",
|
||||
}
|
||||
testCase := &acctest.PluginTestCase{
|
||||
Name: "amazon-ebs_bundled_test_json",
|
||||
Setup: func() error {
|
||||
return cleanupPluginInstallation(plugin)
|
||||
},
|
||||
Teardown: func() error {
|
||||
helper := amazonacc.AMIHelper{
|
||||
Region: "us-east-1",
|
||||
Name: "packer-plugin-bundled-amazon-ebs-test-json",
|
||||
}
|
||||
return helper.CleanUpAmi()
|
||||
},
|
||||
Template: basicAmazonBundledEbsTemplateJSON,
|
||||
Type: "amazon-ebs",
|
||||
Init: false,
|
||||
Check: func(buildCommand *exec.Cmd, logfile string) error {
|
||||
if buildCommand.ProcessState != nil {
|
||||
if buildCommand.ProcessState.ExitCode() != 0 {
|
||||
return fmt.Errorf("Bad exit code. Logfile: %s", logfile)
|
||||
}
|
||||
}
|
||||
|
||||
rawLogs, err := os.ReadFile(logfile)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to read logs: %s", err)
|
||||
}
|
||||
|
||||
var errs error
|
||||
|
||||
logs := string(rawLogs)
|
||||
|
||||
if !strings.Contains(logs, "Warning: Bundled plugins used") {
|
||||
errs = multierror.Append(errs, errors.New("expected warning about bundled plugins, did not find it."))
|
||||
}
|
||||
|
||||
if !strings.Contains(logs, "plugins with the 'packer plugins install' command") {
|
||||
errs = multierror.Append(errs, errors.New("expected suggestion about packer plugins install in logs, did not find it."))
|
||||
}
|
||||
|
||||
return errs
|
||||
},
|
||||
}
|
||||
|
||||
acctest.TestPlugin(t, testCase)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"builders": [{
|
||||
"type": "amazon-ebs",
|
||||
"region": "us-east-1",
|
||||
"instance_type": "m3.medium",
|
||||
"source_ami": "ami-76b2a71e",
|
||||
"ssh_username": "ubuntu",
|
||||
"ami_name": "packer-plugin-bundled-amazon-ebs-test-json"
|
||||
}]
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
source "amazon-ebs" "basic-test" {
|
||||
region = "us-east-1"
|
||||
instance_type = "m3.medium"
|
||||
source_ami = "ami-76b2a71e"
|
||||
ssh_username = "ubuntu"
|
||||
ami_name = "packer-plugin-bundled-amazon-ebs-test"
|
||||
}
|
||||
|
||||
build {
|
||||
sources = ["source.amazon-ebs.basic-test"]
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
packer {
|
||||
required_plugins {
|
||||
amazon = {
|
||||
source = "github.com/hashicorp/amazon",
|
||||
version = "~> 1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
source "amazon-ebs" "basic-test" {
|
||||
region = "us-east-1"
|
||||
instance_type = "m3.medium"
|
||||
source_ami = "ami-76b2a71e"
|
||||
ssh_username = "ubuntu"
|
||||
ami_name = "packer-plugin-bundled-amazon-ebs-test"
|
||||
}
|
||||
|
||||
build {
|
||||
sources = ["source.amazon-ebs.basic-test"]
|
||||
}
|
||||
+9
-1
@@ -87,7 +87,15 @@ func (c *BuildCommand) RunContext(buildCtx context.Context, cla *BuildArgs) int
|
||||
return ret
|
||||
}
|
||||
|
||||
diags := packerStarter.Initialize(packer.InitializeOptions{})
|
||||
diags := packerStarter.DetectPluginBinaries()
|
||||
ret = writeDiags(c.Ui, nil, diags)
|
||||
if ret != 0 {
|
||||
return ret
|
||||
}
|
||||
|
||||
diags = packerStarter.Initialize(packer.InitializeOptions{})
|
||||
bundledDiags := c.DetectBundledPlugins(packerStarter)
|
||||
diags = append(bundledDiags, diags...)
|
||||
ret = writeDiags(c.Ui, nil, diags)
|
||||
if ret != 0 {
|
||||
return ret
|
||||
|
||||
+175
@@ -9,7 +9,9 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/hcl/v2"
|
||||
"github.com/hashicorp/hcl/v2/hclparse"
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
"github.com/hashicorp/packer-plugin-sdk/template"
|
||||
@@ -179,3 +181,176 @@ func (m *Meta) GetConfigFromJSON(cla *MetaArgs) (packer.Handler, int) {
|
||||
}
|
||||
return core, ret
|
||||
}
|
||||
|
||||
func (m *Meta) DetectBundledPlugins(handler packer.Handler) hcl.Diagnostics {
|
||||
var plugins []string
|
||||
|
||||
switch h := handler.(type) {
|
||||
case *packer.Core:
|
||||
plugins = m.detectBundledPluginsJSON(h)
|
||||
case *hcl2template.PackerConfig:
|
||||
plugins = m.detectBundledPluginsHCL2(handler.(*hcl2template.PackerConfig))
|
||||
}
|
||||
|
||||
if len(plugins) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
buf := &strings.Builder{}
|
||||
buf.WriteString("This template relies on the use of plugins bundled into the Packer binary.\n")
|
||||
buf.WriteString("The practice of bundling external plugins into Packer will be removed in an upcoming version.\n\n")
|
||||
switch h := handler.(type) {
|
||||
case *packer.Core:
|
||||
buf.WriteString("To remove this warning and ensure builds keep working you can install these external plugins with the 'packer plugins install' command\n\n")
|
||||
|
||||
for _, plugin := range plugins {
|
||||
fmt.Fprintf(buf, "* packer plugins install %s\n", plugin)
|
||||
}
|
||||
|
||||
buf.WriteString("\nAlternatively, if you upgrade your templates to HCL2, you can use 'packer init' with a 'required_plugins' block to automatically install external plugins.\n\n")
|
||||
fmt.Fprintf(buf, "You can try HCL2 by running 'packer hcl2_upgrade %s'", h.Template.Path)
|
||||
case *hcl2template.PackerConfig:
|
||||
buf.WriteString("To remove this warning, add the following section to your template:\n")
|
||||
buf.WriteString(m.fixRequiredPlugins(h))
|
||||
buf.WriteString("\nThen run 'packer init' to manage installation of the plugins")
|
||||
}
|
||||
|
||||
return hcl.Diagnostics{
|
||||
&hcl.Diagnostic{
|
||||
Severity: hcl.DiagWarning,
|
||||
Summary: "Bundled plugins used",
|
||||
Detail: buf.String(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Meta) detectBundledPluginsJSON(core *packer.Core) []string {
|
||||
bundledPlugins := map[string]struct{}{}
|
||||
|
||||
tmpl := core.Template
|
||||
if tmpl == nil {
|
||||
panic("No template parsed. This is a Packer bug which should be reported, please open an issue on the project's issue tracker.")
|
||||
}
|
||||
|
||||
for _, b := range tmpl.Builders {
|
||||
builderType := fmt.Sprintf("packer-builder-%s", b.Type)
|
||||
if bundledStatus[builderType] {
|
||||
bundledPlugins[builderType] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
for _, p := range tmpl.Provisioners {
|
||||
provisionerType := fmt.Sprintf("packer-provisioner-%s", p.Type)
|
||||
if bundledStatus[provisionerType] {
|
||||
bundledPlugins[provisionerType] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
for _, pps := range tmpl.PostProcessors {
|
||||
for _, pp := range pps {
|
||||
postProcessorType := fmt.Sprintf("packer-post-processor-%s", pp.Type)
|
||||
if bundledStatus[postProcessorType] {
|
||||
bundledPlugins[postProcessorType] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return compileBundledPluginList(bundledPlugins)
|
||||
}
|
||||
|
||||
var knownPluginPrefixes = map[string]string{
|
||||
"amazon": "github.com/hashicorp/amazon",
|
||||
"ansible": "github.com/hashicorp/ansible",
|
||||
"azure": "github.com/hashicorp/azure",
|
||||
"docker": "github.com/hashicorp/docker",
|
||||
"googlecompute": "github.com/hashicorp/googlecompute",
|
||||
"qemu": "github.com/hashicorp/qemu",
|
||||
"vagrant": "github.com/hashicorp/vagrant",
|
||||
"vmware": "github.com/hashicorp/vmware",
|
||||
"vsphere": "github.com/hashicorp/vsphere",
|
||||
}
|
||||
|
||||
func (m *Meta) fixRequiredPlugins(config *hcl2template.PackerConfig) string {
|
||||
plugins := map[string]struct{}{}
|
||||
|
||||
for _, b := range config.Builds {
|
||||
for _, b := range b.Sources {
|
||||
for prefix, plugin := range knownPluginPrefixes {
|
||||
if strings.HasPrefix(b.Type, prefix) {
|
||||
plugins[plugin] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, p := range b.ProvisionerBlocks {
|
||||
for prefix, plugin := range knownPluginPrefixes {
|
||||
if strings.HasPrefix(p.PType, prefix) {
|
||||
plugins[plugin] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, pps := range b.PostProcessorsLists {
|
||||
for _, pp := range pps {
|
||||
for prefix, plugin := range knownPluginPrefixes {
|
||||
if strings.HasPrefix(pp.PType, prefix) {
|
||||
plugins[plugin] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, ds := range config.Datasources {
|
||||
for prefix, plugin := range knownPluginPrefixes {
|
||||
if strings.HasPrefix(ds.Type, prefix) {
|
||||
plugins[plugin] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
retPlugins := make([]string, 0, len(plugins))
|
||||
for plugin := range plugins {
|
||||
retPlugins = append(retPlugins, plugin)
|
||||
}
|
||||
|
||||
return generateRequiredPluginsBlock(retPlugins)
|
||||
}
|
||||
|
||||
func (m *Meta) detectBundledPluginsHCL2(config *hcl2template.PackerConfig) []string {
|
||||
bundledPlugins := map[string]struct{}{}
|
||||
|
||||
for _, b := range config.Builds {
|
||||
for _, src := range b.Sources {
|
||||
builderType := fmt.Sprintf("packer-builder-%s", src.Type)
|
||||
if bundledStatus[builderType] {
|
||||
bundledPlugins[builderType] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
for _, p := range b.ProvisionerBlocks {
|
||||
provisionerType := fmt.Sprintf("packer-provisioner-%s", p.PType)
|
||||
if bundledStatus[provisionerType] {
|
||||
bundledPlugins[provisionerType] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
for _, pps := range b.PostProcessorsLists {
|
||||
for _, pp := range pps {
|
||||
postProcessorType := fmt.Sprintf("packer-post-processor-%s", pp.PType)
|
||||
if bundledStatus[postProcessorType] {
|
||||
bundledPlugins[postProcessorType] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, ds := range config.Datasources {
|
||||
dsType := fmt.Sprintf("packer-datasource-%s", ds.Type)
|
||||
if bundledStatus[dsType] {
|
||||
bundledPlugins[dsType] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
return compileBundledPluginList(bundledPlugins)
|
||||
}
|
||||
|
||||
+9
-1
@@ -65,9 +65,17 @@ func (c *ValidateCommand) RunContext(ctx context.Context, cla *ValidateArgs) int
|
||||
return 0
|
||||
}
|
||||
|
||||
diags := packerStarter.Initialize(packer.InitializeOptions{
|
||||
diags := packerStarter.DetectPluginBinaries()
|
||||
ret = writeDiags(c.Ui, nil, diags)
|
||||
if ret != 0 {
|
||||
return ret
|
||||
}
|
||||
|
||||
diags = packerStarter.Initialize(packer.InitializeOptions{
|
||||
SkipDatasourcesExecution: !cla.EvaluateDatasources,
|
||||
})
|
||||
bundledDiags := c.DetectBundledPlugins(packerStarter)
|
||||
diags = append(bundledDiags, diags...)
|
||||
ret = writeDiags(c.Ui, nil, diags)
|
||||
if ret != 0 {
|
||||
return ret
|
||||
|
||||
@@ -4,6 +4,10 @@
|
||||
package command
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"strings"
|
||||
|
||||
packersdk "github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
|
||||
// Previously core-bundled components, split into their own plugins but
|
||||
@@ -102,6 +106,170 @@ var VendoredPostProcessors = map[string]packersdk.PostProcessor{
|
||||
"vsphere": new(vspherepostprocessor.PostProcessor),
|
||||
}
|
||||
|
||||
// bundledStatus is used to know if one of the bundled components is loaded from
|
||||
// an external plugin, or from the bundled plugins.
|
||||
//
|
||||
// We keep track of this to produce a warning if a user relies on one
|
||||
// such plugin, as they will be removed in a later version of Packer.
|
||||
var bundledStatus = map[string]bool{
|
||||
"packer-builder-amazon-ebs": false,
|
||||
"packer-builder-amazon-chroot": false,
|
||||
"packer-builder-amazon-ebssurrogate": false,
|
||||
"packer-builder-amazon-ebsvolume": false,
|
||||
"packer-builder-amazon-instance": false,
|
||||
"packer-post-processor-amazon-import": false,
|
||||
"packer-datasource-amazon-ami": false,
|
||||
"packer-datasource-amazon-secretsmanager": false,
|
||||
|
||||
"packer-provisioner-ansible": false,
|
||||
"packer-provisioner-ansible-local": false,
|
||||
|
||||
"packer-provisioner-azure-dtlartifact": false,
|
||||
"packer-builder-azure-arm": false,
|
||||
"packer-builder-azure-chroot": false,
|
||||
"packer-builder-azure-dtl": false,
|
||||
|
||||
"packer-builder-docker": false,
|
||||
"packer-post-processor-docker-import": false,
|
||||
"packer-post-processor-docker-push": false,
|
||||
"packer-post-processor-docker-save": false,
|
||||
"packer-post-processor-docker-tag": false,
|
||||
|
||||
"packer-builder-googlecompute": false,
|
||||
"packer-post-processor-googlecompute-export": false,
|
||||
"packer-post-processor-googlecompute-import": false,
|
||||
|
||||
"packer-builder-qemu": false,
|
||||
|
||||
"packer-builder-vagrant": false,
|
||||
"packer-post-processor-vagrant": false,
|
||||
"packer-post-processor-vagrant-cloud": false,
|
||||
|
||||
"packer-builder-virtualbox-iso": false,
|
||||
"packer-builder-virtualbox-ovf": false,
|
||||
"packer-builder-virtualbox-vm": false,
|
||||
|
||||
"packer-builder-vmware-iso": false,
|
||||
"packer-builder-vmware-vmx": false,
|
||||
|
||||
"packer-builder-vsphere-clone": false,
|
||||
"packer-builder-vsphere-iso": false,
|
||||
"packer-post-processor-vsphere-template": false,
|
||||
"packer-post-processor-vsphere": false,
|
||||
}
|
||||
|
||||
// TrackBundledPlugin marks a component as loaded from Packer's bundled plugins
|
||||
// instead of from an externally loaded plugin.
|
||||
//
|
||||
// NOTE: `pluginName' must be in the format `packer-<type>-<component_name>'
|
||||
func TrackBundledPlugin(pluginName string) {
|
||||
_, exists := bundledStatus[pluginName]
|
||||
if !exists {
|
||||
return
|
||||
}
|
||||
|
||||
bundledStatus[pluginName] = true
|
||||
}
|
||||
|
||||
var componentPluginMap = map[string]string{
|
||||
"packer-builder-amazon-ebs": "github.com/hashicorp/amazon",
|
||||
"packer-builder-amazon-chroot": "github.com/hashicorp/amazon",
|
||||
"packer-builder-amazon-ebssurrogate": "github.com/hashicorp/amazon",
|
||||
"packer-builder-amazon-ebsvolume": "github.com/hashicorp/amazon",
|
||||
"packer-builder-amazon-instance": "github.com/hashicorp/amazon",
|
||||
"packer-post-processor-amazon-import": "github.com/hashicorp/amazon",
|
||||
"packer-datasource-amazon-ami": "github.com/hashicorp/amazon",
|
||||
"packer-datasource-amazon-secretsmanager": "github.com/hashicorp/amazon",
|
||||
|
||||
"packer-provisioner-ansible": "github.com/hashicorp/ansible",
|
||||
"packer-provisioner-ansible-local": "github.com/hashicorp/ansible",
|
||||
|
||||
"packer-provisioner-azure-dtlartifact": "github.com/hashicorp/azure",
|
||||
"packer-builder-azure-arm": "github.com/hashicorp/azure",
|
||||
"packer-builder-azure-chroot": "github.com/hashicorp/azure",
|
||||
"packer-builder-azure-dtl": "github.com/hashicorp/azure",
|
||||
|
||||
"packer-builder-docker": "github.com/hashicorp/docker",
|
||||
"packer-post-processor-docker-import": "github.com/hashicorp/docker",
|
||||
"packer-post-processor-docker-push": "github.com/hashicorp/docker",
|
||||
"packer-post-processor-docker-save": "github.com/hashicorp/docker",
|
||||
"packer-post-processor-docker-tag": "github.com/hashicorp/docker",
|
||||
|
||||
"packer-builder-googlecompute": "github.com/hashicorp/googlecompute",
|
||||
"packer-post-processor-googlecompute-export": "github.com/hashicorp/googlecompute",
|
||||
"packer-post-processor-googlecompute-import": "github.com/hashicorp/googlecompute",
|
||||
|
||||
"packer-builder-qemu": "github.com/hashicorp/qemu",
|
||||
|
||||
"packer-builder-vagrant": "github.com/hashicorp/vagrant",
|
||||
"packer-post-processor-vagrant": "github.com/hashicorp/vagrant",
|
||||
"packer-post-processor-vagrant-cloud": "github.com/hashicorp/vagrant",
|
||||
|
||||
"packer-builder-virtualbox-iso": "github.com/hashicorp/virtualbox",
|
||||
"packer-builder-virtualbox-ovf": "github.com/hashicorp/virtualbox",
|
||||
"packer-builder-virtualbox-vm": "github.com/hashicorp/virtualbox",
|
||||
|
||||
"packer-builder-vmware-iso": "github.com/hashicorp/vmware",
|
||||
"packer-builder-vmware-vmx": "github.com/hashicorp/vmware",
|
||||
|
||||
"packer-builder-vsphere-clone": "github.com/hashicorp/vsphere",
|
||||
"packer-builder-vsphere-iso": "github.com/hashicorp/vsphere",
|
||||
"packer-post-processor-vsphere-template": "github.com/hashicorp/vsphere",
|
||||
"packer-post-processor-vsphere": "github.com/hashicorp/vsphere",
|
||||
}
|
||||
|
||||
// compileBundledPluginList returns a list of plugins to import in a config
|
||||
//
|
||||
// This only works on bundled plugins and serves as a way to inform users that
|
||||
// they should not rely on a bundled plugin anymore, but give them recommendations
|
||||
// on how to manage those plugins instead.
|
||||
func compileBundledPluginList(componentMap map[string]struct{}) []string {
|
||||
plugins := map[string]struct{}{}
|
||||
for component := range componentMap {
|
||||
plugin, ok := componentPluginMap[component]
|
||||
if !ok {
|
||||
log.Printf("Unknown bundled plugin component: %q", component)
|
||||
continue
|
||||
}
|
||||
|
||||
plugins[plugin] = struct{}{}
|
||||
}
|
||||
|
||||
pluginList := make([]string, 0, len(plugins))
|
||||
for plugin := range plugins {
|
||||
pluginList = append(pluginList, plugin)
|
||||
}
|
||||
|
||||
return pluginList
|
||||
}
|
||||
|
||||
func generateRequiredPluginsBlock(plugins []string) string {
|
||||
if len(plugins) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
buf := &strings.Builder{}
|
||||
buf.WriteString(`
|
||||
packer {
|
||||
required_plugins {`)
|
||||
|
||||
for _, plugin := range plugins {
|
||||
pluginName := strings.Replace(plugin, "github.com/hashicorp/", "", 1)
|
||||
fmt.Fprintf(buf, `
|
||||
%s = {
|
||||
source = %q
|
||||
version = "~> 1"
|
||||
}`, pluginName, plugin)
|
||||
}
|
||||
|
||||
buf.WriteString(`
|
||||
}
|
||||
}
|
||||
`)
|
||||
|
||||
return buf.String()
|
||||
}
|
||||
|
||||
// Upon init lets load up any plugins that were vendored manually into the default
|
||||
// set of plugins.
|
||||
func init() {
|
||||
|
||||
@@ -153,6 +153,7 @@ func (c *config) discoverInternalComponents() error {
|
||||
for builder := range command.Builders {
|
||||
builder := builder
|
||||
if !c.Plugins.Builders.Has(builder) {
|
||||
command.TrackBundledPlugin(fmt.Sprintf("packer-builder-%s", builder))
|
||||
bin := fmt.Sprintf("%s%splugin%spacker-builder-%s",
|
||||
packerPath, PACKERSPACE, PACKERSPACE, builder)
|
||||
c.Plugins.Builders.Set(builder, func() (packersdk.Builder, error) {
|
||||
@@ -164,6 +165,7 @@ func (c *config) discoverInternalComponents() error {
|
||||
for provisioner := range command.Provisioners {
|
||||
provisioner := provisioner
|
||||
if !c.Plugins.Provisioners.Has(provisioner) {
|
||||
command.TrackBundledPlugin(fmt.Sprintf("packer-provisioner-%s", provisioner))
|
||||
bin := fmt.Sprintf("%s%splugin%spacker-provisioner-%s",
|
||||
packerPath, PACKERSPACE, PACKERSPACE, provisioner)
|
||||
c.Plugins.Provisioners.Set(provisioner, func() (packersdk.Provisioner, error) {
|
||||
@@ -175,6 +177,7 @@ func (c *config) discoverInternalComponents() error {
|
||||
for postProcessor := range command.PostProcessors {
|
||||
postProcessor := postProcessor
|
||||
if !c.Plugins.PostProcessors.Has(postProcessor) {
|
||||
command.TrackBundledPlugin(fmt.Sprintf("packer-post-processor-%s", postProcessor))
|
||||
bin := fmt.Sprintf("%s%splugin%spacker-post-processor-%s",
|
||||
packerPath, PACKERSPACE, PACKERSPACE, postProcessor)
|
||||
c.Plugins.PostProcessors.Set(postProcessor, func() (packersdk.PostProcessor, error) {
|
||||
@@ -186,6 +189,7 @@ func (c *config) discoverInternalComponents() error {
|
||||
for dataSource := range command.Datasources {
|
||||
dataSource := dataSource
|
||||
if !c.Plugins.DataSources.Has(dataSource) {
|
||||
command.TrackBundledPlugin(fmt.Sprintf("packer-datasource-%s", dataSource))
|
||||
bin := fmt.Sprintf("%s%splugin%spacker-datasource-%s",
|
||||
packerPath, PACKERSPACE, PACKERSPACE, dataSource)
|
||||
c.Plugins.DataSources.Set(dataSource, func() (packersdk.Datasource, error) {
|
||||
|
||||
+2
-13
@@ -308,19 +308,8 @@ func filterVarsFromLogs(inputOrLocal Variables) {
|
||||
}
|
||||
|
||||
func (cfg *PackerConfig) Initialize(opts packer.InitializeOptions) hcl.Diagnostics {
|
||||
var diags hcl.Diagnostics
|
||||
|
||||
// enable packer to start plugins requested in required_plugins.
|
||||
moreDiags := cfg.detectPluginBinaries()
|
||||
diags = append(diags, moreDiags...)
|
||||
if moreDiags.HasErrors() {
|
||||
return diags
|
||||
}
|
||||
|
||||
moreDiags = cfg.InputVariables.ValidateValues()
|
||||
diags = append(diags, moreDiags...)
|
||||
moreDiags = cfg.LocalVariables.ValidateValues()
|
||||
diags = append(diags, moreDiags...)
|
||||
diags := cfg.InputVariables.ValidateValues()
|
||||
diags = append(diags, cfg.LocalVariables.ValidateValues()...)
|
||||
diags = append(diags, cfg.evaluateDatasources(opts.SkipDatasourcesExecution)...)
|
||||
diags = append(diags, checkForDuplicateLocalDefinition(cfg.LocalBlocks)...)
|
||||
diags = append(diags, cfg.evaluateLocalVariables(cfg.LocalBlocks)...)
|
||||
|
||||
@@ -54,7 +54,7 @@ func (cfg *PackerConfig) PluginRequirements() (plugingetter.Requirements, hcl.Di
|
||||
return reqs, diags
|
||||
}
|
||||
|
||||
func (cfg *PackerConfig) detectPluginBinaries() hcl.Diagnostics {
|
||||
func (cfg *PackerConfig) DetectPluginBinaries() hcl.Diagnostics {
|
||||
opts := plugingetter.ListInstallationsOptions{
|
||||
FromFolders: cfg.parser.PluginConfig.KnownPluginFolders,
|
||||
BinaryInstallationOptions: plugingetter.BinaryInstallationOptions{
|
||||
|
||||
@@ -132,6 +132,12 @@ func NewCore(c *CoreConfig) *Core {
|
||||
return core
|
||||
}
|
||||
|
||||
// DetectPluginBinaries is used to load required plugins from the template,
|
||||
// since it is unsupported in JSON, this is essentially a no-op.
|
||||
func (c *Core) DetectPluginBinaries() hcl.Diagnostics {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (c *Core) Initialize(_ InitializeOptions) hcl.Diagnostics {
|
||||
err := c.initialize()
|
||||
if err != nil {
|
||||
|
||||
@@ -40,6 +40,12 @@ type InitializeOptions struct {
|
||||
SkipDatasourcesExecution bool
|
||||
}
|
||||
|
||||
type PluginBinaryDetector interface {
|
||||
// DetectPluginBinaries is used only for HCL2 templates, and loads required
|
||||
// plugins if specified.
|
||||
DetectPluginBinaries() hcl.Diagnostics
|
||||
}
|
||||
|
||||
// The Handler handles all Packer things. This interface reflects the Packer
|
||||
// commands, ex: init, console ( evaluate ), fix config, inspect config, etc. To
|
||||
// run a build we will start the builds and then the core of Packer handles
|
||||
@@ -53,6 +59,7 @@ type Handler interface {
|
||||
BuildGetter
|
||||
ConfigFixer
|
||||
ConfigInspector
|
||||
PluginBinaryDetector
|
||||
}
|
||||
|
||||
//go:generate enumer -type FixConfigMode
|
||||
|
||||
Reference in New Issue
Block a user