+ 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['bin_path'] = bin_path
+ 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 = 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()
+ 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('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', '{pidfile}'.
+ format(pidfile=self._temp.get('pidfile')))
+ 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=/dev/hugepages,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 add_kernelvm_params(self):
+ """Set KernelVM QEMU parameters."""
+ self._params.add('chardev', 'file,id=char0,path={log}'.
+ format(log=self._temp.get('log')))
+ self._params.add('device', 'isa-serial,chardev=char0')
+ self._params.add('fsdev', 'local,id=root9p,path=/,security_model=none')
+ self._params.add('device',
+ 'virtio-9p-pci,fsdev=root9p,mount_tag=/dev/root')
+ self._params.add('kernel', '$(readlink -m {img}* | tail -1)'.
+ format(img=self._opt.get('img')))
+ self._params.add('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