func (store *LibvirtMachinerep) Create(machine *models.VirtualMachine, image *models.Image, plan *models.Plan) error { storagePool, err := store.conn.LookupStoragePoolByName("default") if err != nil { return fmt.Errorf("failed to lookup storage pool: %s", err) } volumeXML := fmt.Sprintf(` <volume> <name>%s_disk.%s</name> <capacity unit="b">1</capacity> </volume> `, machine.Name, image.TypeString()) volume, err := storagePool.StorageVolCreateXML(volumeXML, 0) if err != nil { return fmt.Errorf("failed to create storage volume: %s", err) } volumePath, err := volume.GetPath() if err != nil { return fmt.Errorf("failed to get volume path: %s", err) } imageStream, err := image.Stream() if err != nil { return fmt.Errorf("failed to open image file: %s", err) } defer imageStream.Close() vmdriveStream, err := os.Create(volumePath) if err != nil { return fmt.Errorf("failed to open vm drive: %s", err) } defer vmdriveStream.Close() if _, err := io.Copy(vmdriveStream, imageStream); err != nil { return fmt.Errorf("failed to copy image content to vm drive: %s", err) } var machineXml bytes.Buffer vmtplContext := struct { Machine *models.VirtualMachine Image *models.Image Plan *models.Plan VolumePath string }{machine, image, plan, volumePath} if err := store.vmtpl.Execute(&machineXml, vmtplContext); err != nil { return err } log.WithField("xml", machineXml.String()).Debug("defining domain from xml") domain, err := store.conn.DomainDefineXML(machineXml.String()) if err != nil { return err } store.fillVm(machine, domain) return nil }