@ -29,42 +29,6 @@ import (
"github.com/zclconf/go-cty/cty"
)
type HCL2UpgradeCommand struct {
Meta
}
func ( c * HCL2UpgradeCommand ) Run ( args [ ] string ) int {
ctx , cleanup := handleTermInterrupt ( c . Ui )
defer cleanup ( )
cfg , ret := c . ParseArgs ( args )
if ret != 0 {
return ret
}
return c . RunContext ( ctx , cfg )
}
func ( c * HCL2UpgradeCommand ) ParseArgs ( args [ ] string ) ( * HCL2UpgradeArgs , int ) {
var cfg HCL2UpgradeArgs
flags := c . Meta . FlagSet ( "hcl2_upgrade" )
flags . Usage = func ( ) { c . Ui . Say ( c . Help ( ) ) }
cfg . AddFlagSets ( flags )
if err := flags . Parse ( args ) ; err != nil {
return & cfg , 1
}
args = flags . Args ( )
if len ( args ) != 1 {
flags . Usage ( )
return & cfg , 1
}
cfg . Path = args [ 0 ]
if cfg . OutputFile == "" {
cfg . OutputFile = cfg . Path + ".pkr.hcl"
}
return & cfg , 0
}
const (
hcl2UpgradeFileHeader = ` # This file was autogenerated by the ' packer hcl2_upgrade ' command . We
# recommend double checking that everything is correct before going forward . We
@ -130,6 +94,59 @@ var (
strftime = false
)
// knownPlugins represent the HashiCorp maintained plugins the we can confidently
// construct a required plugins block for.
var knownPlugins = 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" ,
}
// unknownPluginName represents any plugin not in knownPlugins or bundled into Packer
const unknownPluginName string = "unknown"
type HCL2UpgradeCommand struct {
Meta
}
func ( c * HCL2UpgradeCommand ) Run ( args [ ] string ) int {
ctx , cleanup := handleTermInterrupt ( c . Ui )
defer cleanup ( )
cfg , ret := c . ParseArgs ( args )
if ret != 0 {
return ret
}
return c . RunContext ( ctx , cfg )
}
func ( c * HCL2UpgradeCommand ) ParseArgs ( args [ ] string ) ( * HCL2UpgradeArgs , int ) {
var cfg HCL2UpgradeArgs
flags := c . Meta . FlagSet ( "hcl2_upgrade" )
flags . Usage = func ( ) { c . Ui . Say ( c . Help ( ) ) }
cfg . AddFlagSets ( flags )
if err := flags . Parse ( args ) ; err != nil {
return & cfg , 1
}
args = flags . Args ( )
if len ( args ) != 1 {
flags . Usage ( )
return & cfg , 1
}
cfg . Path = args [ 0 ]
if cfg . OutputFile == "" {
cfg . OutputFile = cfg . Path + ".pkr.hcl"
}
return & cfg , 0
}
type BlockParser interface {
Parse ( * template . Template ) error
Write ( * bytes . Buffer )
@ -169,7 +186,6 @@ func (c *HCL2UpgradeCommand) RunContext(_ context.Context, cla *HCL2UpgradeArgs)
tpl := core . Template
// Parse blocks
packerBlock := & PackerParser {
WithAnnotations : cla . WithAnnotations ,
}
@ -827,28 +843,28 @@ func gatherPluginsFromTemplate(tpl *template.Template) []string {
plugins := map [ string ] struct { } { }
for _ , b := range tpl . Builders {
for prefix , plugin := range knownPluginPrefixes {
if strings . HasPrefix ( b . Type , prefix ) {
plugins [ plugin ] = struct { } { }
}
name := knownPluginComponent ( b . Type )
if name == unknownPluginName {
continue
}
plugins [ knownPlugins [ name ] ] = struct { } { }
}
for _ , p := range tpl . Provisioners {
for prefix , plugin := range knownPluginPrefixes {
if strings . HasPrefix ( p . Type , prefix ) {
plugins [ plugin ] = struct { } { }
}
name := knownPluginComponent ( p . Type )
if name == unknownPluginName {
continue
}
plugins [ knownPlugins [ name ] ] = struct { } { }
}
for _ , pps := range tpl . PostProcessors {
for _ , pp := range pps {
for prefix , plugin := range knownPluginPrefixes {
if strings . HasPrefix ( pp . Type , prefix ) {
plugins [ plugin ] = struct { } { }
}
name := knownPluginComponent ( pp . Type )
if name == unknownPluginName {
continue
}
plugins [ knownPlugins [ name ] ] = struct { } { }
}
}
@ -1182,18 +1198,17 @@ type SourceParser struct {
}
func ( p * SourceParser ) Parse ( tpl * template . Template ) error {
var unknownBuilders [ ] string
if p . out == nil {
p . out = [ ] byte { }
}
var unknownBuilders [ ] string
for i , builderCfg := range p . Builders {
sourcesContent := hclwrite . NewEmptyFile ( )
body := sourcesContent . Body ( )
body . AppendNewline ( )
if ! p . BuilderPlugins . Has ( builderCfg . Type ) {
if ! p . BuilderPlugins . Has ( builderCfg . Type ) && knownPluginComponent ( builderCfg . Type ) == unknownPluginName {
unknownBuilders = append ( unknownBuilders , builderCfg . Type )
}
if builderCfg . Name == "" || builderCfg . Name == builderCfg . Type {
builderCfg . Name = fmt . Sprintf ( "autogenerated_%d" , i + 1 )
@ -1206,9 +1221,11 @@ func (p *SourceParser) Parse(tpl *template.Template) error {
p . out = append ( p . out , transposeTemplatingCalls ( sourcesContent . Bytes ( ) ) ... )
}
// TODO update to output to stderr as opposed to having the command exit 1
if len ( unknownBuilders ) > 0 {
return fmt . Errorf ( "unknown builder type(s): %v\n" , unknownBuilders )
}
return nil
}
@ -1412,3 +1429,12 @@ func fixQuoting(old string) string {
return string ( body )
}
func knownPluginComponent ( component string ) string {
for prefix := range knownPlugins {
if strings . HasPrefix ( component , prefix ) {
return prefix
}
}
return unknownPluginName
}