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 }
func (repo *LocalfsImagerep) fillLocalfsImage(image *models.Image, fileinfo os.FileInfo) bool { // ubuntu-14.04_x86_64_raw.img -> name: ubuntu-14.04, arch: x86_64, type: raw.img imginfo := strings.SplitN(fileinfo.Name(), "_", 3) if len(imginfo) != 3 { log.WithField("image", fileinfo.Name()).Info("skipping image with invalid name") return false } image.Name = imginfo[0] image.Size = fileinfo.Size() image.Date = fileinfo.ModTime() image.Filename = fileinfo.Name() image.FullPath = filepath.Join(repo.Root, fileinfo.Name()) switch imginfo[1] { default: log.WithField("filename", fileinfo.Name()).WithField("parts", imginfo).Info("skipping unknown image architecture") return false case "amd64": image.Arch = models.IMAGE_ARCH_X86_64 case "i386": image.Arch = models.IMAGE_ARCH_X86 } switch imginfo[2] { default: log.WithField("filename", fileinfo.Name()).WithField("parts", imginfo).Info("skipping unknown image type") return false case "raw.img": image.Type = models.IMAGE_FMT_RAW case "qcow2.img": image.Type = models.IMAGE_FMT_QCOW2 } return true }