func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { //Setup XAPI client client := xsclient.NewXenAPIClient(self.config.HostIp, self.config.Username, self.config.Password) err := client.Login() if err != nil { return nil, err.(error) } ui.Say("XAPI client session established") client.GetHosts() //Share state between the other steps using a statebag state := new(multistep.BasicStateBag) state.Put("cache", cache) state.Put("client", client) state.Put("config", self.config) state.Put("commonconfig", self.config.CommonConfig) state.Put("hook", hook) state.Put("ui", ui) httpReqChan := make(chan string, 1) //Build the steps steps := []multistep.Step{ &xscommon.StepPrepareOutputDir{ Force: self.config.PackerForce, Path: self.config.OutputDir, }, &xscommon.StepPrepareNfsExport{ NfsMount: self.config.NfsMount, }, &xscommon.StepIsoDownload{ IsoName: self.config.ISOName, SrName: self.config.ISOSRName, DlUrl: self.config.ISOUrl, ScriptUrl: self.config.ScriptUrl, }, &common.StepCreateFloppy{ Files: self.config.FloppyFiles, }, &xscommon.StepHTTPServer{ Chan: httpReqChan, }, &xscommon.StepUploadVdi{ VdiNameFunc: func() string { return "Packer-floppy-disk" }, ImagePathFunc: func() string { if floppyPath, ok := state.GetOk("floppy_path"); ok { return floppyPath.(string) } return "" }, VdiUuidKey: "floppy_vdi_uuid", }, &xscommon.StepFindVdi{ VdiName: self.config.ToolsIsoName, VdiUuidKey: "tools_vdi_uuid", }, &xscommon.StepFindVdi{ VdiName: self.config.ISOName, VdiUuidKey: "iso_vdi_uuid", }, new(stepCreateInstance), &xscommon.StepAttachVdi{ VdiUuidKey: "floppy_vdi_uuid", VdiType: xsclient.Floppy, }, &xscommon.StepAttachVdi{ VdiUuidKey: "iso_vdi_uuid", VdiType: xsclient.CD, }, new(xscommon.StepStartVmPaused), new(xscommon.StepGetVNCPort), &xscommon.StepForwardPortOverSSH{ RemotePort: xscommon.InstanceVNCPort, RemoteDest: xscommon.InstanceVNCIP, HostPortMin: self.config.HostPortMin, HostPortMax: self.config.HostPortMax, ResultKey: "local_vnc_port", }, new(xscommon.StepBootWait), &xscommon.StepTypeBootCommand{ Ctx: self.config.ctx, }, new(xscommon.StepWaitForShutdown), &xscommon.StepDetachVdi{ VdiUuidKey: "iso_vdi_uuid", }, &xscommon.StepAttachVdi{ VdiUuidKey: "tools_vdi_uuid", VdiType: xsclient.CD, }, new(xscommon.StepStartVmPaused), new(xscommon.StepBootWait), &xscommon.StepWaitForIP{ // do this again as could have new host and IP Chan: httpReqChan, Timeout: self.config.InstallTimeout, // @todo change this }, &xscommon.StepForwardPortOverSSH{ RemotePort: xscommon.InstanceSSHPort, RemoteDest: xscommon.InstanceSSHIP, HostPortMin: self.config.HostPortMin, HostPortMax: self.config.HostPortMax, ResultKey: "local_ssh_port", }, &communicator.StepConnect{ Config: &self.config.SSHConfig.Comm, Host: xscommon.CommHost, SSHConfig: xscommon.SSHConfigFunc(self.config.CommonConfig.SSHConfig), SSHPort: xscommon.SSHPort, }, new(xscommon.StepShutdown), &xscommon.StepDetachVdi{ VdiUuidKey: "floppy_vdi_uuid", }, new(xscommon.StepStartVmPaused), new(xscommon.StepBootWait), &xscommon.StepWaitForIP{ // do this again as could have new host and IP Chan: httpReqChan, Timeout: self.config.InstallTimeout, // @todo change this }, &xscommon.StepForwardPortOverSSH{ RemotePort: xscommon.InstanceSSHPort, RemoteDest: xscommon.InstanceSSHIP, HostPortMin: self.config.HostPortMin, HostPortMax: self.config.HostPortMax, ResultKey: "local_ssh_port", }, /*&common.StepConnectSSH{ SSHAddress: xscommon.SSHLocalAddress, SSHConfig: xscommon.SSHConfig, SSHWaitTimeout: self.config.SSHWaitTimeout, },*/ &communicator.StepConnectSSH{ Config: &self.config.SSHConfig.Comm, Host: xscommon.CommHost, SSHConfig: xscommon.SSHConfigFunc(self.config.CommonConfig.SSHConfig), SSHPort: xscommon.SSHPort, }, new(common.StepProvision), new(xscommon.StepShutdown), &xscommon.StepDetachVdi{ VdiUuidKey: "tools_vdi_uuid", }, &xscommon.StepExport{ OutputFormat: self.config.Format, }, } self.runner = &multistep.BasicRunner{Steps: steps} self.runner.Run(state) if rawErr, ok := state.GetOk("error"); ok { return nil, rawErr.(error) } // If we were interrupted or cancelled, then just exit. if _, ok := state.GetOk(multistep.StateCancelled); ok { return nil, errors.New("Build was cancelled.") } if _, ok := state.GetOk(multistep.StateHalted); ok { return nil, errors.New("Build was halted.") } artifactState := make(map[string]interface{}) if len(state.Get("virtualization_type").(string)) == 0 { artifactState["virtualizationType"] = "PV" } else { artifactState["virtualizationType"] = "HVM" } artifactState["diskSize"] = fmt.Sprintf("%d", self.config.DiskSize) artifactState["ramSize"] = fmt.Sprintf("%d", self.config.VMMemory) artifactState["vm_name"] = self.config.VMName artifact, _ := xscommon.NewArtifact(self.config.OutputDir, artifactState, state.Get("export_files").([]string)) return artifact, nil }
func (self *Builder) Run(ui packer.Ui, hook packer.Hook, cache packer.Cache) (packer.Artifact, error) { //Setup XAPI client client := xsclient.NewXenAPIClient(self.config.HostIp, self.config.Username, self.config.Password) artifactState := make(map[string]interface{}) err := client.Login() if err != nil { return nil, err.(error) } ui.Say("XAPI client session established") client.GetHosts() //Share state between the other steps using a statebag state := new(multistep.BasicStateBag) state.Put("cache", cache) state.Put("client", client) state.Put("config", self.config) state.Put("commonconfig", self.config.CommonConfig) state.Put("hook", hook) state.Put("ui", ui) httpReqChan := make(chan string, 1) //Build the steps steps := []multistep.Step{ &xscommon.StepPrepareOutputDir{ Force: self.config.PackerForce, Path: self.config.OutputDir, }, &xscommon.StepPrepareNfsExport{ NfsMount: self.config.NfsMount, }, &xscommon.StepHTTPServer{ Chan: httpReqChan, }, new(stepSnapshotInstance), &xscommon.StepStartOnHIMN{ PingTest: false, }, new(xscommon.StepGetVNCPort), &xscommon.StepForwardPortOverSSH{ RemotePort: xscommon.InstanceVNCPort, RemoteDest: xscommon.InstanceVNCIP, HostPortMin: self.config.HostPortMin, HostPortMax: self.config.HostPortMax, ResultKey: "local_vnc_port", }, &stepCopyCleanScript{ ScriptUrl: self.config.ScriptUrl, }, new(xscommon.StepBootWait), &xscommon.StepTypeBootCommand{ Ctx: self.config.ctx, }, new(xscommon.StepWaitForShutdown), new(stepRestoreNetwork), new(xscommon.StepStartVm), &xscommon.StepWaitForIP{ Chan: httpReqChan, Timeout: self.config.BootTimeout, // @todo change this }, &xscommon.StepForwardPortOverSSH{ // do this again as could have new host and IP RemotePort: xscommon.InstanceSSHPort, RemoteDest: xscommon.InstanceSSHIP, HostPortMin: self.config.HostPortMin, HostPortMax: self.config.HostPortMax, ResultKey: "local_ssh_port", }, &communicator.StepConnectSSH{ Config: &self.config.SSHConfig.Comm, Host: xscommon.CommHost, SSHConfig: xscommon.SSHConfigFunc(self.config.CommonConfig.SSHConfig), SSHPort: xscommon.SSHPort, }, new(common.StepProvision), new(xscommon.StepShutdown), &xscommon.StepExport{ OutputFormat: self.config.Format, }, } self.runner = &multistep.BasicRunner{Steps: steps} self.runner.Run(state) if rawErr, ok := state.GetOk("error"); ok { return nil, rawErr.(error) } // If we were interrupted or cancelled, then just exit. if _, ok := state.GetOk(multistep.StateCancelled); ok { return nil, errors.New("Build was cancelled.") } if _, ok := state.GetOk(multistep.StateHalted); ok { return nil, errors.New("Build was halted.") } if len(state.Get("virtualization_type").(string)) == 0 { artifactState["virtualizationType"] = "PV" } else { artifactState["virtualizationType"] = "HVM" } value, found := state.Get("configured_disk").(string) if found { artifactState["diskSize"] = value } value, found = state.Get("configured_ram").(string) if found { artifactState["ramSize"] = value } artifactState["vm_name"] = self.config.VMName artifact, _ := xscommon.NewArtifact(self.config.OutputDir, artifactState, state.Get("export_files").([]string)) return artifact, nil }