+ if node['port'] != 22:
+ self._vm_info['host_port'] = node['port']
+ self._vm_info['host_username'] = node['username']
+ self._vm_info['host_password'] = node['password']
+ # Input Options.
+ self._opt = dict()
+ self._opt['qemu_id'] = qemu_id
+ self._opt['mem'] = int(mem)
+ self._opt['smp'] = int(smp)
+ self._opt['img'] = img
+ self._opt['vnf'] = vnf
+ # Temporary files.
+ self._temp = dict()
+ self._temp['pidfile'] = '/var/run/qemu_{id}.pid'.format(id=qemu_id)
+ if '/var/lib/vm/' in img:
+ self._opt['vm_type'] = 'nestedvm'
+ self._temp['qmp'] = '/var/run/qmp_{id}.sock'.format(id=qemu_id)
+ self._temp['qga'] = '/var/run/qga_{id}.sock'.format(id=qemu_id)
+ elif '/opt/boot/vmlinuz' in img:
+ self._opt['vm_type'] = 'kernelvm'
+ self._temp['log'] = '/tmp/serial_{id}.log'.format(id=qemu_id)
+ self._temp['ini'] = '/etc/vm_init_{id}.conf'.format(id=qemu_id)
+ else:
+ raise RuntimeError('QEMU: Unknown VM image option!')
+ # Computed parameters for QEMU command line.
+ self._params = OptionString(prefix='-')
+ 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()
+ elif self._opt.get('vm_type', '') == 'kernelvm':
+ self.add_kernelvm_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_with_value('name', 'vnf{qemu},debug-threads=on'.format(
+ qemu=self._opt.get('qemu_id')))
+ self._params.add('no-user-config')
+ self._params.add_with_value('monitor', 'none')
+ self._params.add_with_value('display', 'none')
+ self._params.add_with_value('vga', 'none')
+ self._params.add('enable-kvm')
+ self._params.add_with_value('pidfile', self._temp.get('pidfile'))
+ self._params.add_with_value('cpu', 'host')
+ self._params.add_with_value(
+ 'machine', 'pc,accel=kvm,usb=off,mem-merge=off')
+ self._params.add_with_value(
+ 'smp', '{smp},sockets=1,cores={smp},threads=1'.format(
+ smp=self._opt.get('smp')))
+ self._params.add_with_value(
+ 'object', 'memory-backend-file,id=mem,size={mem}M,'
+ 'mem-path=/dev/hugepages,share=on'.format(mem=self._opt.get('mem')))
+ self._params.add_with_value(
+ 'm', '{mem}M'.format(mem=self._opt.get('mem')))
+ self._params.add_with_value('numa', 'node,memdev=mem')
+ self._params.add_with_value('balloon', 'none')
+
+ def add_nestedvm_params(self):
+ """Set NestedVM QEMU parameters."""
+ self._params.add_with_value(
+ 'net', 'nic,macaddr=52:54:00:00:{qemu:02x}:ff'.format(
+ qemu=self._opt.get('qemu_id')))
+ self._params.add_with_value(
+ '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_with_value(
+ 'drive', 'file={img},format=raw,cache=none,if=virtio{locking}'.
+ format(img=self._opt.get('img'), locking=locking))
+ self._params.add_with_value(
+ 'qmp', 'unix:{qmp},server,nowait'.format(qmp=self._temp.get('qmp')))
+ self._params.add_with_value(
+ 'chardev', 'socket,host=127.0.0.1,port={info[serial]},'
+ 'id=gnc0,server,nowait'.format(info=self._vm_info))
+ self._params.add_with_value('device', 'isa-serial,chardev=gnc0')
+ self._params.add_with_value(
+ 'chardev', 'socket,path={qga},server,nowait,id=qga0'.format(
+ qga=self._temp.get('qga')))
+ self._params.add_with_value('device', 'isa-serial,chardev=qga0')
+
+ def add_kernelvm_params(self):
+ """Set KernelVM QEMU parameters."""
+ self._params.add_with_value(
+ 'chardev', 'file,id=char0,path={log}'.format(
+ log=self._temp.get('log')))
+ self._params.add_with_value('device', 'isa-serial,chardev=char0')
+ self._params.add_with_value(
+ 'fsdev', 'local,id=root9p,path=/,security_model=none')
+ self._params.add_with_value(
+ 'device', 'virtio-9p-pci,fsdev=root9p,mount_tag=/dev/root')
+ self._params.add_with_value(
+ 'kernel', '$(readlink -m {img}* | tail -1)'.format(
+ img=self._opt.get('img')))
+ self._params.add_with_value(
+ 'append', '"ro rootfstype=9p rootflags=trans=virtio console=ttyS0'
+ ' tsc=reliable hugepages=256 init={init}"'.format(
+ init=self._temp.get('ini')))
+
+ def create_kernelvm_config_vpp(self, **kwargs):
+ """Create QEMU VPP config files.
+
+ :param kwargs: Key-value pairs to replace content of VPP configuration
+ file.
+ :type kwargs: dict