Adding legacy support for exporting VDI's as VHDs using the Transfer VM.
Signed-off-by: Rob Dobson <rob.dobson@citrix.com>
This commit is contained in:
parent
d63518195d
commit
a0e9c97c89
1089
builder/xenserver/common/client.go
Normal file
1089
builder/xenserver/common/client.go
Normal file
File diff suppressed because it is too large
Load Diff
@ -13,7 +13,7 @@ import (
|
|||||||
|
|
||||||
type StepExport struct{}
|
type StepExport struct{}
|
||||||
|
|
||||||
func downloadFile(url, filename string) (err error) {
|
func downloadFile(url, filename string, ui packer.Ui) (err error) {
|
||||||
|
|
||||||
// Create the file
|
// Create the file
|
||||||
fh, err := os.Create(filename)
|
fh, err := os.Create(filename)
|
||||||
@ -37,7 +37,42 @@ func downloadFile(url, filename string) (err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
io.Copy(fh, resp.Body)
|
|
||||||
|
var progress uint
|
||||||
|
var total uint
|
||||||
|
var percentage uint
|
||||||
|
var marker_len uint
|
||||||
|
|
||||||
|
progress = uint(0)
|
||||||
|
total = uint(resp.ContentLength)
|
||||||
|
percentage = uint(0)
|
||||||
|
marker_len = uint(5)
|
||||||
|
|
||||||
|
var buffer [4096]byte
|
||||||
|
for {
|
||||||
|
n, err := resp.Body.Read(buffer[:])
|
||||||
|
if err != nil && err != io.EOF {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
progress += uint(n)
|
||||||
|
|
||||||
|
if _, write_err := fh.Write(buffer[:n]); write_err != nil {
|
||||||
|
return write_err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err == io.EOF {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Increment percentage in multiples of marker_len
|
||||||
|
cur_percentage := ((progress * 100 / total) / marker_len) * marker_len
|
||||||
|
if cur_percentage > percentage {
|
||||||
|
percentage = cur_percentage
|
||||||
|
ui.Message(fmt.Sprintf("Downloading... %d%%", percentage))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -75,7 +110,7 @@ func (StepExport) Run(state multistep.StateBag) multistep.StepAction {
|
|||||||
export_filename := fmt.Sprintf("%s/%s.xva", config.OutputDir, config.VMName)
|
export_filename := fmt.Sprintf("%s/%s.xva", config.OutputDir, config.VMName)
|
||||||
|
|
||||||
ui.Say("Getting XVA " + export_url)
|
ui.Say("Getting XVA " + export_url)
|
||||||
err = downloadFile(export_url, export_filename)
|
err = downloadFile(export_url, export_filename, ui)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ui.Error(fmt.Sprintf("Could not download XVA: %s", err.Error()))
|
ui.Error(fmt.Sprintf("Could not download XVA: %s", err.Error()))
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
@ -100,24 +135,63 @@ func (StepExport) Run(state multistep.StateBag) multistep.StepAction {
|
|||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
|
|
||||||
// Basic auth in URL request is required as session token is not
|
// Work out XenServer version
|
||||||
// accepted for some reason.
|
hosts, err := client.GetHosts()
|
||||||
// @todo: raise with XAPI team.
|
|
||||||
disk_export_url := fmt.Sprintf("https://%s:%s@%s/export_raw_vdi?vdi=%s%s",
|
if err != nil {
|
||||||
client.Username,
|
ui.Error(fmt.Sprintf("Could not retrieve hosts in the pool: %s", err.Error()))
|
||||||
client.Password,
|
return multistep.ActionHalt
|
||||||
client.Host,
|
}
|
||||||
disk_uuid,
|
host := hosts[0]
|
||||||
extrauri)
|
host_software_versions, err := host.GetSoftwareVersion()
|
||||||
|
xs_version := host_software_versions["product_version"].(string)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ui.Error(fmt.Sprintf("Could not get the software version: %s", err.Error()))
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
var disk_export_url string
|
||||||
|
|
||||||
|
// @todo: check for 6.5 SP1
|
||||||
|
if xs_version <= "6.5.0" && config.Format == "vdi_vhd" {
|
||||||
|
// Export the VHD using a Transfer VM
|
||||||
|
|
||||||
|
disk_export_url, err = disk.Expose("vhd")
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
ui.Error(fmt.Sprintf("Failed to expose disk %s: %s", disk_uuid, err.Error()))
|
||||||
|
return multistep.ActionHalt
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Use the preferred direct export from XAPI
|
||||||
|
// Basic auth in URL request is required as session token is not
|
||||||
|
// accepted for some reason.
|
||||||
|
// @todo: raise with XAPI team.
|
||||||
|
disk_export_url = fmt.Sprintf("https://%s:%s@%s/export_raw_vdi?vdi=%s%s",
|
||||||
|
client.Username,
|
||||||
|
client.Password,
|
||||||
|
client.Host,
|
||||||
|
disk_uuid,
|
||||||
|
extrauri)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
disk_export_filename := fmt.Sprintf("%s/%s%s", config.OutputDir, disk_uuid, suffix)
|
disk_export_filename := fmt.Sprintf("%s/%s%s", config.OutputDir, disk_uuid, suffix)
|
||||||
|
|
||||||
ui.Say("Getting VDI " + disk_export_url)
|
ui.Say("Getting VDI " + disk_export_url)
|
||||||
err = downloadFile(disk_export_url, disk_export_filename)
|
err = downloadFile(disk_export_url, disk_export_filename, ui)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ui.Error(fmt.Sprintf("Could not download VDI: %s", err.Error()))
|
ui.Error(fmt.Sprintf("Could not download VDI: %s", err.Error()))
|
||||||
return multistep.ActionHalt
|
return multistep.ActionHalt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Call unexpose in case a TVM was used. The call is harmless
|
||||||
|
// if that is not the case.
|
||||||
|
disk.Unexpose()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
Loading…
Reference in New Issue
Block a user