+ self._vhost_id = 0
+ self._vm_info = {
+ 'type': NodeType.VM,
+ 'port': 10021 + qemu_id,
+ 'serial': 4555 + qemu_id,
+ 'username': 'cisco',
+ 'password': 'cisco',
+ 'interfaces': {},
+ }
+ if node:
+ self.qemu_set_node(node)
+ # Input Options.
+ self._opt = QemuOptions()
+ self._opt.add('qemu_id', qemu_id)
+ self._opt.add('bin_path', bin_path)
+ self._opt.add('mem', int(mem))
+ self._opt.add('smp', int(smp))
+ self._opt.add('img', img)
+ self._opt.add('vnf', vnf)
+ # Temporary files.
+ self._temp = QemuOptions()
+ self._temp.add('pid', '/var/run/qemu_{id}.pid'.format(id=qemu_id))
+ # Computed parameters for QEMU command line.
+ if '/var/lib/vm/' in img:
+ self._opt.add('vm_type', 'nestedvm')
+ self._temp.add('qmp', '/var/run/qmp_{id}.sock'.format(id=qemu_id))
+ self._temp.add('qga', '/var/run/qga_{id}.sock'.format(id=qemu_id))
+ else:
+ raise RuntimeError('QEMU: Unknown VM image option!')
+ self._params = QemuOptions()
+ self.add_params()
+
+ def add_params(self):
+ """Set QEMU command line parameters."""
+ self.add_default_params()
+ if self._opt.get('vm_type') == 'nestedvm':
+ self.add_nestedvm_params()
+ else:
+ raise RuntimeError('QEMU: Unsupported VM type!')
+
+ def add_default_params(self):
+ """Set default QEMU command line parameters."""
+ self._params.add('daemonize', '')
+ self._params.add('nodefaults', '')
+ self._params.add('name', 'vnf{qemu},debug-threads=on'.
+ format(qemu=self._opt.get('qemu_id')))
+ self._params.add('no-user-config', '')
+ self._params.add('monitor', 'none')
+ self._params.add('display', 'none')
+ self._params.add('vga', 'none')
+ self._params.add('enable-kvm', '')
+ self._params.add('pidfile', '{pid}'.
+ format(pid=self._temp.get('pid')))
+ self._params.add('cpu', 'host')
+ self._params.add('machine', 'pc,accel=kvm,usb=off,mem-merge=off')
+ self._params.add('smp', '{smp},sockets=1,cores={smp},threads=1'.
+ format(smp=self._opt.get('smp')))
+ self._params.add('object',
+ 'memory-backend-file,id=mem,size={mem}M,'
+ 'mem-path=/mnt/huge,share=on'.
+ format(mem=self._opt.get('mem')))
+ self._params.add('m', '{mem}M'.
+ format(mem=self._opt.get('mem')))
+ self._params.add('numa', 'node,memdev=mem')
+ self._params.add('balloon', 'none')
+
+ def add_nestedvm_params(self):
+ """Set NestedVM QEMU parameters."""
+ self._params.add('net', 'nic,macaddr=52:54:00:00:{qemu:02x}:ff'.
+ format(qemu=self._opt.get('qemu_id')))
+ self._params.add('net', 'user,hostfwd=tcp::{info[port]}-:22'.
+ format(info=self._vm_info))
+ # TODO: Remove try except after fully migrated to Bionic or
+ # qemu_set_node is removed.
+ try:
+ locking = ',file.locking=off'\
+ if self.qemu_version(version='2.10') else ''
+ except AttributeError:
+ locking = ''
+ self._params.add('drive',
+ 'file={img},format=raw,cache=none,if=virtio{locking}'.
+ format(img=self._opt.get('img'), locking=locking))
+ self._params.add('qmp', 'unix:{qmp},server,nowait'.
+ format(qmp=self._temp.get('qmp')))
+ self._params.add('chardev', 'socket,host=127.0.0.1,port={info[serial]},'
+ 'id=gnc0,server,nowait'.format(info=self._vm_info))
+ self._params.add('device', 'isa-serial,chardev=gnc0')
+ self._params.add('chardev',
+ 'socket,path={qga},server,nowait,id=qga0'.
+ format(qga=self._temp.get('qga')))
+ self._params.add('device', 'isa-serial,chardev=qga0')
+
+ def qemu_set_node(self, node):
+ """Set node to run QEMU on.