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