Compare commits
8 Commits
main
...
4censord-a
Author | SHA1 | Date | |
---|---|---|---|
|
23a046503d | ||
|
acf35e4901 | ||
|
266dd9869d | ||
|
8325249f0a | ||
|
8a700e8e42 | ||
|
207135c85e | ||
|
aa5a925245 | ||
|
1696c6e02e |
6
.github/dependabot.yml
vendored
6
.github/dependabot.yml
vendored
@ -1,6 +0,0 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "gomod" # See documentation for possible values
|
||||
directory: "/" # Location of package manifests
|
||||
schedule:
|
||||
interval: "daily"
|
14
.github/release.yml
vendored
14
.github/release.yml
vendored
@ -1,14 +0,0 @@
|
||||
changelog:
|
||||
categories:
|
||||
- title: Breaking Changes 🛠
|
||||
labels:
|
||||
- breaking-change
|
||||
- title: New Features 🎉
|
||||
labels:
|
||||
- enhancement
|
||||
- title: Bug fixes
|
||||
labels:
|
||||
- bug
|
||||
- title: Other Changes
|
||||
labels:
|
||||
- "*"
|
24
.github/workflows/go-test.yml
vendored
24
.github/workflows/go-test.yml
vendored
@ -1,24 +0,0 @@
|
||||
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.20"
|
||||
- name: Run go tests
|
||||
run: go test -race -count 1 ./... -timeout=3m
|
20
.github/workflows/release.yml
vendored
20
.github/workflows/release.yml
vendored
@ -1,12 +1,12 @@
|
||||
# This GitHub action can publish assets for release when a tag is created.
|
||||
# Currently its setup to run on any tag that matches the pattern "v*" (ie. v0.1.0).
|
||||
#
|
||||
# This uses an action (hashicorp/ghaction-import-gpg) that assumes you set your
|
||||
# private key in the `GPG_PRIVATE_KEY` secret and passphrase in the `GPG_PASSPHRASE`
|
||||
# This uses an action (paultyng/ghaction-import-gpg) that assumes you set your
|
||||
# private key in the `GPG_PRIVATE_KEY` secret and passphrase in the `PASSPHRASE`
|
||||
# secret. If you would rather own your own GPG handling, please fork this action
|
||||
# or use an alternative one for key handling.
|
||||
#
|
||||
# You will need to pass the `--batch` flag to `gpg` in your signing step
|
||||
# You will need to pass the `--batch` flag to `gpg` in your signing step
|
||||
# in `goreleaser` to indicate this is being used in a non-interactive mode.
|
||||
#
|
||||
name: release
|
||||
@ -25,21 +25,21 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: "1.20"
|
||||
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: crazy-max/ghaction-import-gpg@v5.0.0
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
passphrase: ${{ secrets.GPG_PASSPHRASE }}
|
||||
uses: paultyng/ghaction-import-gpg@v2.1.0
|
||||
env:
|
||||
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
PASSPHRASE: ${{ secrets.PASSPHRASE }}
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@f82d6c1c344bcacabba2c841718984797f664a6b # v4.2.0
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
with:
|
||||
version: latest
|
||||
args: release --clean
|
||||
args: release --rm-dist
|
||||
env:
|
||||
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
@ -1 +0,0 @@
|
||||
1.20.11
|
@ -1,36 +1,41 @@
|
||||
version: 2
|
||||
|
||||
# This is an example goreleaser.yaml file with some sane defaults.
|
||||
# Make sure to check the documentation at http://goreleaser.com
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
before:
|
||||
hooks:
|
||||
- go test ./...
|
||||
# As part of the release doc files are included as a separate deliverable for
|
||||
# consumption by Packer.io. To include a separate docs.zip uncomment the following command.
|
||||
#- make ci-release-docs
|
||||
# Check plugin compatibility with required version of the Packer SDK
|
||||
- make plugin-check
|
||||
# We strongly recommend running tests to catch any regression before release.
|
||||
# Even though, this an optional step.
|
||||
# - go test ./...
|
||||
|
||||
builds:
|
||||
# A separated build to run the packer-plugins-check only once for a linux_amd64 binary
|
||||
-
|
||||
id: plugin-check
|
||||
mod_timestamp: '{{ .CommitTimestamp }}'
|
||||
hooks:
|
||||
post:
|
||||
# This will check plugin compatibility against latest version of Packer
|
||||
- cmd: |
|
||||
go install github.com/hashicorp/packer/cmd/packer-plugins-check@latest &&
|
||||
packer-plugins-check -load={{ .Name }}
|
||||
dir: "{{ dir .Path}}"
|
||||
flags:
|
||||
- -trimpath #removes all file system paths from the compiled executable
|
||||
ldflags:
|
||||
- '-s -w -X {{ .ModulePath }}/version.Version={{.Version}} -X {{ .ModulePath }}/version.VersionPrerelease= '
|
||||
- '-s -w -X main.Version={{.Version}} -X main.VersionPrerelease= '
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- amd64
|
||||
binary: '{{ .ProjectName }}_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}'
|
||||
-
|
||||
-
|
||||
mod_timestamp: '{{ .CommitTimestamp }}'
|
||||
flags:
|
||||
- -trimpath #removes all file system paths from the compiled executable
|
||||
ldflags:
|
||||
- '-s -w -X {{ .ModulePath }}/version.Version={{.Version}} -X {{ .ModulePath }}/version.VersionPrerelease= '
|
||||
- '-s -w -X main.version={{.Version}} -X main.VersionPrerelease= '
|
||||
goos:
|
||||
- freebsd
|
||||
- windows
|
||||
@ -46,11 +51,10 @@ builds:
|
||||
goarch: '386'
|
||||
- goos: linux
|
||||
goarch: amd64
|
||||
|
||||
binary: '{{ .ProjectName }}_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}'
|
||||
archives:
|
||||
- format: zip
|
||||
files:
|
||||
- none*
|
||||
name_template: '{{ .ProjectName }}_v{{ .Version }}_{{ .Env.API_VERSION }}_{{ .Os }}_{{ .Arch }}'
|
||||
checksum:
|
||||
name_template: '{{ .ProjectName }}_v{{ .Version }}_SHA256SUMS'
|
||||
@ -58,7 +62,7 @@ checksum:
|
||||
signs:
|
||||
- artifacts: checksum
|
||||
args:
|
||||
# if you are using this is in a GitHub action or some other automated pipeline, you
|
||||
# if you are using this is in a GitHub action or some other automated pipeline, you
|
||||
# need to pass the batch flag to indicate its not interactive.
|
||||
- "--batch"
|
||||
- "--local-user"
|
||||
@ -68,7 +72,7 @@ signs:
|
||||
- "--detach-sign"
|
||||
- "${artifact}"
|
||||
release:
|
||||
draft: false
|
||||
|
||||
# If you want to manually examine the release before its live, uncomment this line:
|
||||
draft: true
|
||||
changelog:
|
||||
disable: true
|
||||
skip: true
|
||||
|
7
.travis.yml
Normal file
7
.travis.yml
Normal file
@ -0,0 +1,7 @@
|
||||
language: go
|
||||
go:
|
||||
# Test with the first and the latest go release - to ensure compatibility
|
||||
- 1.6
|
||||
- tip
|
||||
script:
|
||||
- gofmtresult=$(gofmt -s -l .); if [[ -n $gofmtresult ]]; then echo -e "Please run \"gofmt -s -w .\" before committing for the below:\n$gofmtresult"; false; fi
|
34
GNUmakefile
34
GNUmakefile
@ -1,34 +0,0 @@
|
||||
NAME=xenserver
|
||||
BINARY=packer-plugin-${NAME}
|
||||
|
||||
COUNT?=1
|
||||
TEST?=$(shell go list ./...)
|
||||
HASHICORP_PACKER_PLUGIN_SDK_VERSION?=$(shell go list -m github.com/hashicorp/packer-plugin-sdk | cut -d " " -f2)
|
||||
|
||||
.PHONY: dev
|
||||
|
||||
build:
|
||||
@go build -o ${BINARY}
|
||||
|
||||
dev: build
|
||||
@mkdir -p ~/.packer.d/plugins/
|
||||
@mv ${BINARY} ~/.packer.d/plugins/${BINARY}
|
||||
|
||||
test:
|
||||
@go test -race -count $(COUNT) $(TEST) -timeout=3m
|
||||
|
||||
install-packer-sdc: ## Install packer sofware development command
|
||||
@go install github.com/hashicorp/packer-plugin-sdk/cmd/packer-sdc@${HASHICORP_PACKER_PLUGIN_SDK_VERSION}
|
||||
|
||||
ci-release-docs: install-packer-sdc
|
||||
@packer-sdc renderdocs -src docs -partials docs-partials/ -dst docs/
|
||||
@/bin/sh -c "[ -d docs ] && zip -r docs.zip docs/"
|
||||
|
||||
plugin-check: install-packer-sdc build
|
||||
@packer-sdc plugin-check ${BINARY}
|
||||
|
||||
testacc: dev
|
||||
@PACKER_ACC=1 go test -count $(COUNT) -v $(TEST) -timeout=120m
|
||||
|
||||
generate: install-packer-sdc
|
||||
@go generate ./...
|
55
README.md
55
README.md
@ -2,7 +2,7 @@
|
||||
|
||||
This builder plugin extends packer.io to support building images for XenServer.
|
||||
|
||||
This is a fork of the original builder since the original project was abandoned and no longer compiled with recent versions of Go or worked with Xenserver 7.6 and later.
|
||||
This is a fork of the original builder since the original project was abandoned and no longer compilied with recent versions of Go or worked with Xenserver 7.6 and later.
|
||||
|
||||
It improves the original project in the following ways:
|
||||
1. Developed alongside the [Xenorchestra terraform provider](https://github.com/ddelnano/terraform-provider-xenorchestra) to ensure the hashicorp ecosystem is interoperable.
|
||||
@ -13,75 +13,40 @@ It improves the original project in the following ways:
|
||||
At the time of this writing the packer builder has been verified to work with Xenserver 7.6 and can launch VMs with the packer output through the xenorchestra terraform provider.
|
||||
|
||||
The following list contains things that are incomplete but will be worked on soon:
|
||||
|
||||
- The documentation is still in an inconsistent state with upstream
|
||||
- Examples that are easier for new users to get up and running quickly
|
||||
- XVA builder is untested
|
||||
- Lots of dead code to remove from upstream
|
||||
|
||||
## Using the builder
|
||||
|
||||
The packer builder can be installed via `packer init` as long as the packer template includes the following in it's `pkr.hcl` file
|
||||
```
|
||||
packer {
|
||||
required_plugins {
|
||||
xenserver= {
|
||||
version = ">= v0.6.0"
|
||||
source = "github.com/ddelnano/xenserver"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The following command will install the packer plugin using the Ubuntu example provided in this repository.
|
||||
|
||||
```
|
||||
packer init examples/ubuntu/ubuntu-2004.pkr.hcl
|
||||
```
|
||||
|
||||
If you are using an older version of packer or are still using json templates you will need to download the relevant release from the project's [releases page](https://github.com/ddelnano/packer-builder-xenserver/releases) and copy the binary to `~/.packer.d/plugins/packer-builder-xenserver-iso`.
|
||||
Download the relevant release from the project's [releases page](https://github.com/ddelnano/packer-builder-xenserver/releases) and copy the binary to `~/.packer.d/plugins/packer-builder-xenserver-iso`.
|
||||
|
||||
## Developing the builder
|
||||
|
||||
### Dependencies
|
||||
* Packer >= v1.7.1 (https://packer.io)
|
||||
* Packer >= v1.7.0 (https://packer.io)
|
||||
* XenServer / Citrix Hypervisor > 7.6
|
||||
* Golang 1.20
|
||||
* Golang 1.16
|
||||
|
||||
## Compile the plugin
|
||||
|
||||
Once you have installed Packer, you must compile this plugin and install the
|
||||
resulting binary.
|
||||
|
||||
Documentation for Plugins directory: [Official Docs](https://developer.hashicorp.com/packer/docs/configure#packer-s-plugin-directory)
|
||||
|
||||
### Linux/MacOS
|
||||
|
||||
```shell
|
||||
go build -o packer-plugin-xenserver
|
||||
$ go build -o packer-plugin-xenserver
|
||||
|
||||
# Add the plugin to the location packer expects it to be installed in
|
||||
mkdir -p ~/.packer.d/plugins/
|
||||
cp packer-plugin-xenserver ~/.packer.d/plugins
|
||||
```
|
||||
|
||||
### Windows (Powershell)
|
||||
|
||||
```powershell
|
||||
go build -o packer-plugin-xenserver
|
||||
|
||||
mkdir "%APPDATA%\packer.d\plugins"
|
||||
cp packer-plugin-xenserver "%APPDATA%\packer.d\plugins"
|
||||
# Add the builder to the location packer expects it to be installed in
|
||||
$ mkdir -p ~/.packer.d/plugins/
|
||||
$ 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/iso/xenserver-iso.html.markdown)
|
||||
xenserver-iso docs](docs/builders/xenserver-iso.html.markdown)
|
||||
|
||||
## Support
|
||||
|
||||
You can discuss any issues you have or feature requests in [Discord](https://discord.gg/ZpNq8ez).
|
||||
|
||||
If you'd like to support my effort on the project, please consider buying me a coffee
|
||||
|
||||
[!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/ddelnano)
|
||||
|
@ -624,17 +624,6 @@ 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) {
|
||||
|
@ -13,19 +13,17 @@ import (
|
||||
)
|
||||
|
||||
type CommonConfig struct {
|
||||
Username string `mapstructure:"remote_username"`
|
||||
Password string `mapstructure:"remote_password"`
|
||||
HostIp string `mapstructure:"remote_host"`
|
||||
HostSshPort uint `mapstructure:"remote_ssh_port"`
|
||||
Username string `mapstructure:"remote_username"`
|
||||
Password string `mapstructure:"remote_password"`
|
||||
HostIp string `mapstructure:"remote_host"`
|
||||
|
||||
VMName string `mapstructure:"vm_name"`
|
||||
VMDescription string `mapstructure:"vm_description"`
|
||||
SrName string `mapstructure:"sr_name"`
|
||||
SrISOName string `mapstructure:"sr_iso_name" required:"false"`
|
||||
SrISOName string `mapstructure:"sr_iso_name"`
|
||||
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"`
|
||||
@ -65,10 +63,6 @@ func (c *CommonConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig
|
||||
|
||||
// Set default values
|
||||
|
||||
if c.HostSshPort == 0 {
|
||||
c.HostSshPort = 22
|
||||
}
|
||||
|
||||
if c.HostPortMin == 0 {
|
||||
c.HostPortMin = 5900
|
||||
}
|
||||
@ -81,6 +75,10 @@ func (c *CommonConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig
|
||||
c.RawBootWait = "5s"
|
||||
}
|
||||
|
||||
if c.ToolsIsoName == "" {
|
||||
c.ToolsIsoName = "xs-tools.iso"
|
||||
}
|
||||
|
||||
if c.HTTPPortMin == 0 {
|
||||
c.HTTPPortMin = 8000
|
||||
}
|
||||
@ -225,11 +223,29 @@ func (c CommonConfig) ShouldKeepVM(state multistep.StateBag) bool {
|
||||
}
|
||||
|
||||
func (config CommonConfig) GetSR(c *Connection) (xenapi.SRRef, error) {
|
||||
var srRef xenapi.SRRef
|
||||
if config.SrName == "" {
|
||||
return getDefaultSR(c)
|
||||
} else {
|
||||
var srRef xenapi.SRRef
|
||||
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))
|
||||
|
||||
} else {
|
||||
// Use the provided name label to find the SR to use
|
||||
srs, err := c.GetClient().SR.GetByNameLabel(c.session, config.SrName)
|
||||
|
||||
@ -251,11 +267,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 getDefaultSR(c)
|
||||
return srRef, errors.New("sr_iso_name must be specified in the packer configuration")
|
||||
|
||||
} else {
|
||||
// Use the provided name label to find the SR to use
|
||||
srs, err := c.GetClient().SR.GetByNameLabel(c.session, config.SrISOName)
|
||||
srs, err := c.GetClient().SR.GetByNameLabel(c.session, config.SrName)
|
||||
|
||||
if err != nil {
|
||||
return srRef, err
|
||||
@ -263,42 +279,11 @@ 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.SrISOName)
|
||||
return srRef, fmt.Errorf("Couldn't find a SR with the specified name-label '%s'", config.SrName)
|
||||
case len(srs) > 1:
|
||||
return srRef, fmt.Errorf("Found more than one SR with the name '%s'. The name must be unique", config.SrISOName)
|
||||
return srRef, fmt.Errorf("Found more than one SR with the name '%s'. The name must be unique", config.SrName)
|
||||
}
|
||||
|
||||
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 packer-sdc mapstructure-to-hcl2 -type Config
|
||||
//go:generate mapstructure-to-hcl2 -type Config
|
||||
package common
|
||||
|
||||
import (
|
||||
@ -17,16 +17,15 @@ type Config struct {
|
||||
VCPUsMax uint `mapstructure:"vcpus_max"`
|
||||
VCPUsAtStartup uint `mapstructure:"vcpus_atstartup"`
|
||||
VMMemory uint `mapstructure:"vm_memory"`
|
||||
DiskName string `mapstructure:"disk_name"`
|
||||
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"`
|
||||
ISOUrls []string `mapstructure:"iso_urls"`
|
||||
ISOUrl string `mapstructure:"iso_url"`
|
||||
ISOName string `mapstructure:"iso_name"`
|
||||
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"`
|
||||
|
||||
PlatformArgs map[string]string `mapstructure:"platform_args"`
|
||||
|
||||
@ -34,9 +33,6 @@ type Config struct {
|
||||
InstallTimeout time.Duration ``
|
||||
SourcePath string `mapstructure:"source_path"`
|
||||
|
||||
Firmware string `mapstructure:"firmware"`
|
||||
SkipSetTemplate bool `mapstructure:"skip_set_template"`
|
||||
|
||||
ctx interpolate.Context
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT.
|
||||
// Code generated by "mapstructure-to-hcl2 -type Config"; DO NOT EDIT.
|
||||
|
||||
package common
|
||||
|
||||
@ -12,7 +12,6 @@ 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"`
|
||||
@ -21,15 +20,13 @@ type FlatConfig struct {
|
||||
Username *string `mapstructure:"remote_username" cty:"remote_username" hcl:"remote_username"`
|
||||
Password *string `mapstructure:"remote_password" cty:"remote_password" hcl:"remote_password"`
|
||||
HostIp *string `mapstructure:"remote_host" cty:"remote_host" hcl:"remote_host"`
|
||||
HostSshPort *uint `mapstructure:"remote_ssh_port" cty:"remote_ssh_port" hcl:"remote_ssh_port"`
|
||||
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" required:"false" cty:"sr_iso_name" hcl:"sr_iso_name"`
|
||||
SrISOName *string `mapstructure:"sr_iso_name" 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"`
|
||||
@ -99,19 +96,17 @@ type FlatConfig struct {
|
||||
VCPUsMax *uint `mapstructure:"vcpus_max" cty:"vcpus_max" hcl:"vcpus_max"`
|
||||
VCPUsAtStartup *uint `mapstructure:"vcpus_atstartup" cty:"vcpus_atstartup" hcl:"vcpus_atstartup"`
|
||||
VMMemory *uint `mapstructure:"vm_memory" cty:"vm_memory" hcl:"vm_memory"`
|
||||
DiskName *string `mapstructure:"disk_name" cty:"disk_name" hcl:"disk_name"`
|
||||
DiskSize *uint `mapstructure:"disk_size" cty:"disk_size" hcl:"disk_size"`
|
||||
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"`
|
||||
PlatformArgs map[string]string `mapstructure:"platform_args" cty:"platform_args" hcl:"platform_args"`
|
||||
RawInstallTimeout *string `mapstructure:"install_timeout" cty:"install_timeout" hcl:"install_timeout"`
|
||||
SourcePath *string `mapstructure:"source_path" cty:"source_path" hcl:"source_path"`
|
||||
Firmware *string `mapstructure:"firmware" cty:"firmware" hcl:"firmware"`
|
||||
SkipSetTemplate *bool `mapstructure:"skip_set_template" cty:"skip_set_template" hcl:"skip_set_template"`
|
||||
}
|
||||
|
||||
// FlatMapstructure returns a new FlatConfig.
|
||||
@ -128,7 +123,6 @@ 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},
|
||||
@ -137,7 +131,6 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
"remote_username": &hcldec.AttrSpec{Name: "remote_username", Type: cty.String, Required: false},
|
||||
"remote_password": &hcldec.AttrSpec{Name: "remote_password", Type: cty.String, Required: false},
|
||||
"remote_host": &hcldec.AttrSpec{Name: "remote_host", Type: cty.String, Required: false},
|
||||
"remote_ssh_port": &hcldec.AttrSpec{Name: "remote_ssh_port", Type: cty.Number, Required: false},
|
||||
"vm_name": &hcldec.AttrSpec{Name: "vm_name", Type: cty.String, Required: false},
|
||||
"vm_description": &hcldec.AttrSpec{Name: "vm_description", Type: cty.String, Required: false},
|
||||
"sr_name": &hcldec.AttrSpec{Name: "sr_name", Type: cty.String, Required: false},
|
||||
@ -145,7 +138,6 @@ 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},
|
||||
@ -215,19 +207,17 @@ func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec {
|
||||
"vcpus_max": &hcldec.AttrSpec{Name: "vcpus_max", Type: cty.Number, Required: false},
|
||||
"vcpus_atstartup": &hcldec.AttrSpec{Name: "vcpus_atstartup", Type: cty.Number, Required: false},
|
||||
"vm_memory": &hcldec.AttrSpec{Name: "vm_memory", Type: cty.Number, Required: false},
|
||||
"disk_name": &hcldec.AttrSpec{Name: "disk_name", Type: cty.String, Required: false},
|
||||
"disk_size": &hcldec.AttrSpec{Name: "disk_size", Type: cty.Number, Required: false},
|
||||
"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},
|
||||
"platform_args": &hcldec.AttrSpec{Name: "platform_args", Type: cty.Map(cty.String), Required: false},
|
||||
"install_timeout": &hcldec.AttrSpec{Name: "install_timeout", Type: cty.String, Required: false},
|
||||
"source_path": &hcldec.AttrSpec{Name: "source_path", Type: cty.String, Required: false},
|
||||
"firmware": &hcldec.AttrSpec{Name: "firmware", Type: cty.String, Required: false},
|
||||
"skip_set_template": &hcldec.AttrSpec{Name: "skip_set_template", Type: cty.Bool, Required: false},
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
@ -17,7 +17,7 @@ import (
|
||||
|
||||
func SSHAddress(state multistep.StateBag) (string, error) {
|
||||
sshIP := state.Get("ssh_address").(string)
|
||||
sshHostPort := state.Get("ssh_port").(uint)
|
||||
sshHostPort := 22
|
||||
return fmt.Sprintf("%s:%d", sshIP, sshHostPort), nil
|
||||
}
|
||||
|
||||
@ -114,10 +114,10 @@ func ExecuteGuestSSHCmd(state multistep.StateBag, cmd string) (stdout string, er
|
||||
return doExecuteSSHCmd(cmd, localAddress, sshConfig)
|
||||
}
|
||||
|
||||
func forward(local_conn net.Conn, config *gossh.ClientConfig, server string, server_ssh_port int, remote_dest string, remote_port uint) error {
|
||||
func forward(local_conn net.Conn, config *gossh.ClientConfig, server, remote_dest string, remote_port uint) error {
|
||||
defer local_conn.Close()
|
||||
|
||||
ssh_client_conn, err := gossh.Dial("tcp", fmt.Sprintf("%s:%d", server, server_ssh_port), config)
|
||||
ssh_client_conn, err := gossh.Dial("tcp", server+":22", config)
|
||||
if err != nil {
|
||||
log.Printf("local ssh.Dial error: %s", err)
|
||||
return err
|
||||
@ -157,7 +157,7 @@ func forward(local_conn net.Conn, config *gossh.ClientConfig, server string, ser
|
||||
return nil
|
||||
}
|
||||
|
||||
func ssh_port_forward(local_listener net.Listener, remote_port int, remote_dest, host string, host_ssh_port int, username, password string) error {
|
||||
func ssh_port_forward(local_listener net.Listener, remote_port int, remote_dest, host, username, password string) error {
|
||||
|
||||
config := &gossh.ClientConfig{
|
||||
User: username,
|
||||
@ -176,7 +176,7 @@ func ssh_port_forward(local_listener net.Listener, remote_port int, remote_dest,
|
||||
}
|
||||
|
||||
// Forward to a remote port
|
||||
go forward(local_connection, config, host, host_ssh_port, remote_dest, uint(remote_port))
|
||||
go forward(local_connection, config, host, remote_dest, uint(remote_port))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -1,44 +0,0 @@
|
||||
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)
|
||||
}
|
@ -35,11 +35,10 @@ func (self *StepForwardPortOverSSH) Run(ctx context.Context, state multistep.Sta
|
||||
ui.Say(fmt.Sprintf("Creating a local port forward over SSH on local port %d", sshHostPort))
|
||||
|
||||
hostAddress, _ := state.Get("ssh_address").(string)
|
||||
hostSshPort, _ := state.Get("ssh_port").(int)
|
||||
remotePort, _ := self.RemotePort(state)
|
||||
remoteDest, _ := self.RemoteDest(state)
|
||||
|
||||
go ssh_port_forward(l, remotePort, remoteDest, hostAddress, hostSshPort, config.Username, config.Password)
|
||||
go ssh_port_forward(l, remotePort, remoteDest, hostAddress, config.Username, config.Password)
|
||||
ui.Say(fmt.Sprintf("Port forward setup. %d ---> %s:%d on %s", sshHostPort, remoteDest, remotePort, hostAddress))
|
||||
|
||||
// Provide the local port to future steps.
|
||||
|
@ -13,7 +13,6 @@ type StepSetVmHostSshAddress struct{}
|
||||
func (self *StepSetVmHostSshAddress) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
|
||||
c := state.Get("client").(*Connection)
|
||||
config := state.Get("config").(Config)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
ui.Say("Step: Set SSH address to VM host IP")
|
||||
@ -38,9 +37,6 @@ func (self *StepSetVmHostSshAddress) Run(ctx context.Context, state multistep.St
|
||||
state.Put("ssh_address", address)
|
||||
ui.Say(fmt.Sprintf("Set host SSH address to '%s'.", address))
|
||||
|
||||
state.Put("ssh_port", config.HostSshPort)
|
||||
ui.Say(fmt.Sprintf("Set host SSH port to %d.", config.HostSshPort))
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
|
@ -16,7 +16,6 @@ func (self *StepStartVmPaused) Run(ctx context.Context, state multistep.StateBag
|
||||
|
||||
c := state.Get("client").(*Connection)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
config := state.Get("config").(Config)
|
||||
|
||||
ui.Say("Step: Start VM Paused")
|
||||
|
||||
@ -35,7 +34,7 @@ func (self *StepStartVmPaused) Run(ctx context.Context, state multistep.StateBag
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
err = c.client.VM.SetHVMBootParams(c.session, instance, map[string]string{"order": "cd", "firmware": config.Firmware})
|
||||
err = c.client.VM.SetHVMBootParams(c.session, instance, map[string]string{"order": "cd"})
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Unable to set HVM boot params: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
|
@ -32,8 +32,8 @@ type StepTypeBootCommand struct {
|
||||
Ctx interpolate.Context
|
||||
}
|
||||
|
||||
func (step *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
config := state.Get("config").(Config)
|
||||
func (self *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
config := state.Get("commonconfig").(CommonConfig)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
c := state.Get("client").(*Connection)
|
||||
httpPort := state.Get("http_port").(int)
|
||||
@ -74,8 +74,7 @@ func (step *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateB
|
||||
}
|
||||
locationPieces := strings.SplitAfter(location, "/")
|
||||
consoleHost := strings.TrimSuffix(locationPieces[2], "/")
|
||||
ui.Say("Connecting to VNC over XAPI...")
|
||||
log.Printf("Connecting to host: %s", consoleHost)
|
||||
ui.Say(fmt.Sprintf("Connecting to the VM console VNC over xapi via %s", consoleHost))
|
||||
conn, err := net.Dial("tcp", fmt.Sprintf("%s:443", consoleHost))
|
||||
|
||||
if err != nil {
|
||||
@ -96,7 +95,7 @@ func (step *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateB
|
||||
httpReq := fmt.Sprintf("CONNECT %s HTTP/1.0\r\nHost: %s\r\nCookie: session_id=%s\r\n\r\n", consoleLocation, consoleHost, c.session)
|
||||
fmt.Printf("Sending the follow http req: %v", httpReq)
|
||||
|
||||
ui.Message(fmt.Sprintf("Making HTTP request to initiate VNC connection: %s", httpReq))
|
||||
ui.Say(fmt.Sprintf("Making HTTP request to initiate VNC connection: %s", httpReq))
|
||||
_, err = io.WriteString(tlsConn, httpReq)
|
||||
|
||||
if err != nil {
|
||||
@ -115,9 +114,9 @@ func (step *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateB
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
ui.Message(fmt.Sprintf("Received response: %s", string(buffer)))
|
||||
ui.Say(fmt.Sprintf("Received response: %s", string(buffer)))
|
||||
|
||||
vncClient, err := vnc.Client(tlsConn, &vnc.ClientConfig{Exclusive: !config.PackerDebug})
|
||||
vncClient, err := vnc.Client(tlsConn, &vnc.ClientConfig{Exclusive: true})
|
||||
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error establishing VNC session: %s", err)
|
||||
@ -143,7 +142,7 @@ func (step *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateB
|
||||
localIp := strings.Split(envVar, " ")[0]
|
||||
ui.Message(fmt.Sprintf("Found local IP: %s", localIp))
|
||||
|
||||
step.Ctx.Data = &bootCommandTemplateData{
|
||||
self.Ctx.Data = &bootCommandTemplateData{
|
||||
config.VMName,
|
||||
localIp,
|
||||
uint(httpPort),
|
||||
@ -152,7 +151,7 @@ func (step *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateB
|
||||
ui.Say("Typing boot commands over VNC...")
|
||||
for _, command := range config.BootCommand {
|
||||
|
||||
command, err := interpolate.Render(command, &step.Ctx)
|
||||
command, err := interpolate.Render(command, &self.Ctx)
|
||||
if err != nil {
|
||||
err := fmt.Errorf("Error preparing boot command: %s", err)
|
||||
state.Put("error", err)
|
||||
@ -168,10 +167,12 @@ func (step *StepTypeBootCommand) Run(ctx context.Context, state multistep.StateB
|
||||
vncSendString(vncClient, command)
|
||||
}
|
||||
|
||||
ui.Say("Finished typing.")
|
||||
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
func (step *StepTypeBootCommand) Cleanup(multistep.StateBag) {}
|
||||
func (self *StepTypeBootCommand) Cleanup(multistep.StateBag) {}
|
||||
|
||||
// Taken from qemu's builder plugin - not an exported function.
|
||||
func vncSendString(c *vnc.ClientConn, original string) {
|
||||
|
@ -18,7 +18,7 @@ type StepUploadVdi struct {
|
||||
VdiUuidKey string
|
||||
}
|
||||
|
||||
func (self *StepUploadVdi) uploadVdi(ctx context.Context, state multistep.StateBag) multistep.StepAction {
|
||||
func (self *StepUploadVdi) Run(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,8 +33,10 @@ func (self *StepUploadVdi) uploadVdi(ctx context.Context, state multistep.StateB
|
||||
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))
|
||||
@ -94,10 +96,6 @@ func (self *StepUploadVdi) uploadVdi(ctx context.Context, state multistep.StateB
|
||||
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)
|
||||
|
@ -60,8 +60,7 @@ func (self *StepWaitForIP) Run(ctx context.Context, state multistep.StateBag) mu
|
||||
return false, err
|
||||
}
|
||||
networks := metrics.Networks
|
||||
var ok bool
|
||||
if ip, ok = networks["0/ip"]; ok {
|
||||
if ip, ok := networks["0/ip"]; ok {
|
||||
if ip != "" {
|
||||
ui.Message(fmt.Sprintf("Got IP '%s' from XenServer tools", ip))
|
||||
return true, nil
|
||||
|
@ -40,7 +40,7 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
|
||||
}, raws...)
|
||||
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(errs, err)
|
||||
packer.MultiErrorAppend(errs, err)
|
||||
}
|
||||
|
||||
errs = packer.MultiErrorAppend(
|
||||
@ -53,10 +53,6 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
|
||||
self.config.RawInstallTimeout = "200m"
|
||||
}
|
||||
|
||||
if self.config.DiskName == "" {
|
||||
self.config.DiskName = "Packer-disk"
|
||||
}
|
||||
|
||||
if self.config.DiskSize == 0 {
|
||||
self.config.DiskSize = 40000
|
||||
}
|
||||
@ -81,10 +77,6 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
|
||||
self.config.CloneTemplate = "Other install media"
|
||||
}
|
||||
|
||||
if self.config.Firmware == "" {
|
||||
self.config.Firmware = "bios"
|
||||
}
|
||||
|
||||
if len(self.config.PlatformArgs) == 0 {
|
||||
pargs := make(map[string]string)
|
||||
pargs["viridian"] = "false"
|
||||
@ -99,11 +91,12 @@ 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_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_checksum_type": &self.config.ISOChecksumType,
|
||||
"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]
|
||||
@ -118,8 +111,23 @@ 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.
|
||||
self.config.ISOChecksum = strings.ToLower(self.config.ISOChecksum)
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if len(self.config.ISOUrls) == 0 {
|
||||
if self.config.ISOUrl == "" {
|
||||
@ -128,25 +136,10 @@ 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.
|
||||
@ -190,6 +183,7 @@ 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,
|
||||
@ -197,7 +191,6 @@ 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,
|
||||
@ -214,22 +207,20 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
|
||||
},
|
||||
VdiUuidKey: "floppy_vdi_uuid",
|
||||
},
|
||||
&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",
|
||||
&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",
|
||||
},
|
||||
&xscommon.StepFindVdi{
|
||||
VdiName: self.config.ToolsIsoName,
|
||||
@ -239,9 +230,7 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
|
||||
VdiName: self.config.ISOName,
|
||||
VdiUuidKey: "isoname_vdi_uuid",
|
||||
},
|
||||
&xscommon.StepCreateInstance{
|
||||
AssumePreInstalledOS: false,
|
||||
},
|
||||
new(stepCreateInstance),
|
||||
&xscommon.StepAttachVdi{
|
||||
VdiUuidKey: "floppy_vdi_uuid",
|
||||
VdiType: xsclient.VbdTypeFloppy,
|
||||
@ -290,14 +279,7 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
|
||||
},
|
||||
new(commonsteps.StepProvision),
|
||||
new(xscommon.StepShutdown),
|
||||
}
|
||||
|
||||
if !self.config.SkipSetTemplate {
|
||||
steps = append(steps,
|
||||
new(xscommon.StepSetVmToTemplate))
|
||||
}
|
||||
|
||||
steps = append(steps,
|
||||
new(xscommon.StepSetVmToTemplate),
|
||||
&xscommon.StepDetachVdi{
|
||||
VdiUuidKey: "iso_vdi_uuid",
|
||||
},
|
||||
@ -310,7 +292,8 @@ func (self *Builder) Run(ctx context.Context, ui packer.Ui, hook packer.Hook) (p
|
||||
&xscommon.StepDetachVdi{
|
||||
VdiUuidKey: "floppy_vdi_uuid",
|
||||
},
|
||||
new(xscommon.StepExport))
|
||||
new(xscommon.StepExport),
|
||||
}
|
||||
|
||||
if self.config.ISOName == "" {
|
||||
steps = append(download_steps, steps...)
|
||||
|
@ -4,22 +4,22 @@ import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/common"
|
||||
"github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
)
|
||||
|
||||
func testConfig() map[string]interface{} {
|
||||
return map[string]interface{}{
|
||||
"remote_host": "localhost",
|
||||
"remote_username": "admin",
|
||||
"remote_password": "admin",
|
||||
"vm_name": "foo",
|
||||
"iso_checksum": "md5:A221725EE181A44C67E25BD6A2516742",
|
||||
"iso_url": "http://www.google.com/",
|
||||
"shutdown_command": "yes",
|
||||
"ssh_username": "foo",
|
||||
"remote_host": "localhost",
|
||||
"remote_username": "admin",
|
||||
"remote_password": "admin",
|
||||
"vm_name": "foo",
|
||||
"iso_checksum": "foo",
|
||||
"iso_checksum_type": "md5",
|
||||
"iso_url": "http://www.google.com/",
|
||||
"shutdown_command": "yes",
|
||||
"ssh_username": "foo",
|
||||
|
||||
common.BuildNameConfigKey: "foo",
|
||||
packer.BuildNameConfigKey: "foo",
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,7 +42,7 @@ func TestBuilderPrepare_Defaults(t *testing.T) {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
if b.config.ToolsIsoName != "" {
|
||||
if b.config.ToolsIsoName != "xs-tools.iso" {
|
||||
t.Errorf("bad tools ISO name: %s", b.config.ToolsIsoName)
|
||||
}
|
||||
|
||||
@ -61,10 +61,6 @@ func TestBuilderPrepare_Defaults(t *testing.T) {
|
||||
if b.config.KeepVM != "never" {
|
||||
t.Errorf("bad keep instance: %s", b.config.KeepVM)
|
||||
}
|
||||
|
||||
if b.config.HostSshPort != 22 {
|
||||
t.Errorf("bad ssh port: %d", b.config.HostSshPort)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_DiskSize(t *testing.T) {
|
||||
@ -183,19 +179,64 @@ func TestBuilderPrepare_ISOChecksum(t *testing.T) {
|
||||
var b Builder
|
||||
config := testConfig()
|
||||
|
||||
// Test good
|
||||
|
||||
b = Builder{}
|
||||
// Test bad
|
||||
config["iso_checksum"] = ""
|
||||
_, 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"] = "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"] = ""
|
||||
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)
|
||||
@ -204,6 +245,23 @@ func TestBuilderPrepare_ISOChecksum(t *testing.T) {
|
||||
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) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package common
|
||||
package iso
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -9,21 +9,18 @@ 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 {
|
||||
// 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
|
||||
|
||||
type stepCreateInstance struct {
|
||||
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").(*Connection)
|
||||
config := state.Get("config").(Config)
|
||||
c := state.Get("client").(*xscommon.Connection)
|
||||
config := state.Get("config").(xscommon.Config)
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
|
||||
ui.Say("Step: Create Instance")
|
||||
@ -104,45 +101,37 @@ func (self *StepCreateInstance) Run(ctx context.Context, state multistep.StateBa
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
// Create VDI for the instance
|
||||
sr, err := config.GetSR(c)
|
||||
|
||||
// Create VDI for the instance
|
||||
sr, err := config.GetSR(c)
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Unable to get SR: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Unable to get SR: %s", err.Error()))
|
||||
return multistep.ActionHalt
|
||||
}
|
||||
ui.Say(fmt.Sprintf("Using the following SR for the VM: %s", sr))
|
||||
|
||||
ui.Say(fmt.Sprintf("Using the following SR for the VM: %s", sr))
|
||||
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
|
||||
|
||||
vdi, err := c.GetClient().VDI.Create(c.GetSessionRef(), xenapi.VDIRecord{
|
||||
NameLabel: config.DiskName,
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
|
||||
// Connect Network
|
||||
@ -179,7 +168,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 = ConnectNetwork(c, network, instance, "0")
|
||||
_, err = xscommon.ConnectNetwork(c, network, instance, "0")
|
||||
|
||||
if err != nil {
|
||||
ui.Error(fmt.Sprintf("Failed to create VIF with error: %v", err))
|
||||
@ -208,7 +197,7 @@ func (self *StepCreateInstance) Run(ctx context.Context, state multistep.StateBa
|
||||
|
||||
//we need the VIF index string
|
||||
vifIndexString := fmt.Sprintf("%d", i)
|
||||
_, err = ConnectNetwork(c, networks[0], instance, vifIndexString)
|
||||
_, err = xscommon.ConnectNetwork(c, networks[0], instance, vifIndexString)
|
||||
|
||||
if err != nil {
|
||||
ui.Say(fmt.Sprintf("Failed to connect VIF with error: %v", err.Error()))
|
||||
@ -216,12 +205,6 @@ 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()))
|
||||
@ -234,14 +217,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").(Config)
|
||||
func (self *stepCreateInstance) Cleanup(state multistep.StateBag) {
|
||||
config := state.Get("config").(xscommon.Config)
|
||||
if config.ShouldKeepVM(state) {
|
||||
return
|
||||
}
|
||||
|
||||
ui := state.Get("ui").(packer.Ui)
|
||||
c := state.Get("client").(*Connection)
|
||||
c := state.Get("client").(*xscommon.Connection)
|
||||
|
||||
if self.instance != nil {
|
||||
ui.Say("Destroying VM")
|
@ -3,6 +3,7 @@ package xva
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/hcl/v2/hcldec"
|
||||
@ -37,12 +38,11 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
|
||||
}, raws...)
|
||||
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(errs, err)
|
||||
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,12 +74,8 @@ func (self *Builder) Prepare(raws ...interface{}) (params []string, warns []stri
|
||||
|
||||
// Validation
|
||||
|
||||
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 self.config.SourcePath == "" {
|
||||
errs = packer.MultiErrorAppend(errs, fmt.Errorf("A source_path must be specified"))
|
||||
}
|
||||
|
||||
if len(errs.Errors) > 0 {
|
||||
@ -105,7 +101,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)
|
||||
@ -120,11 +116,8 @@ 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"
|
||||
@ -141,9 +134,6 @@ 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",
|
||||
@ -163,28 +153,20 @@ 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.InstanceSSHIP,
|
||||
SSHConfig: self.config.Comm.SSHConfigFunc(),
|
||||
SSHPort: xscommon.InstanceSSHPort,
|
||||
Host: xscommon.CommHost,
|
||||
SSHConfig: xscommon.SSHConfigFunc(self.config.CommonConfig.SSHConfig),
|
||||
SSHPort: xscommon.SSHPort,
|
||||
},
|
||||
new(commonsteps.StepProvision),
|
||||
new(xscommon.StepShutdown),
|
||||
new(xscommon.StepSetVmToTemplate),
|
||||
&xscommon.StepDetachVdi{
|
||||
VdiUuidKey: "tools_vdi_uuid",
|
||||
},
|
||||
&xscommon.StepDetachVdi{
|
||||
VdiUuidKey: "floppy_vdi_uuid",
|
||||
},
|
||||
&xscommon.StepDetachVdi{
|
||||
VdiUuidKey: "tools_vdi_uuid",
|
||||
},
|
||||
new(xscommon.StepExport),
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,6 @@ package xva
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/common"
|
||||
"github.com/hashicorp/packer-plugin-sdk/packer"
|
||||
)
|
||||
|
||||
@ -17,7 +16,7 @@ func testConfig() map[string]interface{} {
|
||||
"ssh_username": "foo",
|
||||
"source_path": ".",
|
||||
|
||||
common.BuildNameConfigKey: "foo",
|
||||
packer.BuildNameConfigKey: "foo",
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,7 +39,7 @@ func TestBuilderPrepare_Defaults(t *testing.T) {
|
||||
t.Fatalf("should not have error: %s", err)
|
||||
}
|
||||
|
||||
if b.config.ToolsIsoName != "" {
|
||||
if b.config.ToolsIsoName != "xs-tools.iso" {
|
||||
t.Errorf("bad tools ISO name: %s", b.config.ToolsIsoName)
|
||||
}
|
||||
|
||||
@ -55,10 +54,6 @@ func TestBuilderPrepare_Defaults(t *testing.T) {
|
||||
if b.config.KeepVM != "never" {
|
||||
t.Errorf("bad keep instance: %s", b.config.KeepVM)
|
||||
}
|
||||
|
||||
if b.config.HostSshPort != 22 {
|
||||
t.Errorf("bad ssh port: %d", b.config.HostSshPort)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBuilderPrepare_Format(t *testing.T) {
|
||||
|
@ -3,7 +3,6 @@ package xva
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/multistep"
|
||||
@ -25,11 +24,6 @@ func (self *stepImportInstance) Run(ctx context.Context, state multistep.StateBa
|
||||
|
||||
ui.Say("Step: Import Instance")
|
||||
|
||||
if config.SourcePath == "" {
|
||||
log.Println("Skipping importing instance - no `source_path` configured.")
|
||||
return multistep.ActionContinue
|
||||
}
|
||||
|
||||
// find the SR
|
||||
srs, err := c.GetClient().SR.GetAll(c.GetSessionRef())
|
||||
sr := srs[0]
|
||||
@ -86,12 +80,6 @@ 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
|
||||
|
127
docs/builders/Commented-Example.md
Normal file
127
docs/builders/Commented-Example.md
Normal file
@ -0,0 +1,127 @@
|
||||
---
|
||||
layout: "docs"
|
||||
page_title: "XenServer-iso Commented Example"
|
||||
description: |-
|
||||
This is a Commented example for how to use the xenserver-iso Packer Builder.
|
||||
This Example is written in hcl
|
||||
---
|
||||
|
||||
# What's this
|
||||
This Example builds a vanilla Centos 8 Template. No Provisioning or Post-Processing will be done.
|
||||
|
||||
If you want to run this example, you have to replace the following variables with your own values.
|
||||
```hcl
|
||||
remote_host = "xenserver.example.org"
|
||||
remote_username = "root"
|
||||
remote_password = "very-secret-password"
|
||||
sr_iso_name = "Local-ISO"
|
||||
sr_name = "Local-SR"
|
||||
tools_iso_name = "guest-tools.iso"
|
||||
```
|
||||
|
||||
## Parts of this example
|
||||
This examples composes the following files from the examples folder
|
||||
|
||||
* [centos8-example.pkr.hcl](../../examples/http/centos/centos8-example.pkr.hcl)
|
||||
* [ks-centos8-example.cfg](../../examples/http/centos/ks-centos8-example.cfg)
|
||||
|
||||
|
||||
## Explanation of centos8-example.pkr.hcl
|
||||
|
||||
* `source "xenserver-iso" "example" { } ` directs packer to configure an Artifact named example using the `xenserver-iso` builder
|
||||
|
||||
* `iso_url = "http://mirrors.ocf.berkeley.edu/centos/8.3.2011/isos/x86_64/CentOS-8.3.2011-x86_64-dvd1.iso" ` use the iso obtainable from this url
|
||||
* `iso_checksum_type = "sha1"` the checksum is of type sha1
|
||||
* `iso_checksum = "aaf9d4b3071c16dbbda01dfe06085e5d0fdac76df323e3bbe87cce4318052247"` The checksum for the ISO.
|
||||
|
||||
* `sr_name = "Local-SR"` store the vmdisk used during install on the SR named `Local-SR`
|
||||
* `sr_iso_name = "Local-ISO"` store the iso used during install on the ISO-SR named `Local-ISO`
|
||||
* `tools_iso_name = "guest-tools.iso"` mount the guest-tools iso with the name `guest-tools.iso`
|
||||
|
||||
* `remote_host = "xenserver.example.org"` the ipadress or fqdn of the xenserver. This should be the pool primary
|
||||
* `remote_username = "root"` the user with witch to connect.
|
||||
* `remote_password = "very-secret-password"` the password for the user.
|
||||
|
||||
* `vm_name = "packer-centos8-example"` How packer will name the vm.
|
||||
* `vm_description = "This is an example."` The description field of the vm
|
||||
* `vm_memory = 4096` the Amount of RAM, in MB
|
||||
* `disk_size = 4096` the Size of the Primary Disk in MB
|
||||
|
||||
* `http_directory = "examples/http/centos8'` Packer will spin up a http-server for serving files to the installing vm. the kickstart file `ks-centos8-examples.cfg` is in this directory
|
||||
* `boot_wait = "10s'` Wait for 10s after starting the VM before typeing the `boot_command`
|
||||
* `boot_command = ["<tab> text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks-centos8-examples.cfg<enter><wait>"'`
|
||||
* The command to type into the installing vm.
|
||||
* `<tab>` a tab Character `\t`
|
||||
* `text ks=http://` character literals
|
||||
* `{{ .HTTPIP }}` will be replaced by the local ip-address.
|
||||
* `:` character literal
|
||||
* `{{ .HTTPPort }}` will be replaced by the local port. Will be randomly selectet between 8000 and 9000
|
||||
* `/ks-centos8-examples.cfg` character literals
|
||||
* `<enter>` an enter character
|
||||
* `<wait>` wait for 1s
|
||||
|
||||
* `ssh_username = "root"` The ssh user packer uses to connect to the VM
|
||||
* `ssh_password = "centos"` The ssh password packer uses to connect to the VM
|
||||
* `ssh_wait_timeout = "10m"` consider install failed if unable to connect via ssh 10m into the build
|
||||
* `shutdown_command = "/sbin/shutdown"` After connection via ssh issue this command to shut down the vm
|
||||
* `output_directory = "packer-centos8-local"` Store the resulting xva file in this directory
|
||||
* `keep_vm = "on_success"` Create a template with the vm after a successfull build
|
||||
|
||||
* `build { }` Tell packer what to do while builing
|
||||
* `sources = ["xenserver-iso.example"]` Build the `xenserver.example` without changing any configuration.
|
||||
|
||||
## Explanation of ks-centos8-examples.cfg
|
||||
```
|
||||
eula --agreed
|
||||
# agree to the eula of centos
|
||||
|
||||
lang en-US.UTF-8
|
||||
# set the system-locale to en-US.UTF-8
|
||||
|
||||
timezone Europe/Berlin
|
||||
# set the timezone to Europe/Berlin
|
||||
|
||||
url --url="http://mirror.centos.org/centos/8.3.2011/BaseOS/x86_64/os/"
|
||||
# Primary installation mirror
|
||||
|
||||
text
|
||||
skipx
|
||||
# Install in textmode, do not configure X11
|
||||
|
||||
firstboot --disable
|
||||
# Dont do any configuration on first boot
|
||||
|
||||
rootpw --plaintext centos
|
||||
# set the reboot to "centos"
|
||||
|
||||
firewall --enabled --ssh
|
||||
# enable the firewall, allow ssh
|
||||
|
||||
selinux --enforcing
|
||||
# ensure selinux is in enforcing mode
|
||||
|
||||
logging --level=info
|
||||
# Installation logging level
|
||||
|
||||
network --bootproto=dhcp --device=eth0 --onboot=on
|
||||
# configure the network with dhcp on install
|
||||
|
||||
clearpart --all
|
||||
zerombr
|
||||
bootloader --location=mbr
|
||||
# Clear all partitioning on all disk
|
||||
# Zero the MBR section
|
||||
# Install the bootloader into the MBR
|
||||
|
||||
part / --asprimary --fstype="ext4" --size=1024 --grow
|
||||
# / shall the a primary partition with ext4
|
||||
# with a mimimul size of 1024 MB, but growing to the actual size of the disk
|
||||
|
||||
%packages
|
||||
@base
|
||||
%end
|
||||
# install all packages of the core group
|
||||
|
||||
reboot --eject
|
||||
# After finishing eject all CD-Disk and reboot
|
||||
```
|
127
docs/builders/iso/Commented-Example.md
Normal file
127
docs/builders/iso/Commented-Example.md
Normal file
@ -0,0 +1,127 @@
|
||||
---
|
||||
layout: "docs"
|
||||
page_title: "XenServer-iso Commented Example"
|
||||
description: |-
|
||||
This is a Commented example for how to use the xenserver-iso Packer Builder.
|
||||
This Example is written in hcl
|
||||
---
|
||||
|
||||
# What's this
|
||||
This Example builds a vanilla Centos 8 Template. No Provisioning or Post-Processing will be done.
|
||||
|
||||
If you want to run this example, you have to replace the following variables with your own values.
|
||||
```hcl
|
||||
remote_host = "xenserver.example.org"
|
||||
remote_username = "root"
|
||||
remote_password = "very-secret-password"
|
||||
sr_iso_name = "Local-ISO"
|
||||
sr_name = "Local-SR"
|
||||
tools_iso_name = "guest-tools.iso"
|
||||
```
|
||||
|
||||
## Parts of this example
|
||||
This examples composes the following files from the examples folder
|
||||
|
||||
* [centos8-example.pkr.hcl](../../examples/http/centos/centos8-example.pkr.hcl)
|
||||
* [ks-centos8-example.cfg](../../examples/http/centos/ks-centos8-example.cfg)
|
||||
|
||||
|
||||
## Explanation of centos8-example.pkr.hcl
|
||||
|
||||
* `source "xenserver-iso" "example" { } ` directs packer to configure an Artifact named example using the `xenserver-iso` builder
|
||||
|
||||
* `iso_url = "http://mirrors.ocf.berkeley.edu/centos/8.3.2011/isos/x86_64/CentOS-8.3.2011-x86_64-dvd1.iso" ` use the iso obtainable from this url
|
||||
* `iso_checksum_type = "sha1"` the checksum is of type sha1
|
||||
* `iso_checksum = "aaf9d4b3071c16dbbda01dfe06085e5d0fdac76df323e3bbe87cce4318052247"` The checksum for the ISO.
|
||||
|
||||
* `sr_name = "Local-SR"` store the vmdisk used during install on the SR named `Local-SR`
|
||||
* `sr_iso_name = "Local-ISO"` store the iso used during install on the ISO-SR named `Local-ISO`
|
||||
* `tools_iso_name = "guest-tools.iso"` mount the guest-tools iso with the name `guest-tools.iso`
|
||||
|
||||
* `remote_host = "xenserver.example.org"` the ipadress or fqdn of the xenserver. This should be the pool primary
|
||||
* `remote_username = "root"` the user with witch to connect.
|
||||
* `remote_password = "very-secret-password"` the password for the user.
|
||||
|
||||
* `vm_name = "packer-centos8-example"` How packer will name the vm.
|
||||
* `vm_description = "This is an example."` The description field of the vm
|
||||
* `vm_memory = 4096` the Amount of RAM, in MB
|
||||
* `disk_size = 4096` the Size of the Primary Disk in MB
|
||||
|
||||
* `http_directory = "examples/http/centos8'` Packer will spin up a http-server for serving files to the installing vm. the kickstart file `ks-centos8-examples.cfg` is in this directory
|
||||
* `boot_wait = "10s'` Wait for 10s after starting the VM before typeing the `boot_command`
|
||||
* `boot_command = ["<tab> text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks-centos8-examples.cfg<enter><wait>"'`
|
||||
* The command to type into the installing vm.
|
||||
* `<tab>` a tab Character `\t`
|
||||
* `text ks=http://` character literals
|
||||
* `{{ .HTTPIP }}` will be replaced by the local ip-address.
|
||||
* `:` character literal
|
||||
* `{{ .HTTPPort }}` will be replaced by the local port. Will be randomly selectet between 8000 and 9000
|
||||
* `/ks-centos8-examples.cfg` character literals
|
||||
* `<enter>` an enter character
|
||||
* `<wait>` wait for 1s
|
||||
|
||||
* `ssh_username = "root"` The ssh user packer uses to connect to the VM
|
||||
* `ssh_password = "centos"` The ssh password packer uses to connect to the VM
|
||||
* `ssh_wait_timeout = "10m"` consider install failed if unable to connect via ssh 10m into the build
|
||||
* `shutdown_command = "/sbin/shutdown"` After connection via ssh issue this command to shut down the vm
|
||||
* `output_directory = "packer-centos8-local"` Store the resulting xva file in this directory
|
||||
* `keep_vm = "on_success"` Create a template with the vm after a successfull build
|
||||
|
||||
* `build { }` Tell packer what to do while builing
|
||||
* `sources = ["xenserver-iso.example"]` Build the `xenserver.example` without changing any configuration.
|
||||
|
||||
## Explanation of ks-centos8-examples.cfg
|
||||
```
|
||||
eula --agreed
|
||||
# agree to the eula of centos
|
||||
|
||||
lang en-US.UTF-8
|
||||
# set the system-locale to en-US.UTF-8
|
||||
|
||||
timezone Europe/Berlin
|
||||
# set the timezone to Europe/Berlin
|
||||
|
||||
url --url="http://mirror.centos.org/centos/8.3.2011/BaseOS/x86_64/os/"
|
||||
# Primary installation mirror
|
||||
|
||||
text
|
||||
skipx
|
||||
# Install in textmode, do not configure X11
|
||||
|
||||
firstboot --disable
|
||||
# Dont do any configuration on first boot
|
||||
|
||||
rootpw --plaintext centos
|
||||
# set the reboot to "centos"
|
||||
|
||||
firewall --enabled --ssh
|
||||
# enable the firewall, allow ssh
|
||||
|
||||
selinux --enforcing
|
||||
# ensure selinux is in enforcing mode
|
||||
|
||||
logging --level=info
|
||||
# Installation logging level
|
||||
|
||||
network --bootproto=dhcp --device=eth0 --onboot=on
|
||||
# configure the network with dhcp on install
|
||||
|
||||
clearpart --all
|
||||
zerombr
|
||||
bootloader --location=mbr
|
||||
# Clear all partitioning on all disk
|
||||
# Zero the MBR section
|
||||
# Install the bootloader into the MBR
|
||||
|
||||
part / --asprimary --fstype="ext4" --size=1024 --grow
|
||||
# / shall the a primary partition with ext4
|
||||
# with a mimimul size of 1024 MB, but growing to the actual size of the disk
|
||||
|
||||
%packages
|
||||
@base
|
||||
%end
|
||||
# install all packages of the core group
|
||||
|
||||
reboot --eject
|
||||
# After finishing eject all CD-Disk and reboot
|
||||
```
|
@ -18,6 +18,7 @@ the OS, then shutting it down. The result of the XenServer builder is a
|
||||
directory containing all the files necessary to run the virtual machine
|
||||
portably.
|
||||
|
||||
|
||||
## Configuration Reference
|
||||
|
||||
There are many configuration options available for the XenServer builder.
|
||||
@ -28,37 +29,21 @@ 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 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
|
||||
an example 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.
|
||||
to booting a virtual machine with the ISO attached. The type of the
|
||||
checksum is specified with `iso_checksum_type`, documented below.
|
||||
|
||||
* `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).
|
||||
|
||||
* `remote_ssh_port` (integer) - The port that SSH will be listening on in the Xenserver / XCP-ng pool primary. By default this is 22.
|
||||
* `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_username` (string) - The XenServer username used to access the remote machine.
|
||||
|
||||
@ -74,12 +59,11 @@ 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) and [centos](../../../examples/centos) examples to see how these
|
||||
are used to launch autoinstall and kickstart respectively.
|
||||
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.
|
||||
|
||||
* `boot_wait` (string) - The time to wait after booting the initial virtual
|
||||
machine before typing the `boot_command`. The value of this should be
|
||||
a duration. Examples are `5s` and `1m30s` which will cause Packer to wait
|
||||
a duration. Examples are "5s" and "1m30s" which will cause Packer to wait
|
||||
five seconds and one minute 30 seconds, respectively. If this isn't specified,
|
||||
the default is 10 seconds.
|
||||
|
||||
@ -89,15 +73,9 @@ each category, the available options are alphabetized and described.
|
||||
run `xe template-list`. Setting the correct value hints to XenServer how to
|
||||
optimize the virtual hardware to work best with that operating system.
|
||||
|
||||
* `disk_name` (string) - The name of the hard disk to create for the VM.
|
||||
By default, the name is "Packer-disk".
|
||||
|
||||
* `disk_size` (integer) - The size, in megabytes, of the hard disk to create
|
||||
for the VM. By default, this is 40000 (about 40 GB).
|
||||
|
||||
* `firmware` (string) - Whether to use `bios` or `uefi` as the boot firmware
|
||||
for the resulting VM. Defaults to `bios`.
|
||||
|
||||
* `floppy_files` (array of strings) - A list of files to place onto a floppy
|
||||
disk that is attached when the VM is booted. This is most useful
|
||||
for unattended Windows installs, which look for an `Autounattend.xml` file
|
||||
@ -108,15 +86,15 @@ each category, the available options are alphabetized and described.
|
||||
characters (\*, ?, and []) are allowed. Directory names are also allowed,
|
||||
which will add all the files found in the directory to the floppy.
|
||||
|
||||
* `format` (string) - Either "xva", "xva_compressed", "vdi_raw" or "none", this specifies the
|
||||
* `format` (string) - Either "xva", "vdi_raw" or "none", this specifies the
|
||||
output format of the exported virtual machine. This defaults to "xva". Set to
|
||||
"vdi_raw" to export just the raw disk image. Set to "none" to export nothing;
|
||||
this is only useful with "keep_vm" set to "always" or "on_success".
|
||||
|
||||
* `http_directory` (string) - Path to a directory to serve using an HTTP
|
||||
server. The files in this directory will be available over HTTP which will
|
||||
server. The files in this directory will be available over HTTP that will
|
||||
be requestable from the virtual machine. This is useful for hosting
|
||||
kickstart files and so on. By default, this is `""`, which means no HTTP
|
||||
kickstart files and so on. By default this is "", which means no HTTP
|
||||
server will be started. The address and port of the HTTP server will be
|
||||
available as variables in `boot_command`. This is covered in more detail
|
||||
below.
|
||||
@ -126,7 +104,7 @@ each category, the available options are alphabetized and described.
|
||||
Because Packer often runs in parallel, Packer will choose a randomly available
|
||||
port in this range to run the HTTP server. If you want to force the HTTP
|
||||
server to be on one port, make this minimum and maximum port the same.
|
||||
By default, the values are 8000 and 9000, respectively.
|
||||
By default the values are 8000 and 9000, respectively.
|
||||
|
||||
* `install_timeout` (string) - The amount of time to wait after booting the VM
|
||||
for the installer to shut itself down.
|
||||
@ -136,55 +114,38 @@ each category, the available options are alphabetized and described.
|
||||
* `iso_urls` (array of strings) - Multiple URLs for the ISO to download.
|
||||
Packer will try these in order. If anything goes wrong attempting to download
|
||||
or while downloading a single URL, it will move on to the next. All URLs
|
||||
must point to the same file (same checksum). By default, this is empty
|
||||
must point to the same file (same checksum). By default this is empty
|
||||
and `iso_url` is used. Only one of `iso_url` or `iso_urls` can be specified.
|
||||
|
||||
* `tools_iso_name` (string) - Choose the tools iso you want to use.
|
||||
Usually "guest-tools.iso", or "xs-tools.iso". Not setting this variable causes no tools-related
|
||||
ISO to be attached.
|
||||
|
||||
* `keep_vm` (string) - Determine when to keep the VM and when to clean it up. This
|
||||
can be `always`, `never` or `on_success`. The default is `never`, and Packer
|
||||
can be "always", "never" or "on_success". By default this is "never", and Packer
|
||||
always deletes the VM regardless of whether the process succeeded and an artifact
|
||||
was produced. `always` asks Packer to leave the VM at the end of the process
|
||||
regardless of success. `on_success` requests that the VM only be cleaned up if an
|
||||
was produced. "always" asks Packer to leave the VM at the end of the process
|
||||
regardless of success. "on_success" requests that the VM only be cleaned up if an
|
||||
artifact was produced. The latter is useful for debugging templates that fail.
|
||||
|
||||
* `ip_getter` (string) - Defines the method by which the IP of the guest machine is
|
||||
identified. Options are: `auto`, `tools`, `http`. The default is `auto`, which will
|
||||
attempt both methods. `tools` requires that the guest tools be installed and functional
|
||||
inside the quest machine.
|
||||
|
||||
* `skip_set_template` (bool) - If you want to get the full XVA, to be able to import the VM directly
|
||||
instead of using the output template, you can set this to `true`.
|
||||
|
||||
* `network_names` (array of strings) - A list of networks identified by their name label which
|
||||
* `network_names` (array of strings) - A list of networks identified by their name label which
|
||||
will be used for the VM during creation. The first network will correspond to the VM's
|
||||
first network interface (VIF), the second will correspond to the second VIF and so on.
|
||||
|
||||
* `export_network_names` (array of strings) - A list of networks identified by their name label which
|
||||
will be attached to the export. The first network will correspond to the VM's
|
||||
first network interface (VIF), the second will correspond to the second VIF and so on.
|
||||
first network interface (VIF), the second will corespond to the second VIF and so on.
|
||||
|
||||
* `output_directory` (string) - This is the path to the directory where the
|
||||
resulting virtual machine will be created. This may be relative or absolute.
|
||||
If relative, the path is relative to the working directory when `packer`
|
||||
is executed. This directory must not exist or be empty prior to running the builder.
|
||||
By default, this is "output-BUILDNAME" where "BUILDNAME" is the name
|
||||
By default this is "output-BUILDNAME" where "BUILDNAME" is the name
|
||||
of the build.
|
||||
|
||||
* `platform_args` (object of key/value strings) - The platform args.
|
||||
Defaults to
|
||||
|
||||
```json
|
||||
Defaults to
|
||||
```javascript
|
||||
{
|
||||
"viridian": "false",
|
||||
"nx": "true",
|
||||
"pae": "true",
|
||||
"apic": "true",
|
||||
"timeoffset": "0",
|
||||
"acpi": "1",
|
||||
"cores-per-socket": "1"
|
||||
"viridian": "false",
|
||||
"nx": "true",
|
||||
"pae": "true",
|
||||
"apic": "true",
|
||||
"timeoffset": "0",
|
||||
"acpi": "1",
|
||||
"cores-per-socket": "1"
|
||||
}
|
||||
```
|
||||
|
||||
@ -193,12 +154,6 @@ each category, the available options are alphabetized and described.
|
||||
will shut down the VM gracefully through the Xen api's vm shutdown command. Unless
|
||||
you have special requirements this should typically be left to its default.
|
||||
|
||||
* `sr_name` (string) - The SR to use for storing the disk for the VM that Packer
|
||||
creates. By default, the default SR of the system will be used.
|
||||
|
||||
* `sr_iso_name` (string) - The SR to use for uploading the provided ISO.
|
||||
By default, the default SR of the system will be used.
|
||||
|
||||
* `ssh_host_port_min` and `ssh_host_port_max` (integer) - The minimum and
|
||||
maximum port to use for the SSH port on the host machine which is forwarded
|
||||
to the SSH port on the guest machine. Because Packer often runs in parallel,
|
||||
@ -206,50 +161,46 @@ each category, the available options are alphabetized and described.
|
||||
host port.
|
||||
|
||||
* `ssh_key_path` (string) - Path to a private key to use for authenticating
|
||||
with SSH. By default, this is not set (key-based auth won't be used).
|
||||
with SSH. By default this is not set (key-based auth won't be used).
|
||||
The associated public key is expected to already be configured on the
|
||||
VM being prepared by some other process (kickstart, etc.).
|
||||
|
||||
* `ssh_password` (string) - The password for `ssh_username` to use to
|
||||
authenticate with SSH. By default, this is the empty string.
|
||||
authenticate with SSH. By default this is the empty string.
|
||||
|
||||
* `ssh_port` (integer) - The port that SSH will be listening on in the guest
|
||||
virtual machine. By default, this is `22`.
|
||||
virtual machine. By default this is 22.
|
||||
|
||||
* `ssh_wait_timeout` (string) - The duration to wait for SSH to become
|
||||
available. By default, this is `20m`, or 20 minutes. **Note**: that this should
|
||||
available. By default this is "20m", or 20 minutes. Note that this should
|
||||
be quite long since the timer begins as soon as the virtual machine is booted.
|
||||
|
||||
* `tools_iso_name` (string) - The name of the XenServer Tools ISO. Defaults to
|
||||
`xs-tools.iso`.
|
||||
"xs-tools.iso".
|
||||
|
||||
* `vm_description` (string) - The description of the new virtual
|
||||
machine. By default, this is an empty string.
|
||||
machine. By default this is the empty string.
|
||||
|
||||
* `vm_name` (string) - This is the name of the new virtual
|
||||
machine, without the file extension. By default, this is
|
||||
`packer-BUILDNAME-TIMESTAMP`, where "BUILDNAME" is the name of the build.
|
||||
machine, without the file extension. By default this is
|
||||
"packer-BUILDNAME-TIMESTAMP", where "BUILDNAME" is the name of the build.
|
||||
|
||||
* `vcpus_max` (integer) - The maximum number of VCPUs for the VM.
|
||||
By default, this is `1`.
|
||||
By default this is 1.
|
||||
|
||||
* `vcpus_atstartup` (integer) - The number of startup VCPUs for the VM.
|
||||
By default, this is `1`.
|
||||
By default this is 1.
|
||||
|
||||
* `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
|
||||
allocate for the VM. By default, this is 1024 (1 GB).
|
||||
|
||||
## Differences with other Packer builders
|
||||
|
||||
Currently, the XenServer builder has some quirks when compared with other Packer builders.
|
||||
Currently the XenServer builder has some quirks when compared with other Packer builders.
|
||||
|
||||
The builder currently only works remotely.
|
||||
|
||||
The installer is expected to shut down the VM to indicate that it has completed. This is in contrast to other builders,
|
||||
which instead detect completion by a successful SSH connection. The reason for this difference is that currently the
|
||||
builder has no way of knowing what the IP address of the VM is without starting it on the HIMN.
|
||||
The installer is expected to shut down the VM to indicate that it has completed. This is in contrast to other builders, which instead detect completion by a successful SSH connection. The reason for this difference is that currently the builder has no way of knowing what the IP address of the VM is without starting it on the HIMN.
|
||||
|
||||
## Boot Command
|
||||
|
||||
@ -262,8 +213,8 @@ As documented above, the `boot_command` is an array of strings. The
|
||||
strings are all typed in sequence. It is an array only to improve readability
|
||||
within the template.
|
||||
|
||||
The boot command is "typed" character by character over a VNC connection
|
||||
to the machine, simulating a human actually typing on the keyboard. There are
|
||||
The boot command is "typed" character for character over a VNC connection
|
||||
to the machine, simulating a human actually typing the keyboard. There are
|
||||
a set of special keys available. If these are in your boot command, they
|
||||
will be replaced by the proper key:
|
||||
|
||||
@ -294,7 +245,6 @@ will be replaced by the proper key:
|
||||
|
||||
In addition to the special keys, each command to type is treated as a
|
||||
configuration template.
|
||||
|
||||
The available variables are:
|
||||
|
||||
* `HTTPIP` and `HTTPPort` - The IP and port, respectively of an HTTP server
|
||||
@ -302,4 +252,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.
|
||||
|
@ -6,7 +6,7 @@ In order to see an exhaustive list of configuration options for the packer build
|
||||
|
||||
### Running the examples
|
||||
|
||||
In order to run the examples you will need to perform the following steps:
|
||||
In order to run this example you will need to perform the following steps:
|
||||
1. Export those vars:
|
||||
```
|
||||
PKR_VAR_remote_host
|
||||
@ -15,16 +15,31 @@ PKR_VAR_remote_username
|
||||
PKR_VAR_sr_name
|
||||
PKR_VAR_sr_iso_name
|
||||
```
|
||||
`PKR_VAR_remote_host` must be the resource pool primary, aka the master.
|
||||
`PKR_VAR_remote_host` must be the resource pool primary.
|
||||
|
||||
2. Run `packer init path/to/defenition.pkr.hcl` to download the xenserver plugin
|
||||
|
||||
2. Run `packer build path/to/defenition.pkr.hcl`
|
||||
so for example:
|
||||
`packer build examples/centos/centos8-netinstall.pkr.hcl`
|
||||
|
||||
|
||||
### Ubuntu
|
||||
|
||||
This example has not yet updated to HCL.
|
||||
|
||||
In order to run this example you will need to perform the following steps:
|
||||
1. Export the `XAPI_HOST`, `XAPI_USERNAME` and `XAPI_PASSWORD` environment variables to the current shell. Note: The `XAPI_HOST` must be the resource pool primary.
|
||||
2. Run the `packer build` command specifying the storage repositories to use for the ISO upload and for the VM created during the build.
|
||||
|
||||
```
|
||||
# Replace sr_name and sr_iso_name with your storage repositories names
|
||||
packer build -debug --var sr_name='Local storage' --var sr_iso_name=LocalISO examples/centos8.json
|
||||
|
||||
# Do the same variable replacement for the ubuntu example as well.
|
||||
packer build -debug --var sr_name='Local storage' --var sr_iso_name=LocalISO examples/ubuntu-2004.json
|
||||
```
|
||||
|
||||
|
||||
The Ubuntu example uses the [autoinstall tool](https://ubuntu.com/server/docs/install/autoinstallhttps://ubuntu.com/server/docs/install/autoinstall) to configure the VM template. Please see the [autoinstall docs](https://ubuntu.com/server/docs/install/autoinstall-reference) for an exhaustive list of what is supported.
|
||||
|
||||
Packer will create a http server to serve the files as specified from the `http_directory` specified in the builder configuration. This is where the [user-data](http/ubuntu-2004/user-data) and [meta-data](http/ubuntu-2004/meta-data) for autoinstall must be present.
|
||||
|
53
examples/centos/centos8-example.pkr.hcl
Normal file
53
examples/centos/centos8-example.pkr.hcl
Normal file
@ -0,0 +1,53 @@
|
||||
source "xenserver-iso" "example" {
|
||||
#
|
||||
# Where to get the iso
|
||||
#
|
||||
iso_url = "http://mirrors.ocf.berkeley.edu/centos/8.3.2011/isos/x86_64/CentOS-8.3.2011-x86_64-dvd1.iso"
|
||||
iso_checksum_type = "sha1"
|
||||
iso_checksum = "aaf9d4b3071c16dbbda01dfe06085e5d0fdac76df323e3bbe87cce4318052247"
|
||||
#
|
||||
# Where to store the ISO, vm-disk and where to find the xentools iso
|
||||
#
|
||||
sr_iso_name = "Local-ISO"
|
||||
sr_name = "Local-SR"
|
||||
tools_iso_name = "guest-tools.iso"
|
||||
#
|
||||
# How to communicate with the xenserver
|
||||
#
|
||||
remote_host = "xenserver.example.org"
|
||||
remote_username = "root"
|
||||
remote_password = "very-secret-password"
|
||||
#
|
||||
# Basic info for the vm
|
||||
#
|
||||
vm_name = "packer-centos8-example"
|
||||
vm_description = "This is an example."
|
||||
vm_memory = 4096
|
||||
disk_size = 4096
|
||||
#
|
||||
# For the installation
|
||||
#
|
||||
http_directory = "examples/http/centos8"
|
||||
boot_command = ["<tab> text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks-centos8-examples.cfg<enter><wait>"]
|
||||
boot_wait = "10s"
|
||||
#
|
||||
# how packer contacts the vm
|
||||
#
|
||||
ssh_username = "root"
|
||||
ssh_password = "centos"
|
||||
ssh_wait_timeout = "10m"
|
||||
shutdown_command = "/sbin/shutdown"
|
||||
#
|
||||
# What to do with the resulting VM
|
||||
#
|
||||
output_directory = "packer-centos8-local"
|
||||
keep_vm = "on_success"
|
||||
|
||||
}
|
||||
#
|
||||
# Operations to do while building.
|
||||
# Any provisioning would be done here
|
||||
#
|
||||
build {
|
||||
sources = ["xenserver-iso.example"]
|
||||
}
|
@ -1,29 +1,20 @@
|
||||
packer {
|
||||
required_plugins {
|
||||
xenserver= {
|
||||
version = ">= v0.6.0"
|
||||
source = "github.com/ddelnano/xenserver"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "remote_host" {
|
||||
type = string
|
||||
description = "The ip or fqdn of your XenServer. This will be pulled from the env var 'PKR_VAR_remote_host'"
|
||||
description = "The ip or fqdn of your XenServer. This will be pulled from the env var 'PKR_VAR_XAPI_HOST'"
|
||||
sensitive = true
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "remote_password" {
|
||||
type = string
|
||||
description = "The password used to interact with your XenServer. This will be pulled from the env var 'PKR_VAR_remote_password'"
|
||||
description = "The password used to interact with your XenServer. This will be pulled from the env var 'PKR_VAR_XAPI_PASSWORD'"
|
||||
sensitive = true
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "remote_username" {
|
||||
type = string
|
||||
description = "The username used to interact with your XenServer. This will be pulled from the env var 'PKR_VAR_remote_username'"
|
||||
description = "The username used to interact with your XenServer. This will be pulled from the env var 'PKR_VAR_XAPI_USERNAME'"
|
||||
sensitive = true
|
||||
default = null
|
||||
|
||||
@ -47,7 +38,8 @@ locals {
|
||||
}
|
||||
|
||||
source "xenserver-iso" "centos8-local" {
|
||||
iso_checksum = "sha1:aaf9d4b3071c16dbbda01dfe06085e5d0fdac76df323e3bbe87cce4318052247"
|
||||
iso_checksum = "aaf9d4b3071c16dbbda01dfe06085e5d0fdac76df323e3bbe87cce4318052247"
|
||||
iso_checksum_type = "sha1"
|
||||
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
|
||||
@ -59,7 +51,7 @@ source "xenserver-iso" "centos8-local" {
|
||||
remote_username = var.remote_username
|
||||
|
||||
vm_name = "packer-centos8-local-${local.timestamp}"
|
||||
vm_description = "Build started: ${local.timestamp}\n This was installed from the dvd"
|
||||
vm_description = "Build started: ${local.timestamp}\n This was installed From the dvd"
|
||||
vm_memory = 4096
|
||||
disk_size = 4096
|
||||
|
||||
@ -70,6 +62,7 @@ source "xenserver-iso" "centos8-local" {
|
||||
ssh_username = "root"
|
||||
ssh_password = "centos"
|
||||
ssh_wait_timeout = "10000s"
|
||||
shutdown_command = "/sbin/shutdown"
|
||||
|
||||
output_directory = "packer-centos8-local"
|
||||
keep_vm = "always"
|
||||
@ -77,4 +70,4 @@ source "xenserver-iso" "centos8-local" {
|
||||
|
||||
build {
|
||||
sources = ["xenserver-iso.centos8-local"]
|
||||
}
|
||||
}
|
@ -1,29 +1,20 @@
|
||||
packer {
|
||||
required_plugins {
|
||||
xenserver= {
|
||||
version = ">= v0.6.0"
|
||||
source = "github.com/ddelnano/xenserver"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
variable "remote_host" {
|
||||
type = string
|
||||
description = "The ip or fqdn of your XenServer. This will be pulled from the env var 'PKR_VAR_remote_host'"
|
||||
description = "The ip or fqdn of your XenServer. This will be pulled from the env var 'PKR_VAR_XAPI_HOST'"
|
||||
sensitive = true
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "remote_password" {
|
||||
type = string
|
||||
description = "The password used to interact with your XenServer. This will be pulled from the env var 'PKR_VAR_remote_password'"
|
||||
description = "The password used to interact with your XenServer. This will be pulled from the env var 'PKR_VAR_XAPI_PASSWORD'"
|
||||
sensitive = true
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "remote_username" {
|
||||
type = string
|
||||
description = "The username used to interact with your XenServer. This will be pulled from the env var 'PKR_VAR_remote_username'"
|
||||
description = "The username used to interact with your XenServer. This will be pulled from the env var 'PKR_VAR_XAPI_USERNAME'"
|
||||
sensitive = true
|
||||
default = null
|
||||
|
||||
@ -47,7 +38,8 @@ locals {
|
||||
}
|
||||
|
||||
source "xenserver-iso" "centos8-netinstall" {
|
||||
iso_checksum = "sha1:07a8e59c42cc086ec4c49bdce4fae5a17b077dea"
|
||||
iso_checksum = "07a8e59c42cc086ec4c49bdce4fae5a17b077dea"
|
||||
iso_checksum_type = "sha1"
|
||||
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
|
||||
@ -70,6 +62,7 @@ source "xenserver-iso" "centos8-netinstall" {
|
||||
ssh_username = "root"
|
||||
ssh_password = "centos"
|
||||
ssh_wait_timeout = "10000s"
|
||||
shutdown_command = "/sbin/shutdown"
|
||||
|
||||
output_directory = "packer-centos8-netinstall"
|
||||
keep_vm = "always"
|
||||
@ -77,4 +70,4 @@ source "xenserver-iso" "centos8-netinstall" {
|
||||
|
||||
build {
|
||||
sources = ["xenserver-iso.centos8-netinstall"]
|
||||
}
|
||||
}
|
42
examples/centos8.json
Normal file
42
examples/centos8.json
Normal file
@ -0,0 +1,42 @@
|
||||
{
|
||||
"variables": {
|
||||
"sr_name": "",
|
||||
"sr_iso_name": "",
|
||||
"remote_host": "{{env `XAPI_HOST`}}",
|
||||
"remote_username": "{{env `XAPI_USERNAME`}}",
|
||||
"remote_password": "{{env `XAPI_PASSWORD`}}"
|
||||
},
|
||||
"builders": [
|
||||
{
|
||||
"type": "xenserver-iso",
|
||||
"sr_name": "{{user `sr_name`}}",
|
||||
"sr_iso_name": "{{user `sr_iso_name`}}",
|
||||
"remote_host": "{{user `remote_host`}}",
|
||||
"remote_username": "{{user `remote_username`}}",
|
||||
"remote_password": "{{user `remote_password`}}",
|
||||
"vm_memory": "4096",
|
||||
"boot_command": [
|
||||
"<tab> text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks-centos8.cfg<enter><wait>"
|
||||
],
|
||||
"boot_wait": "10s",
|
||||
"disk_size": 40960,
|
||||
"http_directory": "examples/http/centos8",
|
||||
"iso_checksum": "07a8e59c42cc086ec4c49bdce4fae5a17b077dea",
|
||||
"iso_checksum_type": "sha1",
|
||||
"iso_url": "http://mirrors.ocf.berkeley.edu/centos/8.3.2011/isos/x86_64/CentOS-8.3.2011-x86_64-boot.iso",
|
||||
"iso_name": "CentOS-8.3.2011-x86_64-boot.iso",
|
||||
"tools_iso_name": "guest-tools.iso",
|
||||
"vm_other_config": {
|
||||
"conversionvm":"true"
|
||||
},
|
||||
"output_directory": "packer-centos-8.3-x86_64-xenserver",
|
||||
"ssh_username": "vagrant",
|
||||
"ssh_password": "vagrant",
|
||||
"ssh_wait_timeout": "10000s",
|
||||
"ssh_agent_auth": false,
|
||||
"vm_name": "packer-centos-8.3-x86_64-{{isotime}}",
|
||||
"vm_description": "Build time: {{isotime}}",
|
||||
"keep_vm": "always"
|
||||
}
|
||||
]
|
||||
}
|
52
examples/http/centos8/ks-centos8-example.cfg
Normal file
52
examples/http/centos8/ks-centos8-example.cfg
Normal file
@ -0,0 +1,52 @@
|
||||
eula --agreed
|
||||
# agree to the eula of centos
|
||||
|
||||
lang en-US.UTF-8
|
||||
# set the system-locale to en-US.UTF-8
|
||||
|
||||
timezone Europe/Berlin
|
||||
# set the timezone to Europe/Berlin
|
||||
|
||||
url --url="http://mirror.centos.org/centos/8.3.2011/BaseOS/x86_64/os/"
|
||||
# Primary installation mirror
|
||||
|
||||
text
|
||||
skipx
|
||||
# Install in textmode, do not configure X11
|
||||
|
||||
firstboot --disable
|
||||
# Dont do any configuration on first boot
|
||||
|
||||
rootpw --plaintext centos
|
||||
# set the reboot to "centos"
|
||||
|
||||
firewall --enabled --ssh
|
||||
# enable the firewall, allow ssh
|
||||
|
||||
selinux --enforcing
|
||||
# ensure selinux is in enforcing mode
|
||||
|
||||
logging --level=info
|
||||
# Installation logging level
|
||||
|
||||
network --bootproto=dhcp --device=eth0 --onboot=on
|
||||
# configure the network with dhcp on install
|
||||
|
||||
clearpart --all
|
||||
zerombr
|
||||
bootloader --location=mbr
|
||||
# Clear all partitioning on all disk
|
||||
# Zero the MBR section
|
||||
# Install the bootloader into the MBR
|
||||
|
||||
part / --asprimary --fstype="ext4" --size=1024 --grow
|
||||
# / shall the a primary partition with ext4
|
||||
# with a mimimul size of 1024 MB, but growing to the actual size of the disk
|
||||
|
||||
%packages
|
||||
@base
|
||||
%end
|
||||
# install all packages of the core group
|
||||
|
||||
reboot --eject
|
||||
# After finishing eject all CD-Disk and reboot
|
@ -1,13 +1,4 @@
|
||||
#cloud-config
|
||||
|
||||
# hack for cloud-init per:
|
||||
# https://github.com/leakespeake/packer/blob/3f3e361751b4be9326b66771d96f2519bc8f885e/builders/vmware/vsphere-iso/ubuntu-server-20-04/hcl2/http/ubuntu-server-subiquity/user-data
|
||||
runcmd:
|
||||
# to enable true auto-install for Ubuntu 20.04 with cloud-init nocloud (eliminates "Continue with autoinstall?" prompt)
|
||||
- [eval, 'echo $(cat /proc/cmdline) "autoinstall" > /root/cmdline']
|
||||
- [eval, 'mount -n --bind -o ro /root/cmdline /proc/cmdline']
|
||||
- [eval, 'snap restart subiquity.subiquity-service']
|
||||
|
||||
autoinstall:
|
||||
version: 1
|
||||
identity:
|
||||
@ -15,8 +6,6 @@ autoinstall:
|
||||
# This is the crypted pass of 'ubuntu'
|
||||
password: "$6$exDY1mhS4KUYCE/2$zmn9ToZwTKLhCw.b4/b.ZRTIZM30JZ4QrOQ2aOXJ8yk96xpcCof0kxKwuX1kqLG/ygbJ1f8wxED22bTL4F46P0"
|
||||
username: testuser
|
||||
packages:
|
||||
- xe-guest-utilities
|
||||
ssh:
|
||||
install-server: yes
|
||||
allow-pw: yes
|
||||
|
44
examples/ubuntu-2004.json
Normal file
44
examples/ubuntu-2004.json
Normal file
@ -0,0 +1,44 @@
|
||||
{
|
||||
"variables": {
|
||||
"sr_name": "",
|
||||
"sr_iso_name": "",
|
||||
"remote_host": "{{env `XAPI_HOST`}}",
|
||||
"remote_username": "{{env `XAPI_USERNAME`}}",
|
||||
"remote_password": "{{env `XAPI_PASSWORD`}}"
|
||||
},
|
||||
"builders": [
|
||||
{
|
||||
"type": "xenserver-iso",
|
||||
"sr_name": "{{user `sr_name`}}",
|
||||
"sr_iso_name": "{{user `sr_iso_name`}}",
|
||||
"remote_host": "{{user `remote_host`}}",
|
||||
"remote_username": "{{user `remote_username`}}",
|
||||
"remote_password": "{{user `remote_password`}}",
|
||||
"tools_iso_name": "guest-tools.iso",
|
||||
"boot_command": [
|
||||
"<esc><f6> autoinstall ds=nocloud-net;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/<enter><wait>",
|
||||
"<f6><wait><esc><wait> autoinstall ds=nocloud-net;s=http://{{ .HTTPIP }}:{{ .HTTPPort }}/<enter><wait>"
|
||||
],
|
||||
"boot_wait": "10s",
|
||||
"disk_size": 10960,
|
||||
"http_directory": "examples/http/ubuntu-2004",
|
||||
"iso_checksum": "443511f6bf12402c12503733059269a2e10dec602916c0a75263e5d990f6bb93",
|
||||
"iso_checksum_type": "sha256",
|
||||
"iso_url": "http://releases.ubuntu.com/20.04/ubuntu-20.04.1-live-server-amd64.iso",
|
||||
"iso_name": "ubuntu-20.04.1-live-server-amd64.iso",
|
||||
"vm_other_config": {
|
||||
"conversionvm":"true"
|
||||
},
|
||||
"output_directory": "packer-ubuntu-2004-x86_64-xenserver",
|
||||
"ssh_username": "testuser",
|
||||
"ssh_password": "ubuntu",
|
||||
"ssh_wait_timeout": "60000s",
|
||||
"ssh_timeout": "60000s",
|
||||
"vm_name": "packer-ubuntu-2004-x86_64 {{isotime}}",
|
||||
"vm_description": "Build time: {{isotime}}",
|
||||
"vm_memory": "4096",
|
||||
"keep_vm": "always",
|
||||
"ssh_handshake_attempts": "10000"
|
||||
}
|
||||
]
|
||||
}
|
@ -1,111 +0,0 @@
|
||||
packer {
|
||||
required_plugins {
|
||||
xenserver= {
|
||||
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'"
|
||||
sensitive = true
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "remote_password" {
|
||||
type = string
|
||||
description = "The password used to interact with your XenServer. This will be pulled from the env var 'PKR_VAR_XAPI_PASSWORD'"
|
||||
sensitive = true
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "remote_username" {
|
||||
type = string
|
||||
description = "The username used to interact with your XenServer. This will be pulled from the env var 'PKR_VAR_XAPI_USERNAME'"
|
||||
sensitive = true
|
||||
default = null
|
||||
|
||||
}
|
||||
|
||||
variable "sr_iso_name" {
|
||||
type = string
|
||||
default = ""
|
||||
description = "The ISO-SR to packer will use"
|
||||
|
||||
}
|
||||
|
||||
variable "sr_name" {
|
||||
type = string
|
||||
default = ""
|
||||
description = "The name of the SR to packer will use"
|
||||
}
|
||||
|
||||
source "xenserver-iso" "ubuntu-2004" {
|
||||
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
|
||||
tools_iso_name = "guest-tools.iso"
|
||||
|
||||
remote_host = var.remote_host
|
||||
remote_password = var.remote_password
|
||||
remote_username = var.remote_username
|
||||
|
||||
# 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 = 30720
|
||||
|
||||
floppy_files = [
|
||||
"examples/http/ubuntu-2004/meta-data",
|
||||
"examples/http/ubuntu-2004/user-data",
|
||||
]
|
||||
|
||||
ssh_username = "testuser"
|
||||
ssh_password = "ubuntu"
|
||||
ssh_wait_timeout = "60000s"
|
||||
ssh_handshake_attempts = 10000
|
||||
|
||||
output_directory = "packer-ubuntu-2004-iso"
|
||||
keep_vm = "always"
|
||||
}
|
||||
|
||||
build {
|
||||
sources = ["xenserver-iso.ubuntu-2004"]
|
||||
}
|
101
go.mod
101
go.mod
@ -1,104 +1,15 @@
|
||||
module github.com/xenserver/packer-builder-xenserver
|
||||
|
||||
go 1.20
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/amfranz/go-xmlrpc-client v0.0.0-20190612172737-76858463955d
|
||||
github.com/hashicorp/hcl/v2 v2.20.1
|
||||
github.com/hashicorp/packer-plugin-sdk v0.3.0
|
||||
github.com/hashicorp/hcl/v2 v2.8.0
|
||||
github.com/hashicorp/packer-plugin-sdk v0.1.0
|
||||
github.com/mitchellh/go-vnc v0.0.0-20150629162542-723ed9867aed
|
||||
github.com/terra-farm/go-xen-api-client v0.0.2
|
||||
github.com/zclconf/go-cty v1.14.4
|
||||
golang.org/x/crypto v0.24.0
|
||||
)
|
||||
|
||||
require (
|
||||
cloud.google.com/go v0.110.0 // indirect
|
||||
cloud.google.com/go/compute v1.19.1 // indirect
|
||||
cloud.google.com/go/compute/metadata v0.2.3 // indirect
|
||||
cloud.google.com/go/iam v0.13.0 // indirect
|
||||
cloud.google.com/go/storage v1.28.1 // indirect
|
||||
github.com/Azure/go-ntlmssp v0.0.0-20200615164410-66371956d46c // indirect
|
||||
github.com/ChrisTrenkamp/goxpath v0.0.0-20210404020558-97928f7e12b6 // indirect
|
||||
github.com/agext/levenshtein v1.2.3 // indirect
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect
|
||||
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
|
||||
github.com/armon/go-metrics v0.3.9 // indirect
|
||||
github.com/aws/aws-sdk-go v1.40.34 // indirect
|
||||
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
|
||||
github.com/cenkalti/backoff/v3 v3.2.2 // indirect
|
||||
github.com/dylanmei/iso8601 v0.1.0 // indirect
|
||||
github.com/fatih/color v1.12.0 // indirect
|
||||
github.com/gofrs/flock v0.8.1 // indirect
|
||||
github.com/gofrs/uuid v4.0.0+incompatible // indirect
|
||||
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
|
||||
github.com/golang/protobuf v1.5.3 // indirect
|
||||
github.com/golang/snappy v0.0.4 // indirect
|
||||
github.com/google/go-cmp v0.6.0 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
|
||||
github.com/googleapis/gax-go/v2 v2.7.1 // indirect
|
||||
github.com/hashicorp/consul/api v1.10.1 // indirect
|
||||
github.com/hashicorp/errwrap v1.1.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
|
||||
github.com/hashicorp/go-getter/gcs/v2 v2.1.0 // indirect
|
||||
github.com/hashicorp/go-getter/s3/v2 v2.1.0 // indirect
|
||||
github.com/hashicorp/go-getter/v2 v2.1.0 // indirect
|
||||
github.com/hashicorp/go-hclog v0.16.2 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-retryablehttp v0.7.0 // indirect
|
||||
github.com/hashicorp/go-rootcerts v1.0.2 // indirect
|
||||
github.com/hashicorp/go-safetemp v1.0.0 // indirect
|
||||
github.com/hashicorp/go-sockaddr v1.0.2 // indirect
|
||||
github.com/hashicorp/go-version v1.3.0 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/hashicorp/hcl v1.0.0 // indirect
|
||||
github.com/hashicorp/serf v0.9.5 // indirect
|
||||
github.com/hashicorp/vault/api v1.1.1 // indirect
|
||||
github.com/hashicorp/vault/sdk v0.2.1 // indirect
|
||||
github.com/hashicorp/yamux v0.0.0-20210826001029-26ff87cf9493 // indirect
|
||||
github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect
|
||||
github.com/jmespath/go-jmespath v0.4.0 // indirect
|
||||
github.com/kr/fs v0.1.0 // indirect
|
||||
github.com/masterzen/simplexml v0.0.0-20190410153822-31eea3082786 // indirect
|
||||
github.com/masterzen/winrm v0.0.0-20210623064412-3b76017826b0 // indirect
|
||||
github.com/mattn/go-colorable v0.1.8 // indirect
|
||||
github.com/mattn/go-isatty v0.0.13 // indirect
|
||||
github.com/mitchellh/go-fs v0.0.0-20180402235330-b7b9ca407fff // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/go-testing-interface v1.14.1 // indirect
|
||||
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
|
||||
github.com/mitchellh/iochan v1.0.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.1 // indirect
|
||||
github.com/mitchellh/reflectwalk v1.0.0 // indirect
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e // indirect
|
||||
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
|
||||
github.com/packer-community/winrmcp v0.0.0-20180921211025-c76d91c1e7db // indirect
|
||||
github.com/pierrec/lz4 v2.6.1+incompatible // indirect
|
||||
github.com/pkg/sftp v1.13.2 // indirect
|
||||
github.com/ryanuber/go-glob v1.0.0 // indirect
|
||||
github.com/ugorji/go/codec v1.2.6 // indirect
|
||||
github.com/ulikunitz/xz v0.5.10 // indirect
|
||||
go.opencensus.io v0.24.0 // indirect
|
||||
golang.org/x/mod v0.17.0 // indirect
|
||||
golang.org/x/net v0.25.0 // indirect
|
||||
golang.org/x/oauth2 v0.7.0 // indirect
|
||||
golang.org/x/sync v0.7.0 // indirect
|
||||
golang.org/x/sys v0.21.0 // indirect
|
||||
golang.org/x/term v0.21.0 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
|
||||
golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d // indirect
|
||||
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
|
||||
google.golang.org/api v0.114.0 // indirect
|
||||
google.golang.org/appengine v1.6.7 // indirect
|
||||
google.golang.org/genproto v0.0.0-20230410155749-daa745c078e1 // indirect
|
||||
google.golang.org/grpc v1.56.3 // indirect
|
||||
google.golang.org/protobuf v1.33.0 // indirect
|
||||
github.com/terra-farm/go-xen-api-client v0.0.1
|
||||
github.com/zclconf/go-cty v1.7.0
|
||||
golang.org/x/crypto v0.0.0-20201208171446-5f87f3452ae9
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/zclconf/go-cty => github.com/nywilken/go-cty v1.13.3 // added by packer-sdc fix as noted in github.com/hashicorp/packer-plugin-sdk/issues/187
|
||||
|
18
main.go
18
main.go
@ -6,16 +6,30 @@ import (
|
||||
|
||||
"github.com/xenserver/packer-builder-xenserver/builder/xenserver/iso"
|
||||
"github.com/xenserver/packer-builder-xenserver/builder/xenserver/xva"
|
||||
"github.com/xenserver/packer-builder-xenserver/version"
|
||||
|
||||
"github.com/hashicorp/packer-plugin-sdk/plugin"
|
||||
"github.com/hashicorp/packer-plugin-sdk/version"
|
||||
)
|
||||
|
||||
var (
|
||||
// Version is the main version number that is being run at the moment.
|
||||
Version = "v0.3.0"
|
||||
|
||||
// VersionPrerelease is A pre-release marker for the Version. If this is ""
|
||||
// (empty string) then it means that it is a final release. Otherwise, this
|
||||
// is a pre-release such as "dev" (in development), "beta", "rc1", etc.
|
||||
VersionPrerelease = ""
|
||||
|
||||
// PluginVersion is used by the plugin set to allow Packer to recognize
|
||||
// what version this plugin is.
|
||||
PluginVersion = version.InitializePluginVersion(Version, VersionPrerelease)
|
||||
)
|
||||
|
||||
func main() {
|
||||
pps := plugin.NewSet()
|
||||
pps.RegisterBuilder("iso", new(iso.Builder))
|
||||
pps.RegisterBuilder("xva", new(xva.Builder))
|
||||
pps.SetVersion(version.PluginVersion)
|
||||
pps.SetVersion(PluginVersion)
|
||||
err := pps.Run()
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, err.Error())
|
||||
|
6
packer.json
Normal file
6
packer.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"builders": [{
|
||||
"type": "xenserver-iso",
|
||||
"tools_iso_name": "guest-tools.iso"
|
||||
}]
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package version
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/packer-plugin-sdk/version"
|
||||
)
|
||||
|
||||
var (
|
||||
// Version is the main version number that is being run at the moment.
|
||||
Version = "v0.6.0"
|
||||
|
||||
// VersionPrerelease is A pre-release marker for the Version. If this is ""
|
||||
// (empty string) then it means that it is a final release. Otherwise, this
|
||||
// is a pre-release such as "dev" (in development), "beta", "rc1", etc.
|
||||
VersionPrerelease = "dev"
|
||||
|
||||
// PluginVersion is used by the plugin set to allow Packer to recognize
|
||||
// what version this plugin is.
|
||||
PluginVersion = version.InitializePluginVersion(Version, VersionPrerelease)
|
||||
)
|
Loading…
Reference in New Issue
Block a user