From ef2496b199bcf2855f600be674c1cc2f17b978b3 Mon Sep 17 00:00:00 2001 From: Ben Keith Date: Wed, 5 Feb 2014 08:35:46 -0500 Subject: [PATCH] Adding cpu_count, mac_address, and default mem_size - Completing documentation for mem_size - Ran `make format` to standardize formatting - I do a lot of compilation on my installation so being able to set multiple CPUs is a major speedup. - I was having some major issues with the IP address not staying consistent across the reboot and thus not being able to connect via ssh so I'm making the IP address statically assigned. - Setting the default mem_size to 1GB since before you would get errors if you didn't specify it manually. This could possibly go lower to 512MB. --- builder/libvirt/builder.go | 95 +++++++++++-------- builder/libvirt/libvirt.go | 6 +- builder/libvirt/step_create_disk.go | 2 +- builder/libvirt/step_create_network.go | 9 +- builder/libvirt/step_create_xml.go | 35 ++++--- builder/libvirt/step_run.go | 14 +-- .../docs/builders/libvirt.html.markdown | 11 +++ 7 files changed, 103 insertions(+), 69 deletions(-) diff --git a/builder/libvirt/builder.go b/builder/libvirt/builder.go index f1bc8645074..acae89f29d7 100644 --- a/builder/libvirt/builder.go +++ b/builder/libvirt/builder.go @@ -6,12 +6,12 @@ import ( "github.com/mitchellh/multistep" "github.com/mitchellh/packer/common" "github.com/mitchellh/packer/packer" + "io/ioutil" "log" "os" "path/filepath" "strings" "time" - "io/ioutil" ) const BuilderId = "qur.libvirt" @@ -24,30 +24,32 @@ type Builder struct { type config struct { common.PackerConfig `mapstructure:",squash"` - BootCommand []string `mapstructure:"boot_command"` - MemSize uint `mapstructure:"mem_size"` - DomainType string `mapstructure:"domain_type"` - DiskName string `mapstructure:"disk_name"` - DiskType string `mapstructure:"disk_type"` - DiskSize uint `mapstructure:"disk_size"` - FloppyFiles []string `mapstructure:"floppy_files"` - Headless bool `mapstructure:"headless"` - HTTPDir string `mapstructure:"http_directory"` - HTTPPortMin uint `mapstructure:"http_port_min"` - HTTPPortMax uint `mapstructure:"http_port_max"` - ISOChecksum string `mapstructure:"iso_checksum"` - ISOChecksumType string `mapstructure:"iso_checksum_type"` - ISOUrls []string `mapstructure:"iso_urls"` - OutputDir string `mapstructure:"output_directory"` - ShutdownCommand string `mapstructure:"shutdown_command"` - SSHHostPortMin uint `mapstructure:"ssh_host_port_min"` - SSHHostPortMax uint `mapstructure:"ssh_host_port_max"` - SSHKeyPath string `mapstructure:"ssh_key_path"` - SSHPassword string `mapstructure:"ssh_password"` - SSHPort uint `mapstructure:"ssh_port"` - SSHUser string `mapstructure:"ssh_username"` - VMName string `mapstructure:"vm_name"` - XMLTemplatePath string `mapstructure:"xml_template_path"` + BootCommand []string `mapstructure:"boot_command"` + CPUCount uint `mapstructure:"cpu_count"` + DomainType string `mapstructure:"domain_type"` + DiskName string `mapstructure:"disk_name"` + DiskType string `mapstructure:"disk_type"` + DiskSize uint `mapstructure:"disk_size"` + FloppyFiles []string `mapstructure:"floppy_files"` + Headless bool `mapstructure:"headless"` + HTTPDir string `mapstructure:"http_directory"` + HTTPPortMin uint `mapstructure:"http_port_min"` + HTTPPortMax uint `mapstructure:"http_port_max"` + ISOChecksum string `mapstructure:"iso_checksum"` + ISOChecksumType string `mapstructure:"iso_checksum_type"` + ISOUrls []string `mapstructure:"iso_urls"` + MACAddress string `mapstructure:"mac_address"` + MemSize uint `mapstructure:"mem_size"` + OutputDir string `mapstructure:"output_directory"` + ShutdownCommand string `mapstructure:"shutdown_command"` + SSHHostPortMin uint `mapstructure:"ssh_host_port_min"` + SSHHostPortMax uint `mapstructure:"ssh_host_port_max"` + SSHKeyPath string `mapstructure:"ssh_key_path"` + SSHPassword string `mapstructure:"ssh_password"` + SSHPort uint `mapstructure:"ssh_port"` + SSHUser string `mapstructure:"ssh_username"` + VMName string `mapstructure:"vm_name"` + XMLTemplatePath string `mapstructure:"xml_template_path"` RawBootWait string `mapstructure:"boot_wait"` RawSingleISOUrl string `mapstructure:"iso_url"` @@ -88,6 +90,18 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { b.config.DiskName = "disk" } + if b.config.MemSize == 0 { + b.config.MemSize = 1024 + } + + if b.config.CPUCount == 0 { + b.config.CPUCount = 1 + } + + if b.config.MACAddress == "" { + b.config.MACAddress = "00:12:34:56:78:90" + } + if b.config.DiskSize == 0 { b.config.DiskSize = 40000 } @@ -130,20 +144,20 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { // Errors templates := map[string]*string{ - "disk_name": &b.config.DiskName, - "http_directory": &b.config.HTTPDir, - "iso_checksum": &b.config.ISOChecksum, - "iso_checksum_type": &b.config.ISOChecksumType, - "iso_url": &b.config.RawSingleISOUrl, - "output_directory": &b.config.OutputDir, - "shutdown_command": &b.config.ShutdownCommand, - "ssh_password": &b.config.SSHPassword, - "ssh_username": &b.config.SSHUser, - "vm_name": &b.config.VMName, - "boot_wait": &b.config.RawBootWait, - "shutdown_timeout": &b.config.RawShutdownTimeout, - "ssh_wait_timeout": &b.config.RawSSHWaitTimeout, - "xml_template_path": &b.config.XMLTemplatePath, + "disk_name": &b.config.DiskName, + "http_directory": &b.config.HTTPDir, + "iso_checksum": &b.config.ISOChecksum, + "iso_checksum_type": &b.config.ISOChecksumType, + "iso_url": &b.config.RawSingleISOUrl, + "output_directory": &b.config.OutputDir, + "shutdown_command": &b.config.ShutdownCommand, + "ssh_password": &b.config.SSHPassword, + "ssh_username": &b.config.SSHUser, + "vm_name": &b.config.VMName, + "boot_wait": &b.config.RawBootWait, + "shutdown_timeout": &b.config.RawShutdownTimeout, + "ssh_wait_timeout": &b.config.RawSSHWaitTimeout, + "xml_template_path": &b.config.XMLTemplatePath, } for n, ptr := range templates { @@ -164,8 +178,7 @@ func (b *Builder) Prepare(raws ...interface{}) ([]string, error) { } } - validates := map[string]*string{ - } + validates := map[string]*string{} for n, ptr := range validates { if err := b.config.tpl.Validate(*ptr); err != nil { diff --git a/builder/libvirt/libvirt.go b/builder/libvirt/libvirt.go index efe24dad3df..45925a0a926 100644 --- a/builder/libvirt/libvirt.go +++ b/builder/libvirt/libvirt.go @@ -3,15 +3,15 @@ package libvirt import ( "bufio" "bytes" - "log" - "strings" "fmt" + "log" "os" "os/exec" + "strings" ) var ( - virshCmd = "" + virshCmd = "" qemuImgCmd = "" ) diff --git a/builder/libvirt/step_create_disk.go b/builder/libvirt/step_create_disk.go index 84a462ef3d1..e1966c54020 100644 --- a/builder/libvirt/step_create_disk.go +++ b/builder/libvirt/step_create_disk.go @@ -15,7 +15,7 @@ func (s *stepCreateDisk) Run(state multistep.StateBag) multistep.StepAction { config := state.Get("config").(*config) ui := state.Get("ui").(packer.Ui) - path := filepath.Join(config.OutputDir, config.DiskName + ".img") + path := filepath.Join(config.OutputDir, config.DiskName+".img") size := fmt.Sprintf("%dM", config.DiskSize) ui.Say("Creating hard drive...") diff --git a/builder/libvirt/step_create_network.go b/builder/libvirt/step_create_network.go index 6cec5d59241..54ca965b22c 100644 --- a/builder/libvirt/step_create_network.go +++ b/builder/libvirt/step_create_network.go @@ -1,10 +1,10 @@ package libvirt import ( + "fmt" "github.com/mitchellh/multistep" "github.com/mitchellh/packer/packer" "os" - "fmt" "path/filepath" ) @@ -19,10 +19,12 @@ func (stepCreateNetwork) Run(state multistep.StateBag) multistep.StepAction { ni := &netInfo{ VMName: config.VMName, + MACAddress: config.MACAddress, IP: "172.13.92.1", Netmask: "255.255.255.0", - RangeStart: "172.13.92.2", + RangeStart: "172.13.92.3", RangeEnd: "172.13.92.250", + HostIP: "172.13.92.2", } state.Put("host_ip", ni.IP) @@ -84,6 +86,8 @@ type netInfo struct { Netmask string RangeStart string RangeEnd string + MACAddress string + HostIP string } const netTemplate = ` @@ -93,6 +97,7 @@ const netTemplate = ` + diff --git a/builder/libvirt/step_create_xml.go b/builder/libvirt/step_create_xml.go index 5f4429661da..37796135336 100644 --- a/builder/libvirt/step_create_xml.go +++ b/builder/libvirt/step_create_xml.go @@ -14,9 +14,11 @@ type xmlTemplateData struct { Name string NetName string MemSize uint + CPUCount uint DiskType string DiskPath string ISOPath string + MACAddress string } // This step creates the XML file for the VM. @@ -51,9 +53,11 @@ func (stepCreateXML) Run(state multistep.StateBag) multistep.StepAction { Name: config.VMName, NetName: config.VMName, MemSize: config.MemSize, + CPUCount: config.CPUCount, DiskType: config.DiskType, DiskPath: diskPath, ISOPath: isoPath, + MACAddress: config.MACAddress, } xmlTemplate := DefaultXMLTemplate @@ -88,22 +92,22 @@ func (stepCreateXML) Run(state multistep.StateBag) multistep.StepAction { xmlData := ParseXML(xmlContents) /* - TODO: figure out how to add this stuff back in! - - if config.XMLData != nil { - log.Println("Setting custom XML data...") - for k, v := range config.XMLData { - log.Printf("Setting XML: '%s' = '%s'", k, v) - xmlData[k] = v + TODO: figure out how to add this stuff back in! + + if config.XMLData != nil { + log.Println("Setting custom XML data...") + for k, v := range config.XMLData { + log.Printf("Setting XML: '%s' = '%s'", k, v) + xmlData[k] = v + } } - } - if floppyPathRaw, ok := state.GetOk("floppy_path"); ok { - log.Println("Floppy path present, setting in XML") - xmlData["floppy0.present"] = "TRUE" - xmlData["floppy0.fileType"] = "file" - xmlData["floppy0.fileName"] = floppyPathRaw.(string) - } + if floppyPathRaw, ok := state.GetOk("floppy_path"); ok { + log.Println("Floppy path present, setting in XML") + xmlData["floppy0.present"] = "TRUE" + xmlData["floppy0.fileType"] = "file" + xmlData["floppy0.fileName"] = floppyPathRaw.(string) + } */ xmlPath := filepath.Join(config.OutputDir, config.VMName+".xml") @@ -129,7 +133,7 @@ const DefaultXMLTemplate = ` {{ .Name }} {{ .MemSize }} - 1 + {{ .CPUCount }} hvm @@ -163,6 +167,7 @@ const DefaultXMLTemplate = ` + diff --git a/builder/libvirt/step_run.go b/builder/libvirt/step_run.go index df392a05737..fe144778172 100644 --- a/builder/libvirt/step_run.go +++ b/builder/libvirt/step_run.go @@ -23,13 +23,13 @@ func (s *stepRun) Run(state multistep.StateBag) multistep.StepAction { ui.Say("Starting the virtual machine...") /* - guiArgument := "gui" - if config.Headless == true { - ui.Message("WARNING: The VM will be started in headless mode, as configured.\n" + - "In headless mode, errors during the boot sequence or OS setup\n" + - "won't be easily visible. Use at your own discretion.") - guiArgument = "headless" - } + guiArgument := "gui" + if config.Headless == true { + ui.Message("WARNING: The VM will be started in headless mode, as configured.\n" + + "In headless mode, errors during the boot sequence or OS setup\n" + + "won't be easily visible. Use at your own discretion.") + guiArgument = "headless" + } */ if _, _, err := virsh("create", xmlPath); err != nil { err := fmt.Errorf("Error starting VM: %s", err) diff --git a/website/source/docs/builders/libvirt.html.markdown b/website/source/docs/builders/libvirt.html.markdown index cf3f2ac611d..d956cdec9e0 100644 --- a/website/source/docs/builders/libvirt.html.markdown +++ b/website/source/docs/builders/libvirt.html.markdown @@ -88,6 +88,15 @@ Optional: * `disk_type` (string) - The type of libvirt virtual disk to create. The default is "qcow2", which is generally the best option when using KVM. +* `mem_size` - The amount of memory to allocate (in Megabytes). By default + this is set to 1,024 (1GB). + +* `cpu_count` - The number of virtual CPUs to allocate to the VM. By default + this is set to 1. + +* `mac_address` - The Ethernet MAC address to use for this machine. By default + this is `00:12:34:56:78:90`. + * `domain_type` (string) - The type of libvirt domain to create (e.g. "kvm", "xen", "lxc" etc). If not specified, it defaults to "kvm". @@ -297,6 +306,8 @@ these variables isn't required, however. a network to use whilst building the VM). * `MemSize` - The amount of memory to allocate (in Megabytes) (`mem_size` from above). +* `CPUCount` - The number of virtual CPUs to allocate to the VM. (`cpu_count` + from above). * `DiskType` - The type of disk to create (`disk_type` from above). * `DiskPath` - The path to the virtual disk image (including file extension). * `ISOPath` - The path to the ISO to use for the OS installation.