packer-cn/hcl2template/zz_retrocompat.go

157 lines
3.4 KiB
Go
Raw Normal View History

package hcl2template
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"strings"
)
func translateBuilder(path string) (string, error) {
type ConfigV1 map[string]json.RawMessage
type ConfigV1V2 struct {
Artifact map[string]map[string]json.RawMessage `json:"artifact"`
}
type Type struct {
Name string `json:"name"`
Type string `json:"type"`
}
type PostProcessor struct {
Type string `json:"type"`
Except []string `json:"except"`
Only []string `json:"only"`
}
b, err := ioutil.ReadFile(path)
if err != nil {
return "", err
}
c1 := ConfigV1{}
if err := json.Unmarshal(b, &c1); err != nil {
return "", err
}
c12 := ConfigV1V2{}
if err := json.Unmarshal(b, &c12); err != nil {
return "", err
}
rawBuilder, found := c1["builders"]
if !found {
// no v1 builders
return path, nil
}
var tn []Type
if err := json.Unmarshal([]byte(rawBuilder), &tn); err != nil {
return "", err
}
var rawbuilders []json.RawMessage
if err := json.Unmarshal([]byte(rawBuilder), &rawbuilders); err != nil {
return "", err
}
var typePPs []PostProcessor
var rawPPs []json.RawMessage
if rawPP := c1["post-processors"]; len(rawPP) != 0 {
if err := json.Unmarshal([]byte(rawPP), &typePPs); err != nil {
return "", err
}
if err := json.Unmarshal([]byte(rawPP), &rawPPs); err != nil {
return "", err
}
}
for n, tn := range tn {
builderName := tn.Type
if tn.Name != "" {
builderName = tn.Name
}
if c12.Artifact[tn.Type] == nil {
c12.Artifact[tn.Type] = map[string]json.RawMessage{}
}
name := tn.Name
if name == "" {
name = fmt.Sprintf("autotranslated-builder-%d", len(c12.Artifact[tn.Type]))
}
if _, exists := c12.Artifact[tn.Type][name]; exists {
return "", fmt.Errorf("%s-%s is defined in old and new config", tn.Type, name)
}
rawbuilder := rawbuilders[n]
rawbuilder = removeKey(rawbuilder, "name", "only", "type")
c12.Artifact[tn.Type][name] = rawbuilder
for n, pp := range typePPs {
skip := false
for _, except := range pp.Except {
if except == builderName {
skip = true
break
}
}
for _, only := range pp.Only {
if only != builderName {
skip = true
break
}
}
if skip {
continue
}
if c12.Artifact[pp.Type] == nil {
c12.Artifact[pp.Type] = map[string]json.RawMessage{}
}
name := fmt.Sprintf("autotranslated-post-processor-%d", len(c12.Artifact[pp.Type]))
if _, exists := c12.Artifact[tn.Type][name]; exists {
return "", fmt.Errorf("%s-%s is defined in old and new config", tn.Type, name)
}
rawpp := rawPPs[n]
rawpp = rawpp[:len(rawpp)-1]
rawpp = append(rawpp, json.RawMessage(`,"source":"$artifacts.`+tn.Type+`.`+builderName+`"}`)...)
rawpp = removeKey(rawpp, "name", "only", "type")
c12.Artifact[pp.Type][name] = rawpp
log.Printf("%s", rawpp)
}
}
path = strings.TrimSuffix(path, ".json")
path = strings.TrimSuffix(path, ".pk")
path = path + ".v2.pk.json"
file, err := os.Create(path)
if err != nil {
return "", err
}
defer file.Close()
enc := json.NewEncoder(file)
enc.SetIndent("", " ")
return path, enc.Encode(c12)
}
func removeKey(in json.RawMessage, keys ...string) json.RawMessage {
m := map[string]json.RawMessage{}
if err := json.Unmarshal(in, &m); err != nil {
panic(err)
}
for _, key := range keys {
delete(m, key)
}
b, err := json.Marshal(m)
if err != nil {
panic(err)
}
return b
}