Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maintenance changes #99

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ go:
- 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
- ./build.sh
21 changes: 15 additions & 6 deletions Godeps/Godeps.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

51 changes: 51 additions & 0 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Go
# Build your Go project.
# Add steps that test, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/go

trigger:
- master

pool:
vmImage: 'ubuntu-latest'

variables:
GOBIN: '$(GOPATH)/bin' # Go binaries path
GOROOT: '/usr/local/go1.11' # Go installation path
GOPATH: '$(system.defaultWorkingDirectory)/gopath' # Go workspace path
modulePath: '$(GOPATH)/src/github.com/$(build.repository.name)' # Path to the module's code

steps:
- script: |
mkdir -p '$(GOBIN)'
mkdir -p '$(GOPATH)/pkg'
mkdir -p '$(modulePath)'
shopt -s extglob
shopt -s dotglob
mv !(gopath) '$(modulePath)'
echo '##vso[task.prependpath]$(GOBIN)'
echo '##vso[task.prependpath]$(GOROOT)/bin'
displayName: 'Set up the Go workspace'

- script: |
go version
if [ -f Gopkg.toml ]; then
curl https://raw.githubusercontent.com/golang/dep/master/install.sh | sh
dep ensure
fi
cd $(GOPATH)
mkdir -p src/github.com/xenserver/
cd src/github.com/xenserver
git clone https://github.com/xenserver/packer-builder-xenserver.git
cd packer-builder-xenserver
go get github.com/mitchellh/go-vnc
go get github.com/mitchellh/gox
./build.sh
workingDirectory: '$(modulePath)'
displayName: 'Get dependencies, then build'

- task: PublishPipelineArtifact@1
inputs:
targetPath: '$(Pipeline.Workspace)'
artifact: 'xs'
publishLocation: 'pipeline'
3 changes: 3 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ rm -rf pkg/*
rm -rf $GOPATH/pkg/*
mkdir -p bin/

# Fix for ./build.sh: gox: command not found
go get github.com/mitchellh/gox

gox \
-os="${XC_OS}" \
-arch="${XC_ARCH}" \
Expand Down
31 changes: 24 additions & 7 deletions builder/xenserver/common/common_config.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@ import (
)

type CommonConfig struct {
Username string `mapstructure:"remote_username"`
Password string `mapstructure:"remote_password"`
HostIp string `mapstructure:"remote_host"`
Username string `mapstructure:"remote_username"`
Password string `mapstructure:"remote_password"`
HostIp string `mapstructure:"remote_host"`
XenSSHPort uint `mapstructure:"remote_ssh_port"`

VMName string `mapstructure:"vm_name"`
VMDescription string `mapstructure:"vm_description"`
Expand All @@ -28,8 +29,10 @@ type CommonConfig struct {
HostPortMin uint `mapstructure:"host_port_min"`
HostPortMax uint `mapstructure:"host_port_max"`

BootCommand []string `mapstructure:"boot_command"`
ShutdownCommand string `mapstructure:"shutdown_command"`
PreBootHostScripts []string `mapstructure:"pre_boot_host_scripts"`
PreExportHostScripts []string `mapstructure:"pre_export_host_scripts"`
BootCommand []string `mapstructure:"boot_command"`
ShutdownCommand string `mapstructure:"shutdown_command"`

RawBootWait string `mapstructure:"boot_wait"`
BootWait time.Duration
Expand All @@ -40,6 +43,8 @@ type CommonConfig struct {
HTTPPortMin uint `mapstructure:"http_port_min"`
HTTPPortMax uint `mapstructure:"http_port_max"`

Communicator string `mapstructure:"communicator"`

// SSHHostPortMin uint `mapstructure:"ssh_host_port_min"`
// SSHHostPortMax uint `mapstructure:"ssh_host_port_max"`
SSHKeyPath string `mapstructure:"ssh_key_path"`
Expand All @@ -51,6 +56,10 @@ type CommonConfig struct {
RawSSHWaitTimeout string `mapstructure:"ssh_wait_timeout"`
SSHWaitTimeout time.Duration

ConvertToTemplate bool `mapstructure:"convert_to_template"`
DestroyVIFs bool `mapstructure:"destroy_vifs"`
DiscDrives int `mapstructure:"disc_drives"`

OutputDir string `mapstructure:"output_directory"`
Format string `mapstructure:"format"`
KeepVM string `mapstructure:"keep_vm"`
Expand All @@ -63,6 +72,10 @@ func (c *CommonConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig

// Set default values

if c.XenSSHPort == 0 {
c.XenSSHPort = 22
}

if c.HostPortMin == 0 {
c.HostPortMin = 5900
}
Expand Down Expand Up @@ -175,7 +188,7 @@ func (c *CommonConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig
}
*/

