Search code examples
pythonubuntukvmlibvirt

KVM made with Libvirt not persisting after host restart


I currently am making a ubuntu KVM with libvirt using the following code

import libvirt

conn = libvirt.open('qemu:///system')
pool_name = 'VMPOOL'
name = 'ubuntu0'

pools = conn.listAllStoragePools(0)

for pool in pools:
    # check if pool is active
    print(pool.isActive())
    if pool.isActive() == 0:
        #activate pool
        pool.create()

    stgvols = pool.listVolumes()
    print('Storage pool: '+pool.name())
    for stgvol in stgvols :
        print('  Storage vol: '+stgvol)


def createStoragePool(conn, pool_name):
    xmlDesc = """
    <pool type='dir'>
      <name>""" + pool_name + """</name>
      <capacity unit="G">10</capacity>
      <allocation unit='bytes'>237457858</allocation>
      <available unit='bytes'>4069322956</available>
      <source>
      </source>
      <target>
        <path>/var/lib/libvirt/pool</path>
        <format type='qcow2'/>
        <permissions>
          <mode>0755</mode>
          <owner>-1</owner>
          <group>-1</group>
        </permissions>
      </target>
    </pool>"""
    pool = conn.storagePoolDefineXML(xmlDesc, 0)

    # set storage pool autostart
    pool.setAutostart(1)
    print(pool.name(), 'pool name in create')
    return pool


for pool in pools:
    # check if pool is active
    print(pool.isActive())
    if pool.isActive() == 0:
        #activate pool
        pool.create()

    stgvols = pool.listVolumes()
    print('Storage pool: '+pool.name())
    for stgvol in stgvols :
        print('  Storage vol: '+stgvol)

def createStoragePoolVolume(pool, name):
    stpVolXml = """
    <volume>
      <name>""" + name + """.img</name>
      <allocation>0</allocation>
      <capacity unit="G">10</capacity>
      <target>
        <path>/var/lib/libvirt/pool/""" + name + """.img</path>
        <permissions>
          <owner>107</owner>
          <group>107</group>
          <mode>0744</mode>
          <label>virt_image_t</label>
        </permissions>
      </target>
    </volume>"""
    stpVol = pool.createXML(stpVolXml, 0)
    return stpVol


def deleteVolStoragePool(conn, name):
    volume = conn.storageVolLookupByPath('/var/lib/libvirt/pool/%s.img' % name)
    volume.wipe()
    volume.delete()
    return True

##make kvm via xml
def makeKvm(name, conn):
    xmldesc = """
    <domain type="kvm">
    <name>""" + name + """</name>
    <memory unit='GB'>1</memory>
    <vcpu>1</vcpu>
    <os>
        <type arch='x86_64' machine='pc'>hvm</type>
        <boot dev='cdrom'/>
    </os>
    <iothreads>1</iothreads>
    <on_poweroff>destroy</on_poweroff>
    <on_reboot>restart</on_reboot>
    <on_crash>preserve</on_crash>
    <devices>
        <emulator>/usr/bin/qemu-system-x86_64</emulator>
        <disk type='file' device='disk'>
          <driver name='qemu' type='raw'/>
          <source file='/var/lib/libvirt/pool/""" + name + """.img'/>
          <target dev='vda' bus='virtio'/>
        </disk>
        <disk type='file' device='cdrom'>
          <driver name='qemu' type='raw'/>
          <source file='/var/lib/libvirt/iso/ubuntu-16.04.3-desktop-amd64.iso'/>
          <target dev='hdb' bus='ide'/>
        <readonly/>
        </disk>
        <interface type='bridge'>
          <source bridge='br0'/>
          <model type='virtio'/>
        </interface>
        <input type='mouse' bus='ps2'/>
        <graphics type='vnc' port='-1' autoport='yes' listen='0.0.0.0' keymap='en-us'/>
      </devices>
    </domain>
    """
    dom = conn.createLinux(xmldesc, 0)
    return dom


try:
    pool = conn.storagePoolLookupByName(pool_name)
except:
    pool = createStoragePool(conn, pool_name)

createStoragePoolVolume(pool, name)
makeKvm(name, conn)

The problem I'm having is after I reboot the host machine (my laptop) the vm disapears.

The .img file is still in /var/lib/libvirt/pool/ but the vm doesn't show when I do a virsh list -all

Is there something missing on the config xml? I'm referencing this question in regards of the need to make the storage pool first, then the volume


Solution

  • Let's start with... createLinux() is deprecated; you should be using createXML() instead. It takes identical arguments.

    But, createXML() only creates and starts transient VMs. To make a persistent VM, you need to call defineXML() instead. This creates a persistent VM, but does not start it. You can start it yourself when ready with create().