Merge branch 'master' of https://github.com/ddelnano/packer-plugin-xenserver into destroy-vifs
This commit is contained in:
commit
30400a41a0
6
.github/dependabot.yml
vendored
Normal file
6
.github/dependabot.yml
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "gomod" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "daily"
|
24
.github/workflows/go-test.yml
vendored
Normal file
24
.github/workflows/go-test.yml
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
name: go-test
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
pull_request:
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
go-tests:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
- name: Unshallow
|
||||
run: git fetch --prune --unshallow
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16
|
||||
- name: Run go tests
|
||||
run: go test -race -count 1 ./... -timeout=3m
|
10
.github/workflows/release.yml
vendored
10
.github/workflows/release.yml
vendored
@ -25,16 +25,16 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.17
|
||||
go-version: 1.16
|
||||
- name: Describe plugin
|
||||
id: plugin_describe
|
||||
run: echo "::set-output name=api_version::$(go run . describe | jq -r '.api_version')"
|
||||
- name: Import GPG key
|
||||
id: import_gpg
|
||||
uses: hashicorp/ghaction-import-gpg@v2.1.0
|
||||
env:
|
||||
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
||||
uses: crazy-max/ghaction-import-gpg@v5.0.0
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
passphrase: ${{ secrets.GPG_PASSPHRASE }}
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
with:
|
||||
|
@ -62,7 +62,7 @@ $ cp builder-xenserver-iso ~/.packer.d/plugins/packer-builder-xenserver-iso
|
||||
# Documentation
|
||||
|
||||
For complete documentation on configuration commands, see [the
|
||||
xenserver-iso docs](docs/builders/xenserver-iso.html.markdown)
|
||||
xenserver-iso docs](docs/builders/iso/xenserver-iso.html.markdown)
|
||||
|
||||
## Support
|
||||
|
||||
|
@ -624,6 +624,17 @@ func ConnectNetwork(c *Connection, networkRef xenapi.NetworkRef, vmRef xenapi.VM
|
||||
return &vif, nil
|
||||
}
|
||||
|
||||
func AddVMTags(c *Connection, vmRef xenapi.VMRef, tags []string) error {
|
||||
for _, tag := range tags {
|
||||
log.Printf("Adding tag %s to VM %s\n", tag, vmRef)
|
||||
err := c.GetClient().VM.AddTags(c.session, vmRef, tag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Setters
|
||||
|
||||
func (self *VM) SetIsATemplate(is_a_template bool) (err error) {
|
||||
|
@ -20,10 +20,11 @@ type CommonConfig struct {
|
||||
VMName string `mapstructure:"vm_name"`
|
||||
VMDescription string `mapstructure:"vm_description"`
|
||||
SrName string `mapstructure:"sr_name"`
|
||||
SrISOName string `mapstructure:"sr_iso_name"`
|
||||
SrISOName string `mapstructure:"sr_iso_name" required:"false"`
|
||||
FloppyFiles []string `mapstructure:"floppy_files"`
|
||||
NetworkNames []string `mapstructure:"network_names"`
|
||||
ExportNetworkNames []string `mapstructure:"export_network_names"`
|
||||
VMTags []string `mapstructure:"vm_tags"`
|
||||
|
||||
HostPortMin uint `mapstructure:"host_port_min"`
|
||||
HostPortMax uint `mapstructure:"host_port_max"`
|
||||
@ -225,29 +226,11 @@ func (c CommonConfig) ShouldKeepVM(state multistep.StateBag) bool {
|
||||
}
|
||||
|
||||
func (config CommonConfig) GetSR(c *Connection) (xenapi.SRRef, error) {
|
||||
var srRef xenapi.SRRef
|
||||
if config.SrName == "" {
|
||||
hostRef, err := c.GetClient().Session.GetThisHost(c.session, c.session)
|
||||
|
||||
if err != nil {
|
||||
return srRef, err
|
||||
}
|
||||
|
||||
pools, err := c.GetClient().Pool.GetAllRecords(c.session)
|
||||
|
||||
if err != nil {
|
||||
return srRef, err
|
||||
}
|
||||
|
||||
for _, pool := range pools {
|
||||
if pool.Master == hostRef {
|
||||
return pool.DefaultSR, nil
|
||||
}
|
||||
}
|
||||
|
||||
return srRef, errors.New(fmt.Sprintf("failed to find default SR on host '%s'", hostRef))
|
||||
|
||||
return getDefaultSR(c)
|
||||
} else {
|
||||
var srRef xenapi.SRRef
|
||||
|
||||
// Use the provided name label to find the SR to use
|
||||
srs, err := c.GetClient().SR.GetByNameLabel(c.session, config.SrName)
|
||||
|
||||
@ -269,11 +252,11 @@ func (config CommonConfig) GetSR(c *Connection) (xenapi.SRRef, error) {
|
||||
func (config CommonConfig) GetISOSR(c *Connection) (xenapi.SRRef, error) {
|
||||
var srRef xenapi.SRRef
|
||||
if config.SrISOName == "" {
|
||||
return srRef, errors.New("sr_iso_name must be specified in the packer configuration")
|
||||
return getDefaultSR(c)
|
||||
|
||||
} else {
|
||||
// Use the provided name label to find the SR to use
|
||||
srs, err := c.GetClient().SR.GetByNameLabel(c.session, config.SrName)
|
||||
srs, err := c.GetClient().SR.GetByNameLabel(c.session, config.SrISOName)
|
||||
|
||||
if err != nil {
|
||||
return srRef, err
|
||||
@ -281,11 +264,42 @@ func (config CommonConfig) GetISOSR(c *Connection) (xenapi.SRRef, error) {
|
||||
|
||||
switch {
|
||||
case len(srs) == 0:
|
||||
return srRef, fmt.Errorf("Couldn't find a SR with the specified name-label '%s'", config.SrName)
|
||||
return srRef, fmt.Errorf("Couldn't find a SR with the specified name-label '%s'", config.SrISOName)
|
||||
case len(srs) > 1:
|
||||
return srRef, fmt.Errorf("Found more than one SR with the name '%s'. The name must be unique", config.SrName)
|
||||
return srRef, fmt.Errorf("Found more than one SR with the name '%s'. The name must be unique", config.SrISOName)
|
||||
}
|
||||
|
||||
return srs[0], nil
|
||||
}
|
||||
}
|
||||
|
||||
func getDefaultSR(c *Connection) (xenapi.SRRef, error) {
|
||||
var srRef xenapi.SRRef
|
||||
client := c.GetClient()
|
||||
hostRef, err := client.Session.GetThisHost(c.session, c.session)
|
||||
|
||||
if err != nil {
|
||||
return srRef, err
|
||||
}
|
||||
|
||||
// The current version of the go-xen-api-client does not fully support XenAPI version 8.2
|
||||
// In particular, some values for the pool `allowed_operations` are not recognised, resulting
|
||||
// in a parse error when retrieving pool records. As a workaround, we only fetch pool refs.
|
||||
pool_refs, err := client.Pool.GetAll(c.session)
|
||||
|
||||
if err != nil {
|
||||
return srRef, err
|
||||
}
|
||||
|
||||
for _, pool_ref := range pool_refs {
|
||||
pool_master, err := client.Pool.GetMaster(c.session, pool_ref)
|
||||
if err != nil {
|
||||
return srRef, err
|
||||
}
|
||||
if pool_master == hostRef {
|
||||
return client.Pool.GetDefaultSR(c.session, pool_ref)
|
||||
}
|
||||
}
|
||||
|
||||
return srRef, errors.New(fmt.Sprintf("failed to find default SR on host '%s'", hostRef))
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//go:generate mapstructure-to-hcl2 -type Config
|
||||
//go:generate packer-sdc mapstructure-to-hcl2 -type Config
|
||||
package common
|
||||
|
||||
import (
|
||||
@ -20,12 +20,12 @@ type Config struct {
|
||||
DiskSize uint `mapstructure:"disk_size"`
|
||||
CloneTemplate string `mapstructure:"clone_template"`
|
||||
VMOtherConfig map[string]string `mapstructure:"vm_other_config"`
|
||||
VMTags []string `mapstructure:"vm_tags"`
|
||||
|
||||
ISOChecksum string `mapstructure:"iso_checksum"`
|
||||
ISOChecksumType string `mapstructure:"iso_checksum_type"`
|
||||
ISOUrls []string `mapstructure:"iso_urls"`
|
||||
ISOUrl string `mapstructure:"iso_url"`
|
||||
ISOName string `mapstructure:"iso_name"`
|
||||
ISOChecksum string `mapstructure:"iso_checksum"`
|
||||
ISOUrls []string `mapstructure:"iso_urls"`
|
||||
ISOUrl string `mapstructure:"iso_url"`
|
||||
ISOName string `mapstructure:"iso_name"`
|
||||
|
||||
PlatformArgs map[string]string `mapstructure:"platform_args"`
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Code generated by "mapstructure-to-hcl2 -type Config"; DO NOT EDIT.
|
||||
// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT.
|
||||
|
||||
package common
|
||||
|
||||
@ -12,6 +12,7 @@ import (
|
||||
type FlatConfig struct {
|
||||
PackerBuildName *string `mapstructure:"packer_build_name" cty:"packer_build_name" hcl:"packer_build_name"`
|
||||
PackerBuilderType *string `mapstructure:"packer_builder_type" cty:"packer_builder_type" hcl:"packer_builder_type"`
|
||||
PackerCoreVersion *string `mapstructure:"packer_core_version" cty:"packer_core_version" hcl:"packer_core_version"`
|
||||
PackerDebug *bool `mapstructure:"packer_debug" cty:"packer_debug" hcl:"packer_debug"`
|
||||
PackerForce *bool `mapstructure:"packer_force" cty:"packer_force" hcl:"packer_force"`
|
||||
PackerOnError *string `mapstructure:"packer_on_error" cty:"packer_on_error" hcl:"packer_on_error"`
|
||||
@ -23,10 +24,11 @@ type FlatConfig struct {
|
||||
VMName *string `mapstructure:"vm_name" cty:"vm_name" hcl:"vm_name"`
|
||||
VMDescription *string `mapstructure:"vm_description" cty:"vm_description" hcl:"vm_description"`
|
||||
SrName *string `mapstructure:"sr_name" cty:"sr_name" hcl:"sr_name"`
|
||||
SrISOName *string `mapstructure:"sr_iso_name" cty:"sr_iso_name" hcl:"sr_iso_name"`
|
||||
SrISOName *string `mapstructure:"sr_iso_name" required:"false" cty:"sr_iso_name" hcl:"sr_iso_name"`
|
||||
FloppyFiles []string `mapstructure:"floppy_files" cty:"floppy_files" hcl:"floppy_files"`
|
||||
NetworkNames []string `mapstructure:"network_names" cty:"network_names" hcl:"network_names"`
|
||||
ExportNetworkNames []string `mapstructure:"export_network_names" cty:"export_network_names" hcl:"export_network_names"`
|
||||
VMTags []string `mapstructure:"vm_tags" cty:"vm_tags" hcl:"vm_tags"`
|
||||
HostPortMin *uint `mapstructure:"host_port_min" cty:"host_port_min" hcl:"host_port_min"`
|
||||
HostPortMax *uint `mapstructure:"host_port_max" cty:"host_port_max" hcl:"host_port_max"`
|
||||
BootCommand []string `mapstructure:"boot_command" cty:"boot_command" hcl:"boot_command"`
|
||||
@ -100,7 +102,6 @@ type FlatConfig struct {
|
||||
CloneTemplate *string `mapstructure:"clone_template" cty:"clone_template" hcl:"clone_template"`
|
||||
VMOtherConfig map[string]string `mapstructure:"vm_other_config" cty:"vm_other_config" hcl:"vm_other_config"`
|
||||
ISOChecksum *string `mapstructure:"iso_checksum" cty:"iso_checksum" hcl:"iso_checksum"`
|
||||
ISOChecksumType *string `mapstructure:"iso_checksum_type" cty:"iso_checksum_type" hcl:"iso_checksum_type"`
|
||||
ISOUrls []string `mapstructure:"iso_urls" cty:"iso_urls" hcl:"iso_urls"`
|
||||
ISOUrl *string `mapstructure:"iso_url" cty:"iso_url" hcl:"iso_url"`
|
||||
ISOName *string `mapstructure:"iso_name" cty:"iso_name" hcl:"iso_name"`
|
||||
@ -125,6 +126,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
s := map[string]hcldec.Spec{
|
||||
"packer_build_name": &hcldec.AttrSpec{Name: "packer_build_name", Type: cty.String, Required: false},
|
||||
"packer_builder_type": &hcldec.AttrSpec{Name: "packer_builder_type", Type: cty.String, Required: false},
|
||||
"packer_core_version": &hcldec.AttrSpec{Name: "packer_core_version", Type: cty.String, Required: false},
|
||||
"packer_debug": &hcldec.AttrSpec{Name: "packer_debug", Type: cty.Bool, Required: false},
|
||||
"packer_force": &hcldec.AttrSpec{Name: "packer_force", Type: cty.Bool, Required: false},
|
||||
"packer_on_error": &hcldec.AttrSpec{Name: "packer_on_error", Type: cty.String, Required: false},
|
||||
@ -140,6 +142,7 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
"floppy_files": &hcldec.AttrSpec{Name: "floppy_files", Type: cty.List(cty.String), Required: false},
|
||||
"network_names": &hcldec.AttrSpec{Name: "network_names", Type: cty.List(cty.String), Required: false},
|
||||
"export_network_names": &hcldec.AttrSpec{Name: "export_network_names", Type: cty.List(cty.String), Required: false},
|
||||
"vm_tags": &hcldec.AttrSpec{Name: "vm_tags", Type: cty.List(cty.String), Required: false},
|
||||
"host_port_min": &hcldec.AttrSpec{Name: "host_port_min", Type: cty.Number, Required: false},
|
||||
"host_port_max": &hcldec.AttrSpec{Name: "host_port_max", Type: cty.Number, Required: false},
|
||||
"boot_command": &hcldec.AttrSpec{Name: "boot_command", Type: cty.List(cty.String), Required: false},
|
||||
@ -213,7 +216,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
"clone_template": &hcldec.AttrSpec{Name: "clone_template", Type: cty.String, Required: false},
|
||||
"vm_other_config": &hcldec.AttrSpec{Name: "vm_other_config", Type: cty.Map(cty.String), Required: false},
|
||||
"iso_checksum": &hcldec.AttrSpec{Name: "iso_checksum", Type: cty.String, Required: false},
|
||||
"iso_checksum_type": &hcldec.AttrSpec{Name: "iso_checksum_type", Type: cty.String, Required: false},
|
||||
"iso_urls": &hcldec.AttrSpec{Name: "iso_urls", Type: cty.List(cty.String), Required: false},
|
||||
"iso_url": &hcldec.AttrSpec{Name: "iso_url", Type: cty.String, Required: false},
|
||||
"iso_name": &hcldec.AttrSpec{Name: "iso_name", Type: cty.String, Required: false},
|
||||
|
@ -1,4 +1,4 @@
|
||||
package iso
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -9,18 +9,21 @@ import (
|
||||
"github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
xenapi "github.com/terra-farm/go-xen-api-client"
|
||||
xsclient "github.com/terra-farm/go-xen-api-client"
|
||||
xscommon "github.com/xenserver/packer-builder-xenserver/builder/xenserver/common"
|
||||
)
|
||||
|
||||
type stepCreateInstance struct {
|
||||
type StepCreateInstance struct {
|
||||
// The XVA builder assumes it will boot an instance with an OS installed on its disks
|
||||
// while the ISO builder needs packer to create a disk for an OS to be installed on.
|
||||
AssumePreInstalledOS bool
|
||||
|
||||
instance *xsclient.VMRef
|
||||
vdi *xsclient.VDIRef
|
||||
}
|
||||
|
||||
func (self *stepCreateInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
func (self *StepCreateInstance) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
|
||||
c := state.Get("client").(*xscommon.Connection)
|
||||
config := state.Get("config").(xscommon.Config)
|
||||
c := state.Get("client").(*Connection)
|
||||
config := state.Get("config").(Config)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
ui.Say("Step: Create Instance")
|
||||
@ -101,37 +104,45 @@ func (self *stepCreateInstance) Run(ctx context.Context, state multistep.StateBa
|
||||
}
|
||||
}
|
||||
|
||||
// Create VDI for the instance
|
||||
sr, err := config.GetSR(c)
|
||||
if !self.AssumePreInstalledOS {
|
||||
err = c.GetClient().VM.RemoveFromOtherConfig(c.GetSessionRef(), instance, "disks")
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Error removing disks from VM other-config: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Unable to get SR: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
// Create VDI for the instance
|
||||
sr, err := config.GetSR(c)
|
||||
|
||||
ui.Say(fmt.Sprintf("Using the following SR for the VM: %s", sr))
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Unable to get SR: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
vdi, err := c.GetClient().VDI.Create(c.GetSessionRef(), xenapi.VDIRecord{
|
||||
NameLabel: "Packer-disk",
|
||||
VirtualSize: int(config.DiskSize * 1024 * 1024),
|
||||
Type: "user",
|
||||
Sharable: false,
|
||||
ReadOnly: false,
|
||||
SR: sr,
|
||||
OtherConfig: map[string]string{
|
||||
"temp": "temp",
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Unable to create packer disk VDI: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
self.vdi = &vdi
|
||||
ui.Say(fmt.Sprintf("Using the following SR for the VM: %s", sr))
|
||||
|
||||
err = xscommon.ConnectVdi(c, instance, vdi, xsclient.VbdTypeDisk)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Unable to connect packer disk VDI: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
vdi, err := c.GetClient().VDI.Create(c.GetSessionRef(), xenapi.VDIRecord{
|
||||
NameLabel: "Packer-disk",
|
||||
VirtualSize: int(config.DiskSize * 1024 * 1024),
|
||||
Type: "user",
|
||||
Sharable: false,
|
||||
ReadOnly: false,
|
||||
SR: sr,
|
||||
OtherConfig: map[string]string{
|
||||
"temp": "temp",
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Unable to create packer disk VDI: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
self.vdi = &vdi
|
||||
|
||||
err = ConnectVdi(c, instance, vdi, xsclient.VbdTypeDisk)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Unable to connect packer disk VDI: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
}
|
||||
|
||||
// Connect Network
|
||||
@ -168,7 +179,7 @@ func (self *stepCreateInstance) Run(ctx context.Context, state multistep.StateBa
|
||||
}
|
||||
|
||||
log.Printf("Creating VIF on network '%s' on VM '%s'\n", network, instance)
|
||||
_, err = xscommon.ConnectNetwork(c, network, instance, "0")
|
||||
_, err = ConnectNetwork(c, network, instance, "0")
|
||||
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Failed to create VIF with error: %v", err))
|
||||
@ -197,7 +208,7 @@ func (self *stepCreateInstance) Run(ctx context.Context, state multistep.StateBa
|
||||
|
||||
//we need the VIF index string
|
||||
vifIndexString := fmt.Sprintf("%d", i)
|
||||
_, err = xscommon.ConnectNetwork(c, networks[0], instance, vifIndexString)
|
||||
_, err = ConnectNetwork(c, networks[0], instance, vifIndexString)
|
||||
|
||||
if err != nil {
|
||||
ui.Say(fmt.Sprintf("Failed to connect VIF with error: %v", err.Error()))
|
||||
@ -205,6 +216,12 @@ func (self *stepCreateInstance) Run(ctx context.Context, state multistep.StateBa
|
||||
}
|
||||
}
|
||||
|
||||
err = AddVMTags(c, instance, config.VMTags)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Failed to add tags: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
instanceId, err := c.GetClient().VM.GetUUID(c.GetSessionRef(), instance)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Unable to get VM UUID: %s", err.Error()))
|
||||
@ -217,14 +234,14 @@ func (self *stepCreateInstance) Run(ctx context.Context, state multistep.StateBa
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (self *stepCreateInstance) Cleanup(state multistep.StateBag) {
|
||||
config := state.Get("config").(xscommon.Config)
|
||||
func (self *StepCreateInstance) Cleanup(state multistep.StateBag) {
|
||||
config := state.Get("config").(Config)
|
||||
if config.ShouldKeepVM(state) {
|
||||
return
|
||||
}
|
||||
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
c := state.Get("client").(*xscommon.Connection)
|
||||
c := state.Get("client").(*Connection)
|
||||
|
||||
if self.instance != nil {
|
||||
ui.Say("Destroying VM")
|
44
builder/xenserver/common/step_find_or_upload_vdi.go
Normal file
44
builder/xenserver/common/step_find_or_upload_vdi.go
Normal file
@ -0,0 +1,44 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
"github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
)
|
||||
|
||||
type StepFindOrUploadVdi struct {
|
||||
StepUploadVdi
|
||||
}
|
||||
|
||||
func (self *StepFindOrUploadVdi) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
c := state.Get("client").(*Connection)
|
||||
vdiName := self.VdiNameFunc()
|
||||
|
||||
ui.Say(fmt.Sprintf("Attemping to find VDI '%s'", vdiName))
|
||||
|
||||
vdis, err := c.client.VDI.GetByNameLabel(c.session, vdiName)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Failed to find VDI '%s' by name label: %s", vdiName, err.Error()))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
if len(vdis) > 1 {
|
||||
ui.Error(fmt.Sprintf("Found more than one VDI with name '%s'. Name must be unique", vdiName))
|
||||
return multistep.ActionHalt
|
||||
} else if len(vdis) == 1 {
|
||||
|
||||
vdi := vdis[0]
|
||||
|
||||
vdiUuid, err := c.client.VDI.GetUUID(c.session, vdi)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Unable to get UUID of VDI '%s': %s", vdiName, err.Error()))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
state.Put(self.VdiUuidKey, vdiUuid)
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
return self.uploadVdi(ctx, state)
|
||||
}
|
@ -18,7 +18,7 @@ type StepUploadVdi struct {
|
||||
VdiUuidKey string
|
||||
}
|
||||
|
||||
func (self *StepUploadVdi) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
func (self *StepUploadVdi) uploadVdi(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
config := state.Get("commonconfig").(CommonConfig)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
c := state.Get("client").(*Connection)
|
||||
@ -33,10 +33,8 @@ func (self *StepUploadVdi) Run(ctx context.Context, state multistep.StateBag) mu
|
||||
ui.Say(fmt.Sprintf("Step: Upload VDI '%s'", vdiName))
|
||||
|
||||
// Create VDI for the image
|
||||
srs, err := c.client.SR.GetAll(c.session)
|
||||
ui.Say(fmt.Sprintf("Step: Found SRs '%v'", srs))
|
||||
|
||||
sr, err := config.GetISOSR(c)
|
||||
ui.Say(fmt.Sprintf("Step: Found SR for upload '%v'", sr))
|
||||
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Unable to get SR: %v", err))
|
||||
@ -96,6 +94,10 @@ func (self *StepUploadVdi) Run(ctx context.Context, state multistep.StateBag) mu
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (self *StepUploadVdi) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
return self.uploadVdi(ctx, state)
|
||||
}
|
||||
|
||||
func (self *StepUploadVdi) Cleanup(state multistep.StateBag) {
|
||||
config := state.Get("commonconfig").(CommonConfig)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
@ -40,7 +40,7 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
|
||||
}, raws...)
|
||||
|
||||
if err != nil {
|
||||
packer.MultiErrorAppend(errs, err)
|
||||
errs = packer.MultiErrorAppend(errs, err)
|
||||
}
|
||||
|
||||
errs = packer.MultiErrorAppend(
|
||||
@ -95,12 +95,11 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
|
||||
// Template substitution
|
||||
|
||||
templates := map[string]*string{
|
||||
"clone_template": &self.config.CloneTemplate,
|
||||
"iso_checksum": &self.config.ISOChecksum,
|
||||
"iso_checksum_type": &self.config.ISOChecksumType,
|
||||
"iso_url": &self.config.ISOUrl,
|
||||
"iso_name": &self.config.ISOName,
|
||||
"install_timeout": &self.config.RawInstallTimeout,
|
||||
"clone_template": &self.config.CloneTemplate,
|
||||
"iso_checksum": &self.config.ISOChecksum,
|
||||
"iso_url": &self.config.ISOUrl,
|
||||
"iso_name": &self.config.ISOName,
|
||||
"install_timeout": &self.config.RawInstallTimeout,
|
||||
}
|
||||
for i := range self.config.ISOUrls {
|
||||
templates[fmt.Sprintf("iso_urls[%d]", i)] = &self.config.ISOUrls[i]
|
||||
@ -115,23 +114,8 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
|
||||
}
|
||||
|
||||
if self.config.ISOName == "" {
|
||||
|
||||
// If ISO name is not specified, assume a URL and checksum has been provided.
|
||||
|
||||
if self.config.ISOChecksumType == "" {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, errors.New("The iso_checksum_type must be specified."))
|
||||
} else {
|
||||
self.config.ISOChecksumType = strings.ToLower(self.config.ISOChecksumType)
|
||||
if self.config.ISOChecksumType != "none" {
|
||||
if self.config.ISOChecksum == "" {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, errors.New("Due to the file size being large, an iso_checksum is required."))
|
||||
} else {
|
||||
self.config.ISOChecksum = strings.ToLower(self.config.ISOChecksum)
|
||||
}
|
||||
}
|
||||
}
|
||||
self.config.ISOChecksum = strings.ToLower(self.config.ISOChecksum)
|
||||
|
||||
if len(self.config.ISOUrls) == 0 {
|
||||
if self.config.ISOUrl == "" {
|
||||
@ -140,10 +124,25 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
|
||||
} else {
|
||||
self.config.ISOUrls = []string{self.config.ISOUrl}
|
||||
}
|
||||
|
||||
} else if self.config.ISOUrl != "" {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, errors.New("Only one of iso_url or iso_urls may be specified."))
|
||||
}
|
||||
|
||||
//The SDK can validate the ISO checksum and other sanity checks on the url.
|
||||
iso_config := commonsteps.ISOConfig{
|
||||
ISOChecksum: self.config.ISOChecksum,
|
||||
ISOUrls: self.config.ISOUrls,
|
||||
}
|
||||
|
||||
_, iso_errs := iso_config.Prepare(nil)
|
||||
if iso_errs != nil {
|
||||
for _, this_err := range iso_errs {
|
||||
errs = packer.MultiErrorAppend(errs, this_err)
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
// An ISO name has been provided. It should be attached from an available SR.
|
||||
@ -187,7 +186,6 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
|
||||
Url: self.config.ISOUrls,
|
||||
},
|
||||
}
|
||||
|
||||
steps := []multistep.Step{
|
||||
&xscommon.StepPrepareOutputDir{
|
||||
Force: self.config.PackerForce,
|
||||
@ -212,20 +210,22 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
|
||||
},
|
||||
VdiUuidKey: "floppy_vdi_uuid",
|
||||
},
|
||||
&xscommon.StepUploadVdi{
|
||||
VdiNameFunc: func() string {
|
||||
if len(self.config.ISOUrls) > 0 {
|
||||
return path.Base(self.config.ISOUrls[0])
|
||||
}
|
||||
return ""
|
||||
&xscommon.StepFindOrUploadVdi{
|
||||
xscommon.StepUploadVdi{
|
||||
VdiNameFunc: func() string {
|
||||
if len(self.config.ISOUrls) > 0 {
|
||||
return path.Base(self.config.ISOUrls[0])
|
||||
}
|
||||
return ""
|
||||
},
|
||||
ImagePathFunc: func() string {
|
||||
if isoPath, ok := state.GetOk("iso_path"); ok {
|
||||
return isoPath.(string)
|
||||
}
|
||||
return ""
|
||||
},
|
||||
VdiUuidKey: "iso_vdi_uuid",
|
||||
},
|
||||
ImagePathFunc: func() string {
|
||||
if isoPath, ok := state.GetOk("iso_path"); ok {
|
||||
return isoPath.(string)
|
||||
}
|
||||
return ""
|
||||
},
|
||||
VdiUuidKey: "iso_vdi_uuid",
|
||||
},
|
||||
&xscommon.StepFindVdi{
|
||||
VdiName: self.config.ToolsIsoName,
|
||||
@ -235,7 +235,9 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
|
||||
VdiName: self.config.ISOName,
|
||||
VdiUuidKey: "isoname_vdi_uuid",
|
||||
},
|
||||
new(stepCreateInstance),
|
||||
&xscommon.StepCreateInstance{
|
||||
AssumePreInstalledOS: false,
|
||||
},
|
||||
&xscommon.StepAttachVdi{
|
||||
VdiUuidKey: "floppy_vdi_uuid",
|
||||
VdiType: xsclient.VbdTypeFloppy,
|
||||
|
@ -5,21 +5,22 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
"github.com/hashicorp/packer-plugin-sdk/common"
|
||||
)
|
||||
|
||||
|
||||
func testConfig() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"remote_host": "localhost",
|
||||
"remote_username": "admin",
|
||||
"remote_password": "admin",
|
||||
"vm_name": "foo",
|
||||
"iso_checksum": "foo",
|
||||
"iso_checksum_type": "md5",
|
||||
"iso_checksum": "md5:A221725EE181A44C67E25BD6A2516742",
|
||||
"iso_url": "http://www.google.com/",
|
||||
"shutdown_command": "yes",
|
||||
"ssh_username": "foo",
|
||||
|
||||
packer.BuildNameConfigKey: "foo",
|
||||
common.BuildNameConfigKey: "foo",
|
||||
}
|
||||
}
|
||||
|
||||
@ -179,9 +180,20 @@ func TestBuilderPrepare_ISOChecksum(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
// Test good
|
||||
|
||||
b = Builder{}
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
// Test bad
|
||||
config["iso_checksum"] = ""
|
||||
_, warns, err := b.Prepare(config)
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
@ -189,80 +201,9 @@ func TestBuilderPrepare_ISOChecksum(t *testing.T) {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
// Test good
|
||||
config["iso_checksum"] = "FOo"
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
if b.config.ISOChecksum != "foo" {
|
||||
t.Fatalf("should've lowercased: %s", b.config.ISOChecksum)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_ISOChecksumType(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
// Test bad
|
||||
config["iso_checksum_type"] = ""
|
||||
_, warns, err := b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
// Test good
|
||||
config["iso_checksum_type"] = "mD5"
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
if b.config.ISOChecksumType != "md5" {
|
||||
t.Fatalf("should've lowercased: %s", b.config.ISOChecksumType)
|
||||
}
|
||||
|
||||
// Test unknown
|
||||
config["iso_checksum_type"] = "fake"
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
if len(warns) > 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
if err == nil {
|
||||
t.Fatal("should have error")
|
||||
}
|
||||
|
||||
// Test none
|
||||
config["iso_checksum_type"] = "none"
|
||||
b = Builder{}
|
||||
_, warns, err = b.Prepare(config)
|
||||
// @todo: give warning in this case?
|
||||
/*
|
||||
if len(warns) == 0 {
|
||||
t.Fatalf("bad: %#v", warns)
|
||||
}
|
||||
*/
|
||||
if err != nil {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
if b.config.ISOChecksumType != "none" {
|
||||
t.Fatalf("should've lowercased: %s", b.config.ISOChecksumType)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_ISOUrl(t *testing.T) {
|
||||
var b Builder
|
||||
|
@ -3,7 +3,6 @@ package xva
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
@ -38,11 +37,12 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
|
||||
}, raws...)
|
||||
|
||||
if err != nil {
|
||||
packer.MultiErrorAppend(errs, err)
|
||||
errs = packer.MultiErrorAppend(errs, err)
|
||||
}
|
||||
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, self.config.CommonConfig.Prepare(self.config.GetInterpContext(), &self.config.PackerConfig)...)
|
||||
errs = packer.MultiErrorAppend(errs, self.config.SSHConfig.Prepare(self.config.GetInterpContext())...)
|
||||
|
||||
// Set default values
|
||||
if self.config.VCPUsMax == 0 {
|
||||
@ -74,8 +74,12 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
|
||||
|
||||
// Validation
|
||||
|
||||
if self.config.SourcePath == "" {
|
||||
errs = packer.MultiErrorAppend(errs, fmt.Errorf("A source_path must be specified"))
|
||||
if self.config.SourcePath == "" && self.config.CloneTemplate == "" {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, errors.New("Either source_path or clone_template must be specified"))
|
||||
} else if self.config.SourcePath != "" && self.config.CloneTemplate != "" {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, errors.New("Only one of source_path and clone_template must be specified"))
|
||||
}
|
||||
|
||||
if len(errs.Errors) > 0 {
|
||||
@ -101,7 +105,7 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
|
||||
//Share state between the other steps using a statebag
|
||||
state := new(multistep.BasicStateBag)
|
||||
state.Put("client", c)
|
||||
// state.Put("config", self.config)
|
||||
state.Put("config", self.config)
|
||||
state.Put("commonconfig", self.config.CommonConfig)
|
||||
state.Put("hook", hook)
|
||||
state.Put("ui", ui)
|
||||
@ -116,8 +120,11 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
|
||||
},
|
||||
&commonsteps.StepCreateFloppy{
|
||||
Files: self.config.FloppyFiles,
|
||||
Label: "cidata",
|
||||
},
|
||||
&xscommon.StepHTTPServer{
|
||||
Chan: httpReqChan,
|
||||
},
|
||||
new(xscommon.StepHTTPServer),
|
||||
&xscommon.StepUploadVdi{
|
||||
VdiNameFunc: func() string {
|
||||
return "Packer-floppy-disk"
|
||||
@ -134,6 +141,9 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
|
||||
VdiName: self.config.ToolsIsoName,
|
||||
VdiUuidKey: "tools_vdi_uuid",
|
||||
},
|
||||
&xscommon.StepCreateInstance{
|
||||
AssumePreInstalledOS: true,
|
||||
},
|
||||
new(stepImportInstance),
|
||||
&xscommon.StepAttachVdi{
|
||||
VdiUuidKey: "floppy_vdi_uuid",
|
||||
@ -153,20 +163,28 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
|
||||
Chan: httpReqChan,
|
||||
Timeout: 300 * time.Minute, /*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,
|
||||
Host: xscommon.InstanceSSHIP,
|
||||
SSHConfig: self.config.Comm.SSHConfigFunc(),
|
||||
SSHPort: xscommon.InstanceSSHPort,
|
||||
},
|
||||
new(commonsteps.StepProvision),
|
||||
new(xscommon.StepShutdown),
|
||||
&xscommon.StepDetachVdi{
|
||||
VdiUuidKey: "floppy_vdi_uuid",
|
||||
},
|
||||
new(xscommon.StepSetVmToTemplate),
|
||||
&xscommon.StepDetachVdi{
|
||||
VdiUuidKey: "tools_vdi_uuid",
|
||||
},
|
||||
&xscommon.StepDetachVdi{
|
||||
VdiUuidKey: "floppy_vdi_uuid",
|
||||
},
|
||||
new(xscommon.StepDestroyVIFs),
|
||||
new(xscommon.StepExport),
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
"github.com/hashicorp/packer-plugin-sdk/common"
|
||||
)
|
||||
|
||||
func testConfig() map[string]interface{} {
|
||||
@ -16,7 +17,7 @@ func testConfig() map[string]interface{} {
|
||||
"ssh_username": "foo",
|
||||
"source_path": ".",
|
||||
|
||||
packer.BuildNameConfigKey: "foo",
|
||||
common.BuildNameConfigKey: "foo",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@ package xva
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
@ -24,6 +25,11 @@ func (self *stepImportInstance) Run(ctx context.Context, state multistep.StateBa
|
||||
|
||||
ui.Say("Step: Import Instance")
|
||||
|
||||
if config.SourcePath == "" {
|
||||
log.Println("Skipping imporing instance - no `source_path` configured.")
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
// find the SR
|
||||
srs, err := c.GetClient().SR.GetAll(c.GetSessionRef())
|
||||
sr := srs[0]
|
||||
@ -80,6 +86,12 @@ func (self *stepImportInstance) Run(ctx context.Context, state multistep.StateBa
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
err = xscommon.AddVMTags(c, instance, config.VMTags)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Failed to add tags: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
ui.Say(fmt.Sprintf("Imported instance '%s'", instanceId))
|
||||
|
||||
return multistep.ActionContinue
|
||||
|
@ -29,21 +29,34 @@ each category, the available options are alphabetized and described.
|
||||
|
||||
* `iso_checksum` (string) - The checksum for the OS ISO file. Because ISO
|
||||
files are so large, this is required and Packer will verify it prior
|
||||
to booting a virtual machine with the ISO attached. The type of the
|
||||
checksum is specified with `iso_checksum_type`, documented below.
|
||||
to booting a virtual machine with the ISO attached. The type of
|
||||
the checksum is specified within the checksum field as a prefix, ex:
|
||||
"md5:{$checksum}". The type of the checksum can also be omitted and
|
||||
Packer will try to infer it based on string length. Valid values are
|
||||
"none", "{$checksum}", "md5:{$checksum}", "sha1:{$checksum}",
|
||||
"sha256:{$checksum}", "sha512:{$checksum}" or "file:{$path}". Here is a
|
||||
list of valid checksum values:
|
||||
* md5:090992ba9fd140077b0661cb75f7ce13
|
||||
* 090992ba9fd140077b0661cb75f7ce13
|
||||
* sha1:ebfb681885ddf1234c18094a45bbeafd91467911
|
||||
* ebfb681885ddf1234c18094a45bbeafd91467911
|
||||
* sha256:ed363350696a726b7932db864dda019bd2017365c9e299627830f06954643f93
|
||||
* ed363350696a726b7932db864dda019bd2017365c9e299627830f06954643f93
|
||||
* file:http://releases.ubuntu.com/20.04/SHA256SUMS
|
||||
* file:file://./local/path/file.sum
|
||||
* file:./local/path/file.sum
|
||||
* none
|
||||
Although the checksum will not be verified when it is set to "none",
|
||||
this is not recommended since these files can be very large and
|
||||
corruption does happen from time to time.
|
||||
|
||||
* `iso_checksum_type` (string) - The type of the checksum specified in
|
||||
`iso_checksum`. Valid values are "none", "md5", "sha1", "sha256", or
|
||||
"sha512" currently. While "none" will skip checksumming, this is not
|
||||
recommended since ISO files are generally large and corruption does happen
|
||||
from time to time.
|
||||
|
||||
* `iso_url` (string) - A URL to the ISO containing the installation image.
|
||||
This URL can be either an HTTP URL or a file URL (or path to a file).
|
||||
If this is an HTTP URL, Packer will download it and cache it between
|
||||
runs.
|
||||
|
||||
* `remote_host` (string) - The host of the Xenserver / XCP-ng pool primary. Typically these will be specified through environment variables as seen in the [examples](../../examples/centos8.json).
|
||||
* `remote_host` (string) - The host of the Xenserver / XCP-ng pool primary. Typically these will be specified through environment variables as seen in the [examples](../../../examples).
|
||||
|
||||
* `remote_username` (string) - The XenServer username used to access the remote machine.
|
||||
|
||||
@ -59,7 +72,7 @@ each category, the available options are alphabetized and described.
|
||||
be to type just enough to initialize the operating system installer. Special
|
||||
keys can be typed as well, and are covered in the section below on the boot
|
||||
command. If this is not specified, it is assumed the installer will start
|
||||
itself. See the [Ubuntu](../../examples/ubuntu-2004.json) and [centos](../../examples/centos8.json) examples to see how these are used to launch autoinstall and kickstart respectively.
|
||||
itself. See the [Ubuntu](../../../examples/ubuntu) and [centos](../../../examples/centos) examples to see how these are used to launch autoinstall and kickstart respectively.
|
||||
|
||||
* `boot_wait` (string) - The time to wait after booting the initial virtual
|
||||
machine before typing the `boot_command`. The value of this should be
|
||||
@ -198,6 +211,8 @@ each category, the available options are alphabetized and described.
|
||||
* `vm_memory` (integer) - The size, in megabytes, of the amount of memory to
|
||||
allocate for the VM. By default, this is 1024 (1 GB).
|
||||
|
||||
* `vm_tags` (array of strings) - A list of tags to add to the VM
|
||||
|
||||
## Differences with other Packer builders
|
||||
|
||||
Currently the XenServer builder has some quirks when compared with other Packer builders.
|
||||
@ -256,4 +271,4 @@ The available variables are:
|
||||
configuration parameter. If `http_directory` isn't specified, these will be
|
||||
blank!
|
||||
|
||||
See the [examples](../../examples/) for working boot commands.
|
||||
See the [examples](../../../examples) for working boot commands.
|
||||
|
@ -47,8 +47,7 @@ locals {
|
||||
}
|
||||
|
||||
source "xenserver-iso" "centos8-local" {
|
||||
iso_checksum = "aaf9d4b3071c16dbbda01dfe06085e5d0fdac76df323e3bbe87cce4318052247"
|
||||
iso_checksum_type = "sha1"
|
||||
iso_checksum = "sha1:aaf9d4b3071c16dbbda01dfe06085e5d0fdac76df323e3bbe87cce4318052247"
|
||||
iso_url = "http://mirrors.ocf.berkeley.edu/centos/8.3.2011/isos/x86_64/CentOS-8.3.2011-x86_64-dvd1.iso"
|
||||
|
||||
sr_iso_name = var.sr_iso_name
|
||||
|
@ -47,8 +47,7 @@ locals {
|
||||
}
|
||||
|
||||
source "xenserver-iso" "centos8-netinstall" {
|
||||
iso_checksum = "07a8e59c42cc086ec4c49bdce4fae5a17b077dea"
|
||||
iso_checksum_type = "sha1"
|
||||
iso_checksum = "sha1:07a8e59c42cc086ec4c49bdce4fae5a17b077dea"
|
||||
iso_url = "http://mirrors.ocf.berkeley.edu/centos/8.3.2011/isos/x86_64/CentOS-8.3.2011-x86_64-boot.iso"
|
||||
|
||||
sr_iso_name = var.sr_iso_name
|
||||
|
@ -1,12 +1,43 @@
|
||||
packer {
|
||||
required_plugins {
|
||||
xenserver= {
|
||||
version = ">= v0.3.2"
|
||||
version = ">= v0.5.2"
|
||||
source = "github.com/ddelnano/xenserver"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# The ubuntu_version value determines what Ubuntu iso URL and sha256 hash we lookup. Updating
|
||||
# this will allow a new version to be pulled in.
|
||||
data "null" "ubuntu_version" {
|
||||
input = "20.04"
|
||||
}
|
||||
|
||||
locals {
|
||||
timestamp = regex_replace(timestamp(), "[- TZ:]", "")
|
||||
ubuntu_version = data.null.ubuntu_version.output
|
||||
|
||||
# Update this map to support future releases. At this time, the Ubuntu
|
||||
# jammy template is not available yet.
|
||||
ubuntu_template_name = {
|
||||
20.04 = "Ubuntu Focal Fossa 20.04"
|
||||
}
|
||||
}
|
||||
|
||||
# TODO(ddelnano): Update this to use a local once https://github.com/hashicorp/packer/issues/11011
|
||||
# is fixed.
|
||||
data "http" "ubuntu_sha_and_release" {
|
||||
url = "https://releases.ubuntu.com/${data.null.ubuntu_version.output}/SHA256SUMS"
|
||||
}
|
||||
|
||||
local "ubuntu_sha256" {
|
||||
expression = regex("([A-Za-z0-9]+)[\\s\\*]+ubuntu-.*server", data.http.ubuntu_sha_and_release.body)
|
||||
}
|
||||
|
||||
local "ubuntu_url_path" {
|
||||
expression = regex("[A-Za-z0-9]+[\\s\\*]+ubuntu-${local.ubuntu_version}.(\\d+)-live-server-amd64.iso", data.http.ubuntu_sha_and_release.body)
|
||||
}
|
||||
|
||||
variable "remote_host" {
|
||||
type = string
|
||||
description = "The ip or fqdn of your XenServer. This will be pulled from the env var 'PKR_VAR_XAPI_HOST'"
|
||||
@ -42,15 +73,9 @@ variable "sr_name" {
|
||||
description = "The name of the SR to packer will use"
|
||||
}
|
||||
|
||||
locals {
|
||||
timestamp = regex_replace(timestamp(), "[- TZ:]", "")
|
||||
}
|
||||
|
||||
|
||||
source "xenserver-iso" "ubuntu-2004" {
|
||||
iso_checksum = "d1f2bf834bbe9bb43faf16f9be992a6f3935e65be0edece1dee2aa6eb1767423"
|
||||
iso_checksum_type = "sha256"
|
||||
iso_url = "http://releases.ubuntu.com/20.04/ubuntu-20.04.2-live-server-amd64.iso"
|
||||
iso_checksum = "sha256:${local.ubuntu_sha256.0}"
|
||||
iso_url = "https://releases.ubuntu.com/${local.ubuntu_version}/ubuntu-${local.ubuntu_version}.${local.ubuntu_url_path.0}-live-server-amd64.iso"
|
||||
|
||||
sr_iso_name = var.sr_iso_name
|
||||
sr_name = var.sr_name
|
||||
@ -60,10 +85,12 @@ source "xenserver-iso" "ubuntu-2004" {
|
||||
remote_password = var.remote_password
|
||||
remote_username = var.remote_username
|
||||
|
||||
vm_name = "packer-ubuntu-2004-${local.timestamp}"
|
||||
# Change this to match the ISO of ubuntu you are using in the iso_url variable
|
||||
clone_template = local.ubuntu_template_name[data.null.ubuntu_version.output]
|
||||
vm_name = "packer-ubuntu-${data.null.ubuntu_version.output}-${local.timestamp}"
|
||||
vm_description = "Build started: ${local.timestamp}"
|
||||
vm_memory = 4096
|
||||
disk_size = 20000
|
||||
disk_size = 30720
|
||||
|
||||
floppy_files = [
|
||||
"examples/http/ubuntu-2004/meta-data",
|
||||
|
Loading…
Reference in New Issue
Block a user