if c.SSHUser == "" {
if c.SSHUser == "" && c.Communicator != "winrm" {
errs = append(errs, errors.New("An ssh_username must be specified."))
}

Expand All @@ -184,10 +197,14 @@ func (c *CommonConfig) Prepare(ctx *interpolate.Context, pc *common.PackerConfig
errs = append(errs, fmt.Errorf("Failed to parse ssh_wait_timeout: %s", err))
}

if c.DiscDrives < 0 {
errs = append(errs, errors.New("disc_drives greater than or equal to 0."))
}

switch c.Format {
case "xva", "xva_compressed", "vdi_raw", "vdi_vhd", "none":
default:
errs = append(errs, errors.New("format must be one of 'xva', 'vdi_raw', 'vdi_vhd', 'none'"))
errs = append(errs, errors.New("format must be one of 'xva', 'xva_compressed', 'vdi_raw', 'vdi_vhd', 'none'"))
}

switch c.KeepVM {
Expand Down
116 changes: 116 additions & 0 deletions builder/xenserver/common/step_configure_disc_drives.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package common

import (
"fmt"
"github.com/mitchellh/multistep"
"github.com/mitchellh/packer/packer"
"github.com/nilshell/xmlrpc"
xsclient "github.com/xenserver/go-xenserver-client"
"strings"
)

type StepConfigureDiscDrives struct{}

func (self *StepConfigureDiscDrives) Run(state multistep.StateBag) multistep.StepAction {
ui := state.Get("ui").(packer.Ui)
config := state.Get("commonconfig").(CommonConfig)
client := state.Get("client").(xsclient.XenAPIClient)
ui.Say("Step: Configure disc drives")

uuid := state.Get("instance_uuid").(string)
instance, err := client.GetVMByUuid(uuid)
if err != nil {
ui.Error(fmt.Sprintf("Unable to get VM from UUID '%s': %s", uuid, err.Error()))
return multistep.ActionHalt
}

vbds, err := instance.GetVBDs()
if err != nil {
ui.Error(fmt.Sprintf("Error getting VBDs: %s", err.Error()))
return multistep.ActionHalt
}

var current_number_of_disc_drives int = 0
for _, vbd := range vbds {
vbd_rec, err := vbd.GetRecord()
if err != nil {
ui.Error(fmt.Sprintf("Error getting VBD record: %s", err.Error()))
return multistep.ActionHalt
}
if vbd_rec["type"].(string) == "CD" {
if current_number_of_disc_drives < config.DiscDrives {
ui.Say("Ejecting disc drive")
err = vbd.Eject()
if err != nil && !strings.Contains(err.Error(), "VBD_IS_EMPTY") {
ui.Error(fmt.Sprintf("Error ejecting VBD: %s", err.Error()))
return multistep.ActionHalt
}
current_number_of_disc_drives++
} else {
ui.Say("Destroying excess disc drive")
_ = vbd.Eject()
_ = vbd.Unplug()
err = vbd.Destroy()
if err != nil {
ui.Error(fmt.Sprintf("Error destroying VBD: %s", err.Error()))
return multistep.ActionHalt
}
}
}
}

if current_number_of_disc_drives < config.DiscDrives {
vbd_rec := make(xmlrpc.Struct)
vbd_rec["VM"] = instance.Ref
vbd_rec["VDI"] = "OpaqueRef:NULL"
vbd_rec["userdevice"] = "autodetect"
vbd_rec["empty"] = true
vbd_rec["other_config"] = make(xmlrpc.Struct)
vbd_rec["qos_algorithm_type"] = ""
vbd_rec["qos_algorithm_params"] = make(xmlrpc.Struct)
vbd_rec["mode"] = "RO"
vbd_rec["bootable"] = true
vbd_rec["unpluggable"] = false
vbd_rec["type"] = "CD"
var failures int = 0
for current_number_of_disc_drives < config.DiscDrives {
ui.Say("Creating disc drive")

result := xsclient.APIResult{}
err := client.APICall(&result, "VBD.create", vbd_rec)

if err != nil {
failures++
if failures < 3 {
ui.Error("Error creating disc drive. Retrying...")
continue
} else {
ui.Error("Failed to create disc drive after 3 tries.")
return multistep.ActionHalt
}
}

vbd_ref := result.Value.(string)

result = xsclient.APIResult{}
err = client.APICall(&result, "VBD.get_uuid", vbd_ref)

if err != nil {
failures++
if failures < 3 {
ui.Error("Error verifying disc drive. Retrying...")
continue
} else {
ui.Error("Failed to create disc drive after 3 tries.")
return multistep.ActionHalt
}
}

current_number_of_disc_drives++
}
}

return multistep.ActionContinue
}

func (self *StepConfigureDiscDrives) Cleanup(state multistep.StateBag) {}
Loading