KVM SR: Remove brain overhead of having a dict created from another dict.

First move to a clean KVM wrapper. And must faster maintenance/feature adding.
parent 8ce5a9aa
......@@ -41,32 +41,7 @@ class Recipe(GenericBaseRecipe):
'"virtio" value.'
self.options['disk-type'] = 'virtio'
config = dict(
tap_interface=self.options['tap'],
vnc_ip=self.options['vnc-ip'],
vnc_port=self.options['vnc-port'],
nbd_ip=self.options['nbd-host'],
nbd_port=self.options['nbd-port'],
nbd2_ip=self.options.get('nbd2-host', ''),
nbd2_port=self.options.get('nbd2-port', 1024),
disk_path=self.options['disk-path'],
disk_size=self.options['disk-size'],
disk_type=self.options['disk-type'],
mac_address=self.options['mac-address'],
smp_count=self.options['smp-count'],
ram_size=self.options['ram-size'],
socket_path=self.options['socket-path'],
pid_file_path=self.options['pid-path'],
python_path=sys.executable,
shell_path=self.options['shell-path'],
qemu_path=self.options['qemu-path'],
qemu_img_path=self.options['qemu-img-path'],
vnc_passwd=self.options['passwd'],
default_disk_image=self.options['default-disk-image'],
virtual_hard_drive_url=self.options['virtual-hard-drive-url'],
use_tap=self.options['use-tap'],
nat_rules = self.options.get('nat-rules', ''),
)
self.options['python-path'] = sys.executable
path_list = []
......@@ -90,17 +65,16 @@ class Recipe(GenericBaseRecipe):
)
path_list.append(tunnel_path)
runner_path = self.createExecutable(
self.options['runner-path'],
self.substituteTemplate(self.getTemplateFilename('kvm_run.in'),
config))
self.options))
path_list.append(runner_path)
controller_path = self.createExecutable(
self.options['controller-path'],
self.substituteTemplate(self.getTemplateFilename('kvm_controller_run.in'),
config))
self.options))
return path_list
#!%(python_path)s
#!%(python-path)s
# BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically
......@@ -6,12 +6,15 @@
import socket
import time
socket_path = '%(socket-path)s'
vnc_password = '%(vnc-passwd)s'
# Connect to KVM qmp socket
so = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
connected = False
while not connected:
try:
so.connect('%(socket_path)s')
so.connect(socket_path)
except socket.error:
time.sleep(1)
else:
......@@ -25,7 +28,7 @@ data = so.recv(1024)
# Set VNC password
so.send('{ "execute": "change", ' \
'"arguments": { "device": "vnc", "target": "password", ' \
' "arg": "%(vnc_passwd)s" } }')
' "arg": "' + vnc_password + '" } }')
data = so.recv(1024)
# Finish
......
#!%(python_path)s
#!%(python-path)s
# BEWARE: This file is operated by slapgrid
# BEWARE: It will be overwritten automatically
......@@ -8,6 +8,26 @@ import socket
import subprocess
import urllib
# XXX: give all of this through parameter, don't use this as template, but as module
qemu_img_path = '%(qemu-img-path)s'
qemu_path = '%(qemu-path)s'
disk_size = '%(disk-size)s'
disk_type = '%(disk-type)s'
socket_path = '%(socket-path)s'
nbd_list = (('%(nbd-host)s', %(nbd-port)s), ('%(nbd2-host)s', %(nbd2-port)s))
default_disk_image = '%(default-disk-image)s'
disk_path = '%(disk-path)s'
virtual_hard_drive_url = '%(virtual-hard-drive-url)s'.strip()
virtual_hard_drive_md5_url = '%(virtual-hard-drive-md5-url)s'.strip()
nat_rules = '%(nat-rules)s'.strip()
use_tap = '%(use-tap)s'
tap_interface = '%(tap-interface)s'
listen_ip = '%(ipv4)s'
mac_address = '%(mac-address)s'
smp_count = '%(smp-count)s'
ram_size = '%(ram-size)s'
pid_file_path = '%(pid-file-path)s'
def md5Checksum(file_path):
with open(file_path, 'rb') as fh:
m = hashlib.md5()
......@@ -37,21 +57,6 @@ def getSocketStatus(host, port):
break
return s
# XXX: give all of this through parameter, don't use this as template
default_disk_image = '%(default_disk_image)s'
disk_path = '%(disk_path)s'
virtual_hard_drive_url = '%(virtual_hard_drive_url)s'.strip()
virtual_hard_drive_md5_url = '%(virtual_hard_drive_md5_url)s'.strip()
nat_rules = '%(nat_rules)s'.strip()
use_tap = '%(use_tap)s'
# Generate NAT rules, if any
# XXX: use_tap should be a boolean
if use_tap == 'True':
qemu_network_parameter = 'user,' + ','.join('hostfwd=tcp:%(vnc_ip)s:%%s-:%%s' %% (int(port) + 10000, port) for port in nat_rules.split())
else:
qemu_network_parameter = 'tap,ifname=%(tap_interface)s,script=no,downscript=no'
# Download existing hard drive if needed at first boot
if not os.path.exists(disk_path) and virtual_hard_drive_url != '':
urllib.urlretrieve(virtual_hard_drive_url, disk_path)
......@@ -64,24 +69,32 @@ if not os.path.exists(disk_path) and virtual_hard_drive_url != '':
# Create disk if doesn't exist
# XXX: move to Buildout profile
if not os.path.exists(disk_path):
subprocess.Popen(['%(qemu_img_path)s', 'create' ,'-f', 'qcow2',
disk_path, '%(disk_size)sG'])
subprocess.Popen([qemu_img_path, 'create' ,'-f', 'qcow2',
disk_path, '%%sG' %% disk_size])
kvm_argument_list = ['%(qemu_path)s',
'-enable-kvm', '-net', 'nic,macaddr=%(mac_address)s',
# Generate network parameters
# XXX: use_tap should be a boolean
if use_tap == 'True':
qemu_network_parameter = 'tap,ifname=%%s,script=no,downscript=no' %% tap_interface
else:
qemu_network_parameter = 'user,' + ','.join('hostfwd=tcp:%%s:%%s-:%%s' %% (listen_ip, int(port) + 10000, port) for port in nat_rules.split())
kvm_argument_list = [qemu_path,
'-enable-kvm', '-net', 'nic,macaddr=%%s' %% mac_address,
'-net', qemu_network_parameter,
'-smp', '%(smp_count)s',
'-m', '%(ram_size)s',
'-drive', 'file=%(disk_path)s,if=%(disk_type)s',
'-vnc', '%(vnc_ip)s:1,ipv4,password',
'-smp', smp_count,
'-m', ram_size,
'-drive', 'file=%%s,if=%%s' %% (disk_path, disk_type),
'-vnc', '%%s:1,ipv4,password' %% listen_ip,
'-boot', 'menu=on',
'-qmp', 'unix:%(socket_path)s,server',
'-pidfile', '%(pid_file_path)s',
'-qmp', 'unix:%%s,server' %% socket_path,
'-pidfile', pid_file_path,
]
# Try to connect to NBD server (and second nbd if defined)
for nbd_ip, nbd_port in (
('%(nbd_ip)s', %(nbd_port)s), ('%(nbd2_ip)s', %(nbd2_port)s)):
# Try to connect to NBD server (and second nbd if defined).
# If not available, don't even specify it in qemu command line parameters.
# Reason: if qemu starts with unavailable NBD drive, it will just crash.
for nbd_ip, nbd_port in nbd_list:
if nbd_ip and nbd_port:
s = getSocketStatus(nbd_ip, nbd_port)
if s is None:
......@@ -92,11 +105,10 @@ for nbd_ip, nbd_port in (
kvm_argument_list.extend([
'-drive',
'file=nbd:[%%s]:%%s,media=cdrom' %% (nbd_ip, nbd_port)])
# If no NBD is specified/available: use internal disk image
else:
kvm_argument_list.extend([
'-drive', 'file=%%s,media=cdrom' %% default_disk_image
])
os.execv('%(qemu_path)s', kvm_argument_list)
os.execv(qemu_path, kvm_argument_list)
......@@ -51,12 +51,11 @@ bytes = 8
# Specific code. It needs Jinja.
recipe = slapos.cookbook:kvm
# XXX-Cedric: should be removed and replaced
vnc-ip = $${slap-network-information:local-ipv4}
passwd = $${gen-passwd:passwd}
vnc-passwd = $${gen-passwd:passwd}
ipv4 = $${slap-network-information:local-ipv4}
ipv6 = $${slap-network-information:global-ipv6}
vnc-ip = $${:ipv4}
vnc-port = 5901
......@@ -67,14 +66,14 @@ nbd-port = $${slap-parameter:nbd-port}
nbd2-host = $${slap-parameter:nbd2-host}
nbd2-port = $${slap-parameter:nbd2-port}
tap = $${slap-network-information:network-interface}
tap-interface = $${slap-network-information:network-interface}
disk-path = $${directory:srv}/virtual.qcow2
disk-size = $${slap-parameter:disk-size}
disk-type = $${slap-parameter:disk-type}
socket-path = $${directory:var}/qmp_socket
pid-path = $${directory:run}/pid_file
pid-file-path = $${directory:run}/pid_file
smp-count = $${slap-parameter:cpu-count}
ram-size = $${slap-parameter:ram-size}
......@@ -89,6 +88,7 @@ nat-rules = $${slap-parameter:nat-rules}
6tunnel-wrapper-path = $${directory:services}/6tunnel
virtual-hard-drive-url = $${slap-parameter:virtual-hard-drive-url}
virtual-hard-drive-md5-url = $${slap-parameter:virtual-hard-drive-md5-url}
shell-path = ${dash:location}/bin/dash
qemu-path = ${kvm:location}/bin/qemu-system-x86_64
......@@ -212,8 +212,8 @@ sla-instance_guid = $${slap-parameter:frontend-instance-guid}
[publish-connection-information]
recipe = slapos.cookbook:publish
backend-url = https://[$${novnc-instance:ip}]:$${novnc-instance:port}/vnc_auto.html?host=[$${novnc-instance:ip}]&port=$${novnc-instance:port}&encrypt=1&password=$${kvm-instance:passwd}
url = $${request-slave-frontend:connection-url}/vnc_auto.html?host=$${request-slave-frontend:connection-domainname}&port=$${request-slave-frontend:connection-port}&encrypt=1&path=$${request-slave-frontend:connection-resource}&password=$${kvm-instance:passwd}
backend-url = https://[$${novnc-instance:ip}]:$${novnc-instance:port}/vnc_auto.html?host=[$${novnc-instance:ip}]&port=$${novnc-instance:port}&encrypt=1&password=$${kvm-instance:vnc-passwd}
url = $${request-slave-frontend:connection-url}/vnc_auto.html?host=$${request-slave-frontend:connection-domainname}&port=$${request-slave-frontend:connection-port}&encrypt=1&path=$${request-slave-frontend:connection-resource}&password=$${kvm-instance:vnc-passwd}
[frontend-promise]
......@@ -243,4 +243,4 @@ nat-rules = 22 80 443
use-tap = False
virtual-hard-drive-url =
virtual-hard-drive-md5-url =
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment