Commit f3987c30 authored by Łukasz Nowak's avatar Łukasz Nowak

kvm: Implement multiple disk-device-path

Use json to generate .slapos-disk-permission in a way, that devperm manager
will be able to consume it.
parent cd917cc3
......@@ -19,7 +19,7 @@ md5sum = e6d5c7bb627b4f1d3e7c99721b7c58fe
[template-kvm]
filename = instance-kvm.cfg.jinja2
md5sum = 23493c541efef97ac5fe435114910b8e
md5sum = 0c00ca332d364a2c620cd260d51d4649
[template-kvm-cluster]
filename = instance-kvm-cluster.cfg.jinja2.in
......@@ -55,7 +55,7 @@ md5sum = b7e87479a289f472b634a046b44b5257
[template-kvm-run]
filename = template/template-kvm-run.in
md5sum = cc1b748c82ca15022744558dab05995c
md5sum = d1748b18fc76544cc71be5c40ed9cbb9
[template-kvm-controller]
filename = template/kvm-controller-run.in
......
......@@ -1036,10 +1036,16 @@ keyboard-layout-language = fr
recipe = slapos.recipe.template:jinja2
template = inline:
{%- raw %}
[{"disk": "{{disk_device_path}}"}]
{%- set disk_list = [] %}
{%- for disk in disk_device_path.split() %}
{%- do disk_list.append({'disk': disk}) %}
{%- endfor -%}
{{ json_module.dumps(disk_list) }}
{% endraw -%}
rendered = ${buildout:directory}/.slapos-disk-permission
extensions = jinja2.ext.do
context =
import json_module json
raw disk_device_path {{disk_device_path}}
{% do part_list.append('wipe-disk-device-wrapper') -%}
......
......@@ -83,12 +83,23 @@ disk_aio = disk_aio if disk_aio in ["threads", "native"] else "threads"
# If a device (ie.: /dev/sdb) is provided, use it instead
# the disk_path with disk_format
disk_device_path = '{{ parameter_dict.get("disk-device-path", "") }}'
if disk_device_path.startswith("/dev/"):
disk_path = disk_device_path
disk_format = "raw"
disk_aio = "native"
disk_cache = "none"
disk_info_list = []
for disk_device_path in '{{ parameter_dict.get("disk-device-path", "") }}'.split():
if disk_device_path.startswith("/dev/"):
disk_info_list.append({
'path': disk_device_path,
'format': "raw",
'io': "native",
'cache': "none"
})
if len(disk_info_list) == 0:
disk_info_list.append({
'path': disk_path,
'format': disk_format,
'io': disk_aio,
'cache': disk_cache,
})
smp_count = {{ parameter_dict.get("smp-count") }}
smp_max_count = {{ parameter_dict.get("smp-max-count") }}
......@@ -167,12 +178,12 @@ def getMapStorageList(disk_storage_dict, external_disk_number):
return id_list, external_disk_number
# Download existing hard drive if needed at first boot
if not os.path.exists(disk_path) and virtual_hard_drive_url != '':
if len(disk_info_list) == 1 and not os.path.exists(disk_info_list[0]['path']) and virtual_hard_drive_url != '':
print('Downloading virtual hard drive...')
try:
downloaded_disk = disk_path
downloaded_disk = disk_info_list[0]['path']
if virtual_hard_drive_gzipped == 'true':
downloaded_disk = '%s.gz' % disk_path
downloaded_disk = '%s.gz' % disk_info_list[0]['path']
opener.retrieve(virtual_hard_drive_url, downloaded_disk)
except:
if os.path.exists(downloaded_disk):
......@@ -191,21 +202,21 @@ if not os.path.exists(disk_path) and virtual_hard_drive_url != '':
print('Warning: not checksum specified.')
if downloaded_disk.endswith('.gz'):
try:
with open(disk_path, 'w') as disk:
with open(disk_info_list[0]['path'], 'w') as disk:
with gzip.open(downloaded_disk, 'rb') as disk_gz:
shutil.copyfileobj(disk_gz, disk)
except Exception:
if os.path.exists(disk_path):
os.remove(disk_path)
if os.path.exists(disk_info_list[0]['path']):
os.remove(disk_info_list[0]['path'])
raise
os.remove(downloaded_disk)
# Create disk if doesn't exist
# XXX: move to Buildout profile
if not disk_device_path.startswith("/dev/") and not os.path.exists(disk_path):
if len(disk_info_list) == 1 and not disk_info_list[0]['path'].startswith("/dev/") and not os.path.exists(disk_info_list[0]['path']):
print('Creating virtual hard drive...')
subprocess.check_call([qemu_img_path, 'create' ,'-f', disk_format,
disk_path, '%sG' % disk_size])
subprocess.check_call([qemu_img_path, 'create' ,'-f', disk_info_list[0]['format'],
disk_info_list[0]['path'], '%sG' % disk_size])
print('Done.')
# Check and create external disk
......@@ -240,13 +251,6 @@ if disk_storage_dict:
print('Data folder %s was not used to create external disk %r' % (index +1))
index += 1
additional_disk_options = ''
if disk_aio == 'native':
additional_disk_options += ',cache.direct=on'
if disk_format == "raw":
additional_disk_options += ',discard=on'
# Generate network parameters
# XXX: use_tap should be a boolean
tap_network_parameter = []
......@@ -303,8 +307,6 @@ else:
kvm_argument_list = [qemu_path,
'-enable-kvm', '-smp', smp, '-name', vm_name, '-m', ram, '-vga', 'std',
'-drive', 'file=%s,if=%s,cache=%s,aio=%s%s' % (disk_path, disk_type, disk_cache,
disk_aio, additional_disk_options),
'-vnc', '%s:1,ipv4,password' % listen_ip,
'-boot', 'order=cd,menu=on',
'-qmp', 'unix:%s,server,nowait' % socket_path,
......@@ -312,6 +314,18 @@ kvm_argument_list = [qemu_path,
'-D', logfile,
'-nodefaults',
]
for disk_info in disk_info_list:
additional_disk_options = ''
if disk_info['io'] == 'native':
additional_disk_options += ',cache.direct=on'
if disk_info['format'] == "raw":
additional_disk_options += ',discard=on'
kvm_argument_list.extend([
'-drive',
'file=%s,if=%s,cache=%s,aio=%s%s' % ( disk_info['path'], disk_type, disk_info['cache'], disk_info['io'], additional_disk_options)
])
rgx = re.compile('^[\w*\,][\=\d+\-\,\w]*$')
for numa in numa_list:
......
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