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