packer-cn/post-processor/vsphere-tpl/post-processor.go

114 lines
2.5 KiB
Go

package vsphere_tpl
import (
"fmt"
"net/url"
"github.com/hashicorp/packer/common"
"github.com/hashicorp/packer/helper/config"
"github.com/hashicorp/packer/packer"
"github.com/hashicorp/packer/template/interpolate"
"github.com/mitchellh/multistep"
"time"
)
type Config struct {
common.PackerConfig `mapstructure:",squash"`
Host string `mapstructure:"host"`
Username string `mapstructure:"username"`
Password string `mapstructure:"password"`
Datacenter string `mapstructure:"datacenter"`
VMName string `mapstructure:"vm_name"`
Folder string `mapstructure:"folder"`
ctx interpolate.Context
}
type PostProcessor struct {
config Config
url *url.URL
}
func (p *PostProcessor) Configure(raws ...interface{}) error {
err := config.Decode(&p.config, &config.DecodeOpts{
Interpolate: true,
InterpolateContext: &p.config.ctx,
InterpolateFilter: &interpolate.RenderFilter{
Exclude: []string{},
},
}, raws...)
if err != nil {
return err
}
errs := new(packer.MultiError)
vc := map[string]*string{
"host": &p.config.Host,
"username": &p.config.Username,
"password": &p.config.Password,
}
for key, ptr := range vc {
if *ptr == "" {
errs = packer.MultiErrorAppend(
errs, fmt.Errorf("%s must be set", key))
}
}
if err := p.configureURL(); err != nil {
errs = packer.MultiErrorAppend(
errs, err)
}
if len(errs.Errors) > 0 {
return errs
}
return nil
}
func (p *PostProcessor) PostProcess(ui packer.Ui, artifact packer.Artifact) (packer.Artifact, bool, error) {
state := new(multistep.BasicStateBag)
state.Put("ui", ui)
//FIXME I've trash environment, so I need to wait :(
ui.Message("Waiting 10s for VMWare vSphere to start")
time.Sleep(10 * time.Second)
steps := []multistep.Step{
&StepVSphereClient{
Datacenter: p.config.Datacenter,
VMName: p.config.VMName,
Url: p.url,
},
&StepFetchVm{
VMName: p.config.VMName,
},
&StepCreateFolder{
Folder: p.config.Folder,
},
&StepMarkAsTemplate{},
&StepMoveTemplate{
Folder: p.config.Folder,
},
}
runner := &multistep.BasicRunner{Steps: steps}
runner.Run(state)
if rawErr, ok := state.GetOk("error"); ok {
return artifact, true, rawErr.(error)
}
return artifact, true, nil
}
func (p *PostProcessor) configureURL() error {
sdk, err := url.Parse("https://" + p.config.Host + "/sdk")
if err != nil {
return nil
}
sdk.User = url.UserPassword(p.config.Username, p.config.Password)
p.url = sdk
return nil
}