Ejemplo n.º 1
0
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
}