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