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