From eb9e1a479537f3786b9f5ad48a414fce6aa9cb2c Mon Sep 17 00:00:00 2001 From: Lucas Bajolet Date: Wed, 9 Aug 2023 14:42:38 -0400 Subject: [PATCH] packer: remove implicit required plugins Since this feature is no longer something we plan to activate later, as it contradicts with our efforts to remove bundled plugins, and encouraging users to move to either manually installing plugins, or managing them through `packer init', we clean-up the code for this feature. --- command/init.go | 48 +---- command/plugins_install.go | 1 - command/plugins_installed.go | 1 - command/plugins_remove.go | 1 - hcl2template/parser.go | 18 +- hcl2template/plugin.go | 1 - hcl2template/types.required_plugins.go | 138 ------------- hcl2template/types.required_plugins_test.go | 218 +------------------- main.go | 66 ------ packer/plugin-getter/plugins.go | 3 - packer/plugin.go | 17 -- website/content/docs/commands/init.mdx | 12 -- 12 files changed, 8 insertions(+), 516 deletions(-) diff --git a/command/init.go b/command/init.go index 5a066d962..ad9a7bcdd 100644 --- a/command/init.go +++ b/command/init.go @@ -124,55 +124,13 @@ func (c *InitCommand) RunContext(buildCtx context.Context, cla *InitArgs) int { Getters: getters, }) if err != nil { - if pluginRequirement.Implicit { - msg := fmt.Sprintf(` -Warning! At least one component used in your config file(s) has moved out of -Packer into the %q plugin. -For that reason, Packer init tried to install the latest version of the %s -plugin. Unfortunately, this failed : -%s`, - pluginRequirement.Identifier, - pluginRequirement.Identifier.Type, - err) - c.Ui.Say(msg) - } else { - c.Ui.Error(fmt.Sprintf("Failed getting the %q plugin:", pluginRequirement.Identifier)) - c.Ui.Error(err.Error()) - ret = 1 - } + c.Ui.Error(fmt.Sprintf("Failed getting the %q plugin:", pluginRequirement.Identifier)) + c.Ui.Error(err.Error()) + ret = 1 } if newInstall != nil { - if pluginRequirement.Implicit { - msg := fmt.Sprintf("Installed implicitly required plugin %s %s in %q", pluginRequirement.Identifier, newInstall.Version, newInstall.BinaryPath) - ui.Say(msg) - - warn := fmt.Sprintf(` -Warning, at least one component used in your config file(s) has moved out of -Packer into the %[2]q plugin and is now being implicitly required. -For more details on implicitly required plugins see https://packer.io/docs/commands/init#implicit-required-plugin - -To avoid any backward incompatible changes with your -config file you may want to lock the plugin version by pasting the following to your config: - -packer { - required_plugins { - %[1]s = { - source = "%[2]s" - version = "~> %[3]s" - } - } -} -`, - pluginRequirement.Identifier.Type, - pluginRequirement.Identifier, - newInstall.Version, - ) - ui.Error(warn) - continue - } msg := fmt.Sprintf("Installed plugin %s %s in %q", pluginRequirement.Identifier, newInstall.Version, newInstall.BinaryPath) ui.Say(msg) - } } return ret diff --git a/command/plugins_install.go b/command/plugins_install.go index 7082f134a..3037c0959 100644 --- a/command/plugins_install.go +++ b/command/plugins_install.go @@ -77,7 +77,6 @@ func (c *PluginsInstallCommand) RunContext(buildCtx context.Context, args []stri // a plugin requirement that matches them all pluginRequirement := plugingetter.Requirement{ Identifier: plugin, - Implicit: false, } if len(args) > 1 { diff --git a/command/plugins_installed.go b/command/plugins_installed.go index 114c25b55..b19be4e5c 100644 --- a/command/plugins_installed.go +++ b/command/plugins_installed.go @@ -64,7 +64,6 @@ func (c *PluginsInstalledCommand) RunContext(buildCtx context.Context) int { Accessor: "", VersionConstraints: nil, Identifier: nil, - Implicit: false, } installations, err := allPlugins.ListInstallations(opts) diff --git a/command/plugins_remove.go b/command/plugins_remove.go index ac8c0882b..07993f21a 100644 --- a/command/plugins_remove.go +++ b/command/plugins_remove.go @@ -74,7 +74,6 @@ func (c *PluginsRemoveCommand) RunContext(buildCtx context.Context, args []strin // a plugin requirement that matches them all pluginRequirement := plugingetter.Requirement{ Identifier: plugin, - Implicit: false, } if len(args) > 1 { diff --git a/hcl2template/parser.go b/hcl2template/parser.go index 43b43bcd6..fc9182bf0 100644 --- a/hcl2template/parser.go +++ b/hcl2template/parser.go @@ -163,28 +163,14 @@ func (p *Parser) Parse(filename string, varFiles []string, argVars map[string]st return cfg, diags } - // Decode required_plugins blocks and create implicit required_plugins - // blocks. Implicit required_plugins blocks happen when a builder or another - // plugin cannot be found, for example if one uses : - // source "amazon-ebs" "example" { ... } - // And no `amazon-ebs` builder can be found. This will then be the - // equivalent of having : - // packer { - // required_plugins { - // amazon = { - // version = "latest" - // source = "github.com/hashicorp/amazon" - // } - // } + // Decode required_plugins blocks. + // // Note: using `latest` ( or actually an empty string ) in a config file // does not work and packer will ask you to pick a version { for _, file := range files { diags = append(diags, cfg.decodeRequiredPluginsBlock(file)...) } - for _, file := range files { - diags = append(diags, cfg.decodeImplicitRequiredPluginsBlocks(file)...) - } } // Decode variable blocks so that they are available later on. Here locals diff --git a/hcl2template/plugin.go b/hcl2template/plugin.go index 92b9cf2f3..323263596 100644 --- a/hcl2template/plugin.go +++ b/hcl2template/plugin.go @@ -45,7 +45,6 @@ func (cfg *PackerConfig) PluginRequirements() (plugingetter.Requirements, hcl.Di Accessor: name, Identifier: block.Type, VersionConstraints: block.Requirement.Required, - Implicit: block.PluginDependencyReason == PluginDependencyImplicit, }) uniq[name] = block } diff --git a/hcl2template/types.required_plugins.go b/hcl2template/types.required_plugins.go index 94dfd4669..d5e010345 100644 --- a/hcl2template/types.required_plugins.go +++ b/hcl2template/types.required_plugins.go @@ -9,7 +9,6 @@ import ( "github.com/hashicorp/go-version" "github.com/hashicorp/hcl/v2" "github.com/hashicorp/packer/hcl2template/addrs" - "github.com/hashicorp/packer/packer" "github.com/zclconf/go-cty/cty" ) @@ -44,127 +43,6 @@ func (cfg *PackerConfig) decodeRequiredPluginsBlock(f *hcl.File) hcl.Diagnostics return diags } -func (cfg *PackerConfig) decodeImplicitRequiredPluginsBlocks(f *hcl.File) hcl.Diagnostics { - // when a plugin is used but not available it should be 'implicitly - // required'. Here we read common configuration blocks to try to guess - // plugin usages. - - // decodeRequiredPluginsBlock needs to be called before - // decodeImplicitRequiredPluginsBlocks; otherwise all required plugins will - // be implicitly required too. - - var diags hcl.Diagnostics - - content, moreDiags := f.Body.Content(configSchema) - diags = append(diags, moreDiags...) - - for _, block := range content.Blocks { - - switch block.Type { - case sourceLabel: - diags = append(diags, cfg.decodeImplicitRequiredPluginsBlock(Builder, block)...) - case dataSourceLabel: - diags = append(diags, cfg.decodeImplicitRequiredPluginsBlock(Datasource, block)...) - case buildLabel: - content, _, moreDiags := block.Body.PartialContent(buildSchema) - diags = append(diags, moreDiags...) - for _, block := range content.Blocks { - - switch block.Type { - case buildProvisionerLabel: - diags = append(diags, cfg.decodeImplicitRequiredPluginsBlock(Provisioner, block)...) - case buildPostProcessorLabel: - diags = append(diags, cfg.decodeImplicitRequiredPluginsBlock(PostProcessor, block)...) - case buildPostProcessorsLabel: - content, _, moreDiags := block.Body.PartialContent(postProcessorsSchema) - diags = append(diags, moreDiags...) - for _, block := range content.Blocks { - - switch block.Type { - case buildPostProcessorLabel: - diags = append(diags, cfg.decodeImplicitRequiredPluginsBlock(PostProcessor, block)...) - } - } - } - } - - } - } - return diags -} - -func (cfg *PackerConfig) decodeImplicitRequiredPluginsBlock(k ComponentKind, block *hcl.Block) hcl.Diagnostics { - if len(block.Labels) == 0 { - // malformed block ? Let's not panic :) - return nil - } - // Currently all block types are `type "component-kind" ["name"] {` - // this makes this simple. - componentName := block.Labels[0] - - store := map[ComponentKind]packer.BasicStore{ - Builder: cfg.parser.PluginConfig.Builders, - PostProcessor: cfg.parser.PluginConfig.PostProcessors, - Provisioner: cfg.parser.PluginConfig.Provisioners, - Datasource: cfg.parser.PluginConfig.DataSources, - }[k] - if store.Has(componentName) { - // If any core or pre-loaded plugin defines the `happycloud-uploader` - // pp, skip. This happens for core and manually installed plugins, as - // they will be listed in the PluginConfig before parsing any HCL. - return nil - } - - redirect := map[ComponentKind]map[string]string{ - Builder: cfg.parser.PluginConfig.BuilderRedirects, - PostProcessor: cfg.parser.PluginConfig.PostProcessorRedirects, - Provisioner: cfg.parser.PluginConfig.ProvisionerRedirects, - Datasource: cfg.parser.PluginConfig.DatasourceRedirects, - }[k][componentName] - - if redirect == "" { - // no known redirect for this component - return nil - } - - redirectAddr, diags := addrs.ParsePluginSourceString(redirect) - if diags.HasErrors() { - // This should never happen, since the map is manually filled. - return diags - } - - for _, req := range cfg.Packer.RequiredPlugins { - if _, found := req.RequiredPlugins[redirectAddr.Type]; found { - // This could happen if a plugin was forked. For example, I forked - // the github.com/hashicorp/happycloud plugin into - // github.com/azr/happycloud that is required in my config file; and - // am using the `happycloud-uploader` pp component from it. In that - // case - and to avoid miss-requires - we won't implicitly import - // any other `happycloud` plugin. - return nil - } - } - - cfg.implicitlyRequirePlugin(redirectAddr) - return nil -} - -func (cfg *PackerConfig) implicitlyRequirePlugin(plugin *addrs.Plugin) { - cfg.Packer.RequiredPlugins = append(cfg.Packer.RequiredPlugins, &RequiredPlugins{ - RequiredPlugins: map[string]*RequiredPlugin{ - plugin.Type: { - Name: plugin.Type, - Source: plugin.String(), - Type: plugin, - Requirement: VersionConstraint{ - Required: nil, // means latest - }, - PluginDependencyReason: PluginDependencyImplicit, - }, - }, - }) -} - // RequiredPlugin represents a declaration of a dependency on a particular // Plugin version or source. type RequiredPlugin struct { @@ -177,24 +55,8 @@ type RequiredPlugin struct { Type *addrs.Plugin Requirement VersionConstraint DeclRange hcl.Range - PluginDependencyReason } -// PluginDependencyReason is an enumeration of reasons why a dependency might be -// present. -type PluginDependencyReason int - -const ( - // PluginDependencyExplicit means that there is an explicit - // "required_plugin" block in the configuration. - PluginDependencyExplicit PluginDependencyReason = iota - - // PluginDependencyImplicit means that there is no explicit - // "required_plugin" block but there is at least one resource that uses this - // plugin. - PluginDependencyImplicit -) - type RequiredPlugins struct { RequiredPlugins map[string]*RequiredPlugin DeclRange hcl.Range diff --git a/hcl2template/types.required_plugins_test.go b/hcl2template/types.required_plugins_test.go index 5e2b4a90c..0329d1505 100644 --- a/hcl2template/types.required_plugins_test.go +++ b/hcl2template/types.required_plugins_test.go @@ -46,7 +46,6 @@ func TestPackerConfig_required_plugin_parse(t *testing.T) { Requirement: VersionConstraint{ Required: mustVersionConstraints(version.NewConstraint("~> v1.2.3")), }, - PluginDependencyReason: PluginDependencyExplicit, }, }}, }, @@ -77,19 +76,13 @@ func TestPackerConfig_required_plugin_parse(t *testing.T) { Requirement: VersionConstraint{ Required: mustVersionConstraints(version.NewConstraint("~> v1.2.3")), }, - PluginDependencyReason: PluginDependencyExplicit, }, }}, }, }, }}, {"required_plugin_forked", PackerConfig{ - parser: getBasicParser(func(p *Parser) { - p.PluginConfig.BuilderRedirects = map[string]string{ - "amazon-chroot": "github.com/hashicorp/amazon", - } - }, - )}, ` + parser: getBasicParser(func(p *Parser) {})}, ` packer { required_plugins { amazon = { @@ -114,19 +107,13 @@ func TestPackerConfig_required_plugin_parse(t *testing.T) { Requirement: VersionConstraint{ Required: mustVersionConstraints(version.NewConstraint("~> v1.2.3")), }, - PluginDependencyReason: PluginDependencyExplicit, }, }}, }, }, }}, {"missing-required-plugin-for-pre-defined-builder", PackerConfig{ - parser: getBasicParser(func(p *Parser) { - p.PluginConfig.BuilderRedirects = map[string]string{ - "amazon-ebs": "github.com/hashicorp/amazon", - } - }, - )}, + parser: getBasicParser(func(p *Parser) {})}, ` packer { }`, ` @@ -143,202 +130,6 @@ func TestPackerConfig_required_plugin_parse(t *testing.T) { RequiredPlugins: nil, }, }}, - {"missing-required-plugin-for-builder", PackerConfig{ - parser: getBasicParser(func(p *Parser) { - p.PluginConfig.BuilderRedirects = map[string]string{ - "amazon-chroot": "github.com/hashicorp/amazon", - } - }, - )}, - ` - packer { - }`, ` - source "amazon-chroot" "example" { - } - `, - false, - PackerConfig{ - Packer: struct { - VersionConstraints []VersionConstraint - RequiredPlugins []*RequiredPlugins - }{ - RequiredPlugins: []*RequiredPlugins{ - {RequiredPlugins: map[string]*RequiredPlugin{ - "amazon": { - Name: "amazon", - Source: "github.com/hashicorp/amazon", - Type: &addrs.Plugin{Hostname: "github.com", Namespace: "hashicorp", Type: "amazon"}, - Requirement: VersionConstraint{ - Required: nil, - }, - PluginDependencyReason: PluginDependencyImplicit, - }, - }}, - }, - }, - }}, - {"missing-required-plugin-for-provisioner", PackerConfig{ - parser: getBasicParser(func(p *Parser) { - p.PluginConfig.ProvisionerRedirects = map[string]string{ - "ansible-local": "github.com/ansible/ansible", - } - }, - )}, - ` - packer { - }`, ` - build { - provisioner "ansible-local" {} - } - `, - false, - PackerConfig{ - Packer: struct { - VersionConstraints []VersionConstraint - RequiredPlugins []*RequiredPlugins - }{ - RequiredPlugins: []*RequiredPlugins{ - {RequiredPlugins: map[string]*RequiredPlugin{ - "ansible": { - Name: "ansible", - Source: "github.com/ansible/ansible", - Type: &addrs.Plugin{Hostname: "github.com", Namespace: "ansible", Type: "ansible"}, - Requirement: VersionConstraint{ - Required: nil, - }, - PluginDependencyReason: PluginDependencyImplicit, - }, - }}, - }, - }, - }}, - {"missing-required-plugin-for-post-processor", PackerConfig{ - parser: getBasicParser(func(p *Parser) { - p.PluginConfig.PostProcessorRedirects = map[string]string{ - "docker-push": "github.com/hashicorp/docker", - } - }, - )}, - ` - packer { - }`, ` - build { - post-processor "docker-push" {} - } - `, - false, - PackerConfig{ - Packer: struct { - VersionConstraints []VersionConstraint - RequiredPlugins []*RequiredPlugins - }{ - RequiredPlugins: []*RequiredPlugins{ - {RequiredPlugins: map[string]*RequiredPlugin{ - "docker": { - Name: "docker", - Source: "github.com/hashicorp/docker", - Type: &addrs.Plugin{Hostname: "github.com", Namespace: "hashicorp", Type: "docker"}, - Requirement: VersionConstraint{ - Required: nil, - }, - PluginDependencyReason: PluginDependencyImplicit, - }, - }}, - }, - }, - }}, - {"missing-required-plugin-for-nested-post-processor", PackerConfig{ - parser: getBasicParser(func(p *Parser) { - p.PluginConfig.PostProcessorRedirects = map[string]string{ - "docker-push": "github.com/hashicorp/docker", - } - }, - )}, - ` - packer { - }`, ` - build { - post-processors { - post-processor "docker-push" { - } - } - } - `, - false, - PackerConfig{ - Packer: struct { - VersionConstraints []VersionConstraint - RequiredPlugins []*RequiredPlugins - }{ - RequiredPlugins: []*RequiredPlugins{ - {RequiredPlugins: map[string]*RequiredPlugin{ - "docker": { - Name: "docker", - Source: "github.com/hashicorp/docker", - Type: &addrs.Plugin{Hostname: "github.com", Namespace: "hashicorp", Type: "docker"}, - Requirement: VersionConstraint{ - Required: nil, - }, - PluginDependencyReason: PluginDependencyImplicit, - }, - }}, - }, - }, - }}, - - {"required-plugin-renamed", PackerConfig{ - parser: getBasicParser(func(p *Parser) { - p.PluginConfig.BuilderRedirects = map[string]string{ - "amazon-chroot": "github.com/hashicorp/amazon", - } - }, - )}, - ` - packer { - required_plugins { - amazon-v1 = { - source = "github.com/hashicorp/amazon" - version = "~> v1.0" - } - } - }`, ` - source "amazon-v1-chroot" "example" { - } - source "amazon-chroot" "example" { - } - `, - false, - PackerConfig{ - Packer: struct { - VersionConstraints []VersionConstraint - RequiredPlugins []*RequiredPlugins - }{ - RequiredPlugins: []*RequiredPlugins{ - {RequiredPlugins: map[string]*RequiredPlugin{ - "amazon-v1": { - Name: "amazon-v1", - Source: "github.com/hashicorp/amazon", - Type: &addrs.Plugin{Hostname: "github.com", Namespace: "hashicorp", Type: "amazon"}, - Requirement: VersionConstraint{ - Required: mustVersionConstraints(version.NewConstraint("~> v1.0")), - }, - PluginDependencyReason: PluginDependencyExplicit, - }, - }}, - {RequiredPlugins: map[string]*RequiredPlugin{ - "amazon": { - Name: "amazon", - Source: "github.com/hashicorp/amazon", - Type: &addrs.Plugin{Hostname: "github.com", Namespace: "hashicorp", Type: "amazon"}, - Requirement: VersionConstraint{ - Required: nil, - }, - PluginDependencyReason: PluginDependencyImplicit, - }, - }}, - }, - }, - }}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -351,13 +142,10 @@ func TestPackerConfig_required_plugin_parse(t *testing.T) { t.Fatal(diags) } - rest, diags := cfg.parser.ParseHCL([]byte(tt.restOfTemplate), "rest.pkr.hcl") + _, diags = cfg.parser.ParseHCL([]byte(tt.restOfTemplate), "rest.pkr.hcl") if len(diags) > 0 { t.Fatal(diags) } - if gotDiags := cfg.decodeImplicitRequiredPluginsBlocks(rest); (len(gotDiags) > 0) != tt.wantDiags { - t.Fatal(gotDiags) - } if diff := cmp.Diff(tt.wantConfig, cfg, cmpOpts...); diff != "" { t.Errorf("PackerConfig.inferImplicitRequiredPluginFromBlocks() unexpected PackerConfig: %v", diff) } diff --git a/main.go b/main.go index 0d39d70d5..972f7170c 100644 --- a/main.go +++ b/main.go @@ -325,72 +325,6 @@ func loadConfig() (*config, error) { PluginMinPort: 10000, PluginMaxPort: 25000, KnownPluginFolders: packer.PluginFolders("."), - - // BuilderRedirects - BuilderRedirects: map[string]string{ - - //"amazon-chroot": "github.com/hashicorp/amazon", - //"amazon-ebs": "github.com/hashicorp/amazon", - //"amazon-ebssurrogate": "github.com/hashicorp/amazon", - //"amazon-ebsvolume": "github.com/hashicorp/amazon", - //"amazon-instance": "github.com/hashicorp/amazon", - - //"azure-arm": "github.com/hashicorp/azure", - //"azure-chroot": "github.com/hashicorp/azure", - //"azure-dtl": "github.com/hashicorp/azure", - - //"docker": "github.com/hashicorp/docker", - - //"exoscale": "github.com/exoscale/exoscale", - - //"googlecompute": "github.com/hashicorp/googlecompute", - - //"parallels-iso": "github.com/hashicorp/parallels", - //"parallels-pvm": "github.com/hashicorp/parallels", - - //"qemu": "github.com/hashicorp/qemu", - - //"vagrant": "github.com/hashicorp/vagrant", - - //"virtualbox-iso": "github.com/hashicorp/virtualbox", - //"virtualbox-ovf": "github.com/hashicorp/virtualbox", - //"virtualbox-vm": "github.com/hashicorp/virtualbox", - - //"vmware-iso": "github.com/hashicorp/vmware", - //"vmware-vmx": "github.com/hashicorp/vmware", - - //"vsphere-iso": "github.com/hashicorp/vsphere", - //"vsphere-clone": "github.com/hashicorp/vsphere", - }, - DatasourceRedirects: map[string]string{ - //"amazon-ami": "github.com/hashicorp/amazon", - //"amazon-secretsmanager": "github.com/hashicorp/amazon", - }, - ProvisionerRedirects: map[string]string{ - //"ansible": "github.com/hashicorp/ansible", - //"ansible-local": "github.com/hashicorp/ansible", - - //"azure-dtlartifact": "github.com/hashicorp/azure", - }, - PostProcessorRedirects: map[string]string{ - //"amazon-import": "github.com/hashicorp/amazon", - - //"docker-import": "github.com/hashicorp/docker", - //"docker-push": "github.com/hashicorp/docker", - //"docker-save": "github.com/hashicorp/docker", - //"docker-tag": "github.com/hashicorp/docker", - - //"googlecompute-export": "github.com/hashicorp/googlecompute", - //"googlecompute-import": "github.com/hashicorp/googlecompute", - - //"exoscale-import": "github.com/exoscale/exoscale", - - //"vagrant": "github.com/hashicorp/vagrant", - //"vagrant-cloud": "github.com/hashicorp/vagrant", - - //"vsphere": "github.com/hashicorp/vsphere", - //"vsphere-template": "github.com/hashicorp/vsphere", - }, } if err := config.Plugins.Discover(); err != nil { return nil, err diff --git a/packer/plugin-getter/plugins.go b/packer/plugin-getter/plugins.go index b16edcfad..92f7e28a8 100644 --- a/packer/plugin-getter/plugins.go +++ b/packer/plugin-getter/plugins.go @@ -43,9 +43,6 @@ type Requirement struct { // VersionConstraints as defined by user. Empty ( to be avoided ) means // highest found version. VersionConstraints version.Constraints - - // was this require implicitly guessed ? - Implicit bool } type BinaryInstallationOptions struct { diff --git a/packer/plugin.go b/packer/plugin.go index c88f54f86..313ef2db3 100644 --- a/packer/plugin.go +++ b/packer/plugin.go @@ -34,23 +34,6 @@ type PluginConfig struct { Provisioners ProvisionerSet PostProcessors PostProcessorSet DataSources DatasourceSet - - // Redirects are only set when a plugin was completely moved out; they allow - // telling where a plugin has moved by checking if a known component of this - // plugin is used. For example implicitly require the - // github.com/hashicorp/amazon plugin if it was moved out and the - // "amazon-ebs" plugin is used, but not found. - // - // Redirects will be bypassed if the redirected components are already found - // in their corresponding sets (Builders, Provisioners, PostProcessors, - // DataSources). That is, for example, if you manually put a single - // component plugin in the plugins folder. - // - // Example BuilderRedirects: "amazon-ebs" => "github.com/hashicorp/amazon" - BuilderRedirects map[string]string - DatasourceRedirects map[string]string - ProvisionerRedirects map[string]string - PostProcessorRedirects map[string]string } // PACKERSPACE is used to represent the spaces that separate args for a command diff --git a/website/content/docs/commands/init.mdx b/website/content/docs/commands/init.mdx index 7b61ecbf1..940751c5b 100644 --- a/website/content/docs/commands/init.mdx +++ b/website/content/docs/commands/init.mdx @@ -87,18 +87,6 @@ Directory](/packer/docs/configure#packer-s-plugin-directory). See [Installing Plugins](/packer/docs/plugins#installing-plugins) for more information on how plugin installation works. -### Implicit required plugin - -This is part of a set of breaking changes made to decouple Packer releases from -plugin releases. To make the transition easier, we will tag components of these -plugins as "moved out". If one of the components of a moved out plugin is used -in a config file, but there is no mention of that plugin in the -"required_plugin" block, then Packer init will automatically download and -install that plugin. Packer will then display a warning and suggest that you -add the plugin to your required_plugin block. We recommend you use the -required_plugin block even if you are only using official plugins, because it -allows you to set the plugin version to avoid surprises in the future. - ## Options - `-upgrade` - On top of installing missing plugins, update installed plugins to