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.