github.com/yoctocloud/packer@v0.6.2-0.20160520224004-e11a0a18423f/post-processor/vsphere/post-processor.go (about) 1 package vsphere 2 3 import ( 4 "fmt" 5 "log" 6 "net/url" 7 "os" 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 ui.Message(fmt.Sprintf("Uploading %s to vSphere", source)) 125 126 args, err := p.BuildArgs(source, ovftool_uri) 127 if err != nil { 128 ui.Message(fmt.Sprintf("Failed: %s\n", err)) 129 } 130 131 ui.Message(fmt.Sprintf("Uploading %s to vSphere", source)) 132 133 log.Printf("Starting ovftool with parameters: %s", strings.Join(args, " ")) 134 cmd := exec.Command("ovftool", args...) 135 cmd.Stdout = os.Stdout 136 cmd.Stderr = os.Stderr 137 if err := cmd.Run(); err != nil { 138 return nil, false, fmt.Errorf("Failed: %s\n", err) 139 } 140 141 return artifact, false, nil 142 } 143 144 func (p *PostProcessor) BuildArgs(source, ovftool_uri string) ([]string, error) { 145 args := []string{ 146 "--acceptAllEulas", 147 fmt.Sprintf(`--name=%s`, p.config.VMName), 148 fmt.Sprintf(`--datastore=%s`, p.config.Datastore), 149 } 150 151 if p.config.Insecure { 152 args = append(args, fmt.Sprintf(`--noSSLVerify=%t`, p.config.Insecure)) 153 } 154 155 if p.config.DiskMode != "" { 156 args = append(args, fmt.Sprintf(`--diskMode=%s`, p.config.DiskMode)) 157 } 158 159 if p.config.VMFolder != "" { 160 args = append(args, fmt.Sprintf(`--vmFolder=%s`, p.config.VMFolder)) 161 } 162 163 if p.config.VMNetwork != "" { 164 args = append(args, fmt.Sprintf(`--network=%s`, p.config.VMNetwork)) 165 } 166 167 if p.config.Overwrite == true { 168 args = append(args, "--overwrite") 169 } 170 171 if len(p.config.Options) > 0 { 172 args = append(args, p.config.Options...) 173 } 174 175 args = append(args, fmt.Sprintf(`%s`, source)) 176 args = append(args, fmt.Sprintf(`%s`, ovftool_uri)) 177 178 return args, nil 179 }