forked from hashicorp/packer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
post-processor.go
136 lines (114 loc) · 3.38 KB
/
post-processor.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
package vsphere
import (
"bytes"
"fmt"
"github.com/mitchellh/packer/common"
"github.com/mitchellh/packer/packer"
"os/exec"
"strings"
)
var builtins = map[string]string{
"mitchellh.vmware": "vmware",
}
type Config struct {
common.PackerConfig `mapstructure:",squash"`
Insecure bool `mapstructure:"insecure"`
Cluster string `mapstructure:"cluster"`
Datacenter string `mapstructure:"datacenter"`
Datastore string `mapstructure:"datastore"`
Host string `mapstructure:"host"`
Password string `mapstructure:"password"`
ResourcePool string `mapstructure:"resource_pool"`
Username string `mapstructure:"username"`
VMFolder string `mapstructure:"vm_folder"`
VMName string `mapstructure:"vm_name"`
VMNetwork string `mapstructure:"vm_network"`
tpl *packer.ConfigTemplate
}
type PostProcessor struct {
config Config
}
func (p *PostProcessor) Configure(raws ...interface{}) error {
_, err := common.DecodeConfig(&p.config, raws...)
if err != nil {
return err
}
p.config.tpl, err = packer.NewConfigTemplate()
if err != nil {
return err
}
p.config.tpl.UserVars = p.config.PackerUserVars
// Accumulate any errors
errs := new(packer.MultiError)
if _, err := exec.LookPath("ovftool"); err != nil {
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("ovftool not found: %s", err))
}
templates := map[string]*string{
"cluster": &p.config.Cluster,
"datacenter": &p.config.Datacenter,
"datastore": &p.config.Datastore,
"host": &p.config.Host,
"vm_network": &p.config.VMNetwork,
"password": &p.config.Password,
"resource_pool": &p.config.ResourcePool,
"username": &p.config.Username,
"vm_folder": &p.config.VMFolder,
"vm_name": &p.config.VMName,
}
for key, ptr := range templates {
if *ptr == "" {
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("%s must be set", key))
}
*ptr, err = p.config.tpl.Process(*ptr, nil)
if err != nil {
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("Error processing %s: %s", key, err))
}
}
if len(errs.Errors) > 0 {
return errs
}
return nil
}
func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) {
if _, ok := builtins[artifact.BuilderId()]; !ok {
return nil, false, fmt.Errorf("Unknown artifact type, can't build box: %s", artifact.BuilderId())
}
vmx := ""
for _, path := range artifact.Files() {
if strings.HasSuffix(path, ".vmx") {
vmx = path
break
}
}
if vmx == "" {
return nil, false, fmt.Errorf("VMX file not found")
}
args := []string{
fmt.Sprintf("--noSSLVerify=%t", p.config.Insecure),
"--acceptAllEulas",
fmt.Sprintf("--name=%s", p.config.VMName),
fmt.Sprintf("--datastore=%s", p.config.Datastore),
fmt.Sprintf("--network=%s", p.config.VMNetwork),
fmt.Sprintf("--vmFolder=%s", p.config.VMFolder),
fmt.Sprintf("%s", vmx),
fmt.Sprintf("vi://%s:%s@%s/%s/host/%s/Resources/%s",
p.config.Username,
p.config.Password,
p.config.Host,
p.config.Datacenter,
p.config.Cluster,
p.config.ResourcePool),
}
ui.Message(fmt.Sprintf("Uploading %s to vSphere", vmx))
var out bytes.Buffer
cmd := exec.Command("ovftool", args...)
cmd.Stdout = &out
if err := cmd.Run(); err != nil {
return nil, false, fmt.Errorf("Failed: %s\nStdout: %s", err, out.String())
}
ui.Message(fmt.Sprintf("%s", out.String()))
return artifact, false, nil
}