[PATCH V1] [Kimchi] Issue #992 : Create template on s390x without libvirt storage.
by archus@linux.vnet.ibm.com
From: Harshal Patil <harshalp(a)linux.vnet.ibm.com>
V1:
This patch adds support for creating templates on s390x arch
without using libvirt related storage calls
V2:
Review comments
V3:
Review comments and refactoring
V4:
Rebase patch to latest upstream.
Signed-off-by: Harshal Patil <harshalp(a)linux.vnet.ibm.com>
---
docs/API.md | 2 +
i18n.py | 3 ++
model/storagepools.py | 13 ++++--
model/storagevolumes.py | 1 -
model/templates.py | 27 +++++++++---
model/vms.py | 9 +++-
osinfo.py | 35 +++++++++++++--
utils.py | 34 +++++++++++++++
vmtemplate.py | 111 +++++++++++++++++++++++++++++++-----------------
9 files changed, 179 insertions(+), 56 deletions(-)
diff --git a/docs/API.md b/docs/API.md
index 1c20466..cff623e 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -438,6 +438,7 @@ A interface represents available network interface on VM.
over current will be used exclusively for memory hotplug
* cdrom: A volume name or URI to an ISO image
* storagepool: URI of the storagepool where template allocates vm storage.
+ * path *(optional and only valid for s390x architecture)*: Storage path to store virtual disks without libvirt.
* networks *(optional)*: list of networks will be assigned to the new VM.
* interfaces *(optional)*: list of host network interfaces will be assigned to the new VM. Only applicable for s390x or s390 architecture.
* type: Type of host network interface. Type should be 'macvtap' for host network interface (Ethernet, Bond, VLAN) to be connected as direct MacVTap; or 'ovs' for openvswitch host network interface to be connected as virtual switch to a VM.
@@ -504,6 +505,7 @@ A interface represents available network interface on VM.
* format: Format of the image. Valid formats: qcow, qcow2, qed, raw, vmdk, vpc.
* pool: Storage pool information
* name: URI of the storagepool where template allocates vm disk.
+ * path *(optional and only valid for s390x architecture)*: Either pool or path to store the virtual disks should be specified.
* graphics *(optional)*: A dict of graphics paramenters of this template
* type: The type of graphics. It can be VNC or spice or None.
* vnc: Graphical display using the Virtual Network
diff --git a/i18n.py b/i18n.py
index 47c829e..b6533d4 100644
--- a/i18n.py
+++ b/i18n.py
@@ -203,6 +203,9 @@ messages = {
"KCHTMPL0037E": _("Interfaces should be list of interfaces. Each interface should have name, type and mode(optional, only applicable for interfcae type 'macvtap'."),
"KCHTMPL0038E": _("Interface expects an object with parameters: 'name', 'type' and 'mode'. Name should be name of host network interface (Ethernet, Bond, VLAN) for type 'macvtap' or the name of host openvswitch bridge interface for type 'ovs'. Mode (optional) is only applicable for interface type 'macvtap' to indicates whether packets will be delivered directly to target device (bridge) or to the external bridge (vepa-capable bridge)."),
"KCHTMPL0039E": _("Interfaces parameter only supported on s390x or s390 architecture."),
+ "KCHTMPL0040E": _("Storage without libvirt pool is not supported on this architecture"),
+ "KCHTMPL0041E": _("Error while creating the virtual disk for the guest. Details: %(err)s"),
+ "KCHTMPL0042E": _("When setting template disks without libvirt, following parameters are required: 'index', 'format', 'path', 'size'"),
"KCHPOOL0001E": _("Storage pool %(name)s already exists"),
"KCHPOOL0002E": _("Storage pool %(name)s does not exist"),
diff --git a/model/storagepools.py b/model/storagepools.py
index af92ec9..5942b31 100644
--- a/model/storagepools.py
+++ b/model/storagepools.py
@@ -33,7 +33,7 @@ from wok.plugins.kimchi.model.host import DeviceModel
from wok.plugins.kimchi.model.libvirtstoragepool import StoragePoolDef
from wok.plugins.kimchi.osinfo import defaults as tmpl_defaults
from wok.plugins.kimchi.scan import Scanner
-from wok.plugins.kimchi.utils import pool_name_from_uri
+from wok.plugins.kimchi.utils import pool_name_from_uri, is_s390x
ISO_POOL_NAME = u'kimchi_isos'
@@ -57,6 +57,7 @@ STORAGE_SOURCES = {'netfs': {'addr': '/pool/source/host/@name',
class StoragePoolsModel(object):
+
def __init__(self, **kargs):
self.conn = kargs['conn']
self.objstore = kargs['objstore']
@@ -72,6 +73,9 @@ class StoragePoolsModel(object):
def _check_default_pools(self):
pools = {}
+ if is_s390x():
+ return
+
default_pool = tmpl_defaults['disks'][0]['pool']['name']
default_pool = default_pool.split('/')[-1]
@@ -437,9 +441,10 @@ class StoragePoolModel(object):
for tmpl in templates:
t_info = session.get('template', tmpl)
for disk in t_info['disks']:
- t_pool = disk['pool']['name']
- if pool_name_from_uri(t_pool) == pool_name:
- return True
+ if 'pool' in disk:
+ t_pool = disk['pool']['name']
+ if pool_name_from_uri(t_pool) == pool_name:
+ return True
return False
def deactivate(self, name):
diff --git a/model/storagevolumes.py b/model/storagevolumes.py
index a6ce97b..2d68027 100644
--- a/model/storagevolumes.py
+++ b/model/storagevolumes.py
@@ -43,7 +43,6 @@ from wok.plugins.kimchi.model.diskutils import get_disk_used_by
from wok.plugins.kimchi.model.storagepools import StoragePoolModel
from wok.plugins.kimchi.utils import get_next_clone_name
-
VOLUME_TYPE_MAP = {0: 'file',
1: 'block',
2: 'directory',
diff --git a/model/templates.py b/model/templates.py
index 04e6626..a5d17af 100644
--- a/model/templates.py
+++ b/model/templates.py
@@ -28,13 +28,15 @@ import urlparse
from wok.exception import InvalidOperation, InvalidParameter
from wok.exception import NotFoundError, OperationFailed
-from wok.utils import probe_file_permission_as_user, run_setfacl_set_attr
+from wok.utils import probe_file_permission_as_user
+from wok.utils import run_setfacl_set_attr
from wok.xmlutils.utils import xpath_get_text
from wok.plugins.kimchi.config import get_kimchi_version
from wok.plugins.kimchi.kvmusertests import UserTests
from wok.plugins.kimchi.model.cpuinfo import CPUInfoModel
from wok.plugins.kimchi.utils import is_libvirtd_up, pool_name_from_uri
+from wok.plugins.kimchi.utils import create_disk_image
from wok.plugins.kimchi.vmtemplate import VMTemplate
ISO_TYPE = "ISO 9660 CD-ROM"
@@ -417,15 +419,26 @@ class LibvirtVMTemplate(VMTemplate):
def fork_vm_storage(self, vm_uuid):
# Provision storages:
- vol_list = self.to_volume_list(vm_uuid)
+ disk_and_vol_list = self.to_volume_list(vm_uuid)
try:
- for v in vol_list:
- pool = self._get_storage_pool(v['pool'])
- # outgoing text to libvirt, encode('utf-8')
- pool.createXML(v['xml'].encode('utf-8'), 0)
+ for v in disk_and_vol_list:
+ if v['pool'] is not None:
+ pool = self._get_storage_pool(v['pool'])
+ # outgoing text to libvirt, encode('utf-8')
+ pool.createXML(v['xml'].encode('utf-8'), 0)
+ else:
+ capacity = v['capacity']
+ format_type = v['format']
+ path = v['path']
+ create_disk_image(
+ format_type=format_type,
+ path=path,
+ capacity=capacity)
+
except libvirt.libvirtError as e:
raise OperationFailed("KCHVMSTOR0008E", {'error': e.message})
- return vol_list
+
+ return disk_and_vol_list
def set_cpu_info(self):
# undefined topology: consider these values to calculate maxvcpus
diff --git a/model/vms.py b/model/vms.py
index b889166..6a9b1d1 100644
--- a/model/vms.py
+++ b/model/vms.py
@@ -61,7 +61,7 @@ from wok.plugins.kimchi.model.utils import remove_metadata_node
from wok.plugins.kimchi.model.utils import set_metadata_node
from wok.plugins.kimchi.osinfo import defaults, MEM_DEV_SLOTS
from wok.plugins.kimchi.screenshot import VMScreenshot
-from wok.plugins.kimchi.utils import get_next_clone_name
+from wok.plugins.kimchi.utils import get_next_clone_name, is_s390x
from wok.plugins.kimchi.utils import template_name_from_uri
from wok.plugins.kimchi.xmlutils.bootorder import get_bootorder_node
from wok.plugins.kimchi.xmlutils.bootorder import get_bootmenu_node
@@ -1405,6 +1405,13 @@ class VMModel(object):
except libvirt.libvirtError as e:
wok_log.error('Unable to get storage volume by path: %s' %
e.message)
+ try:
+ if is_s390x() and os.path.exists(path):
+ os.remove(path)
+ except Exception as e:
+ wok_log.error('Unable to delete storage path: %s' %
+ e.message)
+
except Exception as e:
raise OperationFailed('KCHVOL0017E', {'err': e.message})
diff --git a/osinfo.py b/osinfo.py
index 3e56d97..8ec9480 100644
--- a/osinfo.py
+++ b/osinfo.py
@@ -159,6 +159,12 @@ def _get_tmpl_defaults():
'maxmemory': _get_default_template_mem()}
tmpl_defaults['storage']['disk.0'] = {'size': 10, 'format': 'qcow2',
'pool': 'default'}
+ is_on_s390x = True if _get_arch() == 's390x' else False
+
+ if is_on_s390x:
+ tmpl_defaults['storage']['disk.0']['path'] = '/var/lib/libvirt/images/'
+ del tmpl_defaults['storage']['disk.0']['pool']
+
tmpl_defaults['processor']['vcpus'] = 1
tmpl_defaults['processor']['maxvcpus'] = 1
tmpl_defaults['graphics'] = {'type': 'vnc', 'listen': '127.0.0.1'}
@@ -166,7 +172,12 @@ def _get_tmpl_defaults():
default_config = ConfigObj(tmpl_defaults)
# Load template configuration file
- config_file = os.path.join(kimchiPaths.sysconf_dir, 'template.conf')
+ if is_on_s390x:
+ config_file = os.path.join(
+ kimchiPaths.sysconf_dir,
+ 'template_s390x.conf')
+ else:
+ config_file = os.path.join(kimchiPaths.sysconf_dir, 'template.conf')
config = ConfigObj(config_file)
# Merge default configuration with file configuration
@@ -187,11 +198,27 @@ def _get_tmpl_defaults():
# Parse storage section to get disks values
storage_section = default_config.pop('storage')
defaults['disks'] = []
- for disk in storage_section.keys():
+
+ for index, disk in enumerate(storage_section.keys()):
data = storage_section[disk]
data['index'] = int(disk.split('.')[1])
- data['pool'] = {"name": '/plugins/kimchi/storagepools/' +
- storage_section[disk].pop('pool')}
+ # Right now 'Path' is only supported on s390x
+ if storage_section[disk].get('path') and is_on_s390x:
+ data['path'] = storage_section[disk].pop('path')
+ if 'size' not in storage_section[disk]:
+ data['size'] = tmpl_defaults['storage']['disk.0']['size']
+ else:
+ data['size'] = storage_section[disk].pop('size')
+
+ if 'format' not in storage_section[disk]:
+ data['format'] = tmpl_defaults['storage']['disk.0']['format']
+ else:
+ data['format'] = storage_section[disk].pop('format')
+ else:
+ storage_section[disk].get('pool')
+ data['pool'] = {"name": '/plugins/kimchi/storagepools/' +
+ storage_section[disk].pop('pool')}
+
defaults['disks'].append(data)
# Parse processor section to get vcpus and cpu_topology values
diff --git a/utils.py b/utils.py
index 26d3cf6..7129bfe 100644
--- a/utils.py
+++ b/utils.py
@@ -24,6 +24,7 @@ import platform
import re
import sqlite3
import time
+import os
import urllib2
from httplib import HTTPConnection, HTTPException
from urlparse import urlparse
@@ -31,6 +32,7 @@ from urlparse import urlparse
from wok.exception import InvalidParameter, OperationFailed
from wok.plugins.kimchi import config
from wok.plugins.kimchi.osinfo import get_template_default
+from wok.stringutils import encode_value
from wok.utils import run_command, wok_log
from wok.xmlutils.utils import xpath_get_text
@@ -272,3 +274,35 @@ def is_libvirtd_up():
output, error, rc = run_command(cmd, silent=True)
return True if output == 'active\n' else False
+
+
+def is_s390x():
+ """
+ Check if current arch is 's390x'
+ Returns:
+ """
+ if os.uname()[4] == 's390x':
+ return True
+
+ return False
+
+
+def create_disk_image(format_type, path, capacity):
+ """
+ Create a disk image for the Guest
+ Args:
+ format: Format of the storage. e.g. qcow2
+ path: Path where the virtual disk will be created
+ capacity: Capacity of the virtual disk in GBs
+
+ Returns:
+
+ """
+ out, err, rc = run_command(
+ ["/usr/bin/qemu-img", "create", "-f", format_type, "-o",
+ "preallocation=metadata", path, encode_value(capacity) + "G"])
+
+ if rc != 0:
+ raise OperationFailed("KCHTMPL0041E", {'err': err})
+
+ return
diff --git a/vmtemplate.py b/vmtemplate.py
index 07cebb9..20edbfb 100644
--- a/vmtemplate.py
+++ b/vmtemplate.py
@@ -31,7 +31,8 @@ from wok.exception import MissingParameter, OperationFailed
from wok.plugins.kimchi import imageinfo
from wok.plugins.kimchi import osinfo
from wok.plugins.kimchi.isoinfo import IsoImage
-from wok.plugins.kimchi.utils import check_url_path, pool_name_from_uri
+from wok.plugins.kimchi.utils import check_url_path, is_s390x
+from wok.plugins.kimchi.utils import pool_name_from_uri
from wok.plugins.kimchi.xmlutils.bootorder import get_bootorder_xml
from wok.plugins.kimchi.xmlutils.cpu import get_cpu_xml
from wok.plugins.kimchi.xmlutils.disk import get_disk_xml
@@ -42,6 +43,7 @@ from wok.plugins.kimchi.xmlutils.serial import get_serial_xml
class VMTemplate(object):
+
def __init__(self, args, scan=False, netboot=False):
"""
Construct a VM Template from a widely variable amount of information.
@@ -95,35 +97,55 @@ class VMTemplate(object):
disks = self.info.get('disks')
basic_disk = ['index', 'format', 'pool', 'size']
+ basic_path_disk = ['index', 'format', 'path', 'size']
ro_disk = ['index', 'format', 'pool', 'volume']
base_disk = ['index', 'base', 'pool', 'size', 'format']
for index, disk in enumerate(disks):
disk_info = dict(default_disk)
-
- pool = disk.get('pool', default_disk['pool'])
- pool_type = self._get_storage_type(pool['name'])
-
- if pool_type in ['iscsi', 'scsi']:
- disk_info = {'index': 0, 'format': 'raw', 'volume': None}
-
- disk_info.update(disk)
- pool_name = disk_info.get('pool', {}).get('name')
- if pool_name is None:
- raise MissingParameter('KCHTMPL0028E')
-
- keys = sorted(disk_info.keys())
- if ((keys != sorted(basic_disk)) and (keys != sorted(ro_disk)) and
- (keys != sorted(base_disk))):
- raise MissingParameter('KCHTMPL0028E')
-
- if pool_type in ['logical', 'iscsi', 'scsi']:
- if disk_info['format'] != 'raw':
- raise InvalidParameter('KCHTMPL0029E')
-
- disk_info['pool']['type'] = pool_type
- disk_info['index'] = disk_info.get('index', index)
- self.info['disks'][index] = disk_info
+ if disk.get('pool'):
+ pool = disk.get('pool', default_disk.get('pool'))
+ pool_type = self._get_storage_type(pool['name'])
+ if pool_type in ['iscsi', 'scsi']:
+ disk_info = {'index': 0, 'format': 'raw', 'volume': None}
+
+ # This check is required where 'path' disk
+ # exists and is replaced by 'pool' disk during
+ # template update
+ if 'path' in disk_info:
+ del disk_info['path']
+
+ disk_info.update(disk)
+ pool_name = disk_info.get('pool', {}).get('name')
+ if pool_name is None:
+ raise MissingParameter('KCHTMPL0028E')
+
+ keys = sorted(disk_info.keys())
+ if ((keys != sorted(basic_disk)) and
+ (keys != sorted(ro_disk)) and
+ (keys != sorted(base_disk)) and
+ (keys != sorted(basic_path_disk))):
+ raise MissingParameter('KCHTMPL0028E')
+
+ if pool_type in ['logical', 'iscsi', 'scsi']:
+ if disk_info['format'] != 'raw':
+ raise InvalidParameter('KCHTMPL0029E')
+
+ disk_info['pool']['type'] = pool_type
+ disk_info['index'] = disk_info.get('index', index)
+ self.info['disks'][index] = disk_info
+ elif is_s390x():
+ # For now support 'path' only on s390x
+ path = disk.get('path', default_disk['path'])
+ disk_info.update(disk)
+ keys = sorted(disk_info.keys())
+ if keys != sorted(basic_path_disk):
+ raise MissingParameter('KCHTMPL0042E')
+ disk_info['path'] = path
+ disk_info['index'] = disk_info.get('index', index)
+ self.info['disks'][index] = disk_info
+ else:
+ raise InvalidParameter('KCHTMPL0040E')
def _get_os_info(self, args, scan):
distro = version = 'unknown'
@@ -217,8 +239,9 @@ class VMTemplate(object):
params = dict(base_disk_params)
params['format'] = disk['format']
params['index'] = index
- params.update(locals().get('%s_disk_params' %
- disk['pool']['type'], {}))
+ if disk.get('pool'):
+ params.update(locals().get('%s_disk_params' %
+ disk['pool']['type'], {}))
volume = disk.get('volume')
if volume is not None:
@@ -226,9 +249,13 @@ class VMTemplate(object):
volume)
else:
img = "%s-%s.img" % (vm_uuid, params['index'])
- storage_path = self._get_storage_path(disk['pool']['name'])
+ if disk.get('pool'):
+ storage_path = self._get_storage_path(disk['pool']['name'])
+ params['pool_type'] = disk['pool']['type']
+ elif disk.get('path'):
+ storage_path = disk.get('path')
+ params['pool_type'] = None
params['path'] = os.path.join(storage_path, img)
- params['pool_type'] = disk['pool']['type']
disks_xml += get_disk_xml(params)[1]
return unicode(disks_xml, 'utf-8')
@@ -237,20 +264,24 @@ class VMTemplate(object):
ret = []
for i, d in enumerate(self.info['disks']):
# Create only .img. If storagepool is (i)SCSI, volumes will be LUNs
- if d['pool']['type'] in ["iscsi", "scsi"]:
+ if 'pool' in d and d['pool']['type'] in ["iscsi", "scsi"]:
continue
index = d.get('index', i)
volume = "%s-%s.img" % (vm_uuid, index)
- storage_path = self._get_storage_path(d['pool']['name'])
+ if 'path' in d:
+ storage_path = d['path']
+ else:
+ storage_path = self._get_storage_path(d['pool']['name'])
+
info = {'name': volume,
'capacity': d['size'],
'format': d['format'],
'path': '%s/%s' % (storage_path, volume),
- 'pool': d['pool']['name']}
+ 'pool': d['pool']['name'] if 'pool' in d else None}
- if 'logical' == d['pool']['type'] or \
+ if ('pool' in d and 'logical' == d['pool']['type']) or \
info['format'] not in ['qcow2', 'raw']:
info['allocation'] = info['capacity']
else:
@@ -467,8 +498,9 @@ class VMTemplate(object):
def validate(self):
for disk in self.info.get('disks'):
- pool_uri = disk.get('pool', {}).get('name')
- self._get_storage_pool(pool_uri)
+ if 'pool' in disk:
+ pool_uri = disk.get('pool', {}).get('name')
+ self._get_storage_pool(pool_uri)
self._network_validate()
self._iso_validate()
self.cpuinfo_validate()
@@ -519,10 +551,11 @@ class VMTemplate(object):
# validate storagepools and image-based templates integrity
for disk in self.info['disks']:
- pool_uri = disk['pool']['name']
- pool_name = pool_name_from_uri(pool_uri)
- if pool_name not in self._get_active_storagepools_name():
- invalid['storagepools'] = [pool_name]
+ if 'pool' in disk:
+ pool_uri = disk['pool']['name']
+ pool_name = pool_name_from_uri(pool_uri)
+ if pool_name not in self._get_active_storagepools_name():
+ invalid['storagepools'] = [pool_name]
if disk.get("base") is None:
continue
--
2.7.4
8 years, 3 months
Sept 07th scrum meeting CANCELED
by Aline Manera
Hi all,
Sept 07th is holiday in Brazil (Independence Day) so there will be no
scrum meeting this week.
Regards,
Aline Manera
8 years, 3 months
[PATCH v5] [Kimchi] Feature request (#860): Support Guest Autostart
by bianca@linux.vnet.ibm.com
From: Bianca Carvalho <bianca(a)linux.vnet.ibm.com>
Include 'autostart' option in API.json and vms.py (lookup and update)
using libvirt dom.setAutostart to set as true or false. Also edit
test_model.py to include those changes and updated API.md file.
Also included API tests to test_rest.py in test_edit_vm function.
Signed-off-by: Bianca Carvalho <bianca(a)linux.vnet.ibm.com>
---
API.json | 4 ++++
docs/API.md | 3 +++
model/vms.py | 11 ++++++++---
tests/test_mockmodel.py | 2 +-
tests/test_model.py | 8 +++++++-
tests/test_rest.py | 18 ++++++++++++++++++
6 files changed, 41 insertions(+), 5 deletions(-)
diff --git a/API.json b/API.json
index adaa2f7..e72c68d 100644
--- a/API.json
+++ b/API.json
@@ -369,6 +369,10 @@
"error": "KCHVM0053E",
"type": "boolean"
},
+ "autostart": {
+ "description": "Enable/Disable guest autostart",
+ "type": "boolean"
+ },
"users": {
"description": "Array of users who have permission to the VM",
"type": "array",
diff --git a/docs/API.md b/docs/API.md
index 15f0007..43bb04b 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -151,6 +151,8 @@ server.
* bootorder: list of devices in boot order
* description: VM description
* title: VM title
+ * autostart: show if autostart is enabled.
+
* **DELETE**: Remove the Virtual Machine
* **PUT**: update the parameters of existing VM
* name: New name for this VM (only applied for shutoff VM)
@@ -183,6 +185,7 @@ server.
* bootmenu: prompts guest bootmenu. Bool type.
* description: VM description
* title: VM title
+ * autostart: enable/disable guest autostart (true or false params).
* **POST**: *See Virtual Machine Actions*
diff --git a/model/vms.py b/model/vms.py
index f13e605..a8e1c14 100644
--- a/model/vms.py
+++ b/model/vms.py
@@ -80,12 +80,13 @@ DOM_STATE_MAP = {0: 'nostate',
7: 'pmsuspended'}
# update parameters which are updatable when the VM is online
-VM_ONLINE_UPDATE_PARAMS = ['graphics', 'groups', 'memory', 'users']
+VM_ONLINE_UPDATE_PARAMS = ['graphics', 'groups', 'memory', 'users',
+ 'autostart']
# update parameters which are updatable when the VM is offline
VM_OFFLINE_UPDATE_PARAMS = ['cpu_info', 'graphics', 'groups', 'memory',
'name', 'users', 'bootorder', 'bootmenu',
- 'description', 'title']
+ 'description', 'title', 'autostart']
XPATH_DOMAIN_DISK = "/domain/devices/disk[@device='disk']/source/@file"
XPATH_DOMAIN_DISK_BY_FILE = "./devices/disk[@device='disk']/source[@file='%s']"
@@ -270,6 +271,9 @@ class VMModel(object):
with lock:
dom = self.get_vm(name, self.conn)
+ if "autostart" in params:
+ dom.setAutostart(1 if params['autostart'] == True else 0)
+
# You can only change <maxMemory> offline, updating guest XML
if ("memory" in params) and ('maxmemory' in params['memory']) and\
(DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
@@ -1314,7 +1318,8 @@ class VMModel(object):
'access': 'full',
'persistent': True if dom.isPersistent() else False,
'bootorder': boot,
- 'bootmenu': bootmenu
+ 'bootmenu': bootmenu,
+ 'autostart': dom.autostart()
}
def _vm_get_disk_paths(self, dom):
diff --git a/tests/test_mockmodel.py b/tests/test_mockmodel.py
index 147942c..ffd383c 100644
--- a/tests/test_mockmodel.py
+++ b/tests/test_mockmodel.py
@@ -164,7 +164,7 @@ class MockModelTests(unittest.TestCase):
keys = set(('name', 'state', 'stats', 'uuid', 'memory', 'cpu_info',
'screenshot', 'icon', 'graphics', 'users', 'groups',
'access', 'persistent', 'bootorder', 'bootmenu', 'title',
- 'description'))
+ 'description', 'autostart'))
stats_keys = set(('cpu_utilization', 'mem_utilization',
'net_throughput', 'net_throughput_peak',
diff --git a/tests/test_model.py b/tests/test_model.py
index d9ffd5e..2ed5e65 100644
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -129,7 +129,7 @@ class ModelTests(unittest.TestCase):
keys = set(('name', 'state', 'stats', 'uuid', 'memory', 'cpu_info',
'screenshot', 'icon', 'graphics', 'users', 'groups',
'access', 'persistent', 'bootorder', 'bootmenu', 'title',
- 'description'))
+ 'description', 'autostart'))
stats_keys = set(('cpu_utilization', 'mem_utilization',
'net_throughput', 'net_throughput_peak',
@@ -1362,6 +1362,12 @@ class ModelTests(unittest.TestCase):
inst.vm_update(u'пeω-∨м', {"bootmenu": False})
self.assertEquals("no", inst.vm_lookup(u'пeω-∨м')['bootmenu'])
+ # enable/disable autostart
+ inst.vm_update(u'пeω-∨м', {"autostart": True})
+ self.assertEquals(1, inst.vm_lookup(u'пeω-∨м')['autostart'])
+ inst.vm_update(u'пeω-∨м', {"autostart": False})
+ self.assertEquals(0, inst.vm_lookup(u'пeω-∨м')['autostart'])
+
def test_get_interfaces(self):
inst = model.Model('test:///default',
objstore_loc=self.tmp_store)
diff --git a/tests/test_rest.py b/tests/test_rest.py
index b1b9f12..4c1ed14 100644
--- a/tests/test_rest.py
+++ b/tests/test_rest.py
@@ -301,6 +301,24 @@ class RestTests(unittest.TestCase):
resp = self.request('/plugins/kimchi/vms/∨м-црdαtеd', req, 'PUT')
self.assertEquals(400, resp.status)
+ # set vm autostart tests (powered off)
+ resp = self.request('/plugins/kimchi/vms/vm-1/start', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ req = json.dumps({"autostart": True})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/vms/vm-1', '{}', 'GET').read()
+ self.assertEquals(resp["autostart"], True)
+
+ # set vm autostart tests (running)
+ resp = self.request('/plugins/kimchi/vms/vm-1/poweroff', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ req = json.dumps({"autostart": False})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/vms/vm-1', '{}', 'GET').read()
+ self.assertEquals(resp["autostart"], True)
+
def test_vm_lifecycle(self):
# Create a Template
req = json.dumps({'name': 'test',
--
2.7.4
8 years, 3 months
[PATCH V3] Issue #992 : Create template on s390x without libvirt storage
by harshalp@linux.vnet.ibm.com
From: Harshal Patil <harshalp(a)linux.vnet.ibm.com>
V1:
This patch adds support for creating templates on s390x arch
without using libvirt related storage calls
V2:
Review comments
V3:
Review comments and refactoring
Signed-off-by: Harshal Patil <harshalp(a)linux.vnet.ibm.com>
---
docs/API.md | 2 +
i18n.py | 3 ++
model/storagepools.py | 13 ++++--
model/storagevolumes.py | 1 -
model/templates.py | 27 +++++++++---
model/vms.py | 9 +++-
osinfo.py | 35 +++++++++++++--
utils.py | 34 +++++++++++++++
vmtemplate.py | 111 +++++++++++++++++++++++++++++++-----------------
9 files changed, 179 insertions(+), 56 deletions(-)
diff --git a/docs/API.md b/docs/API.md
index 7bd677f..d8d191a 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -427,6 +427,7 @@ A interface represents available network interface on VM.
over current will be used exclusively for memory hotplug
* cdrom: A volume name or URI to an ISO image
* storagepool: URI of the storagepool where template allocates vm storage.
+ * path : Storage path to store virtual disks without libvirt
* networks *(optional)*: list of networks will be assigned to the new VM.
* disks: An array of requested disks with the following optional fields
(either *size* or *volume* must be specified):
@@ -481,6 +482,7 @@ A interface represents available network interface on VM.
* format: Format of the image. Valid formats: qcow, qcow2, qed, raw, vmdk, vpc.
* pool: Storage pool information
* name: URI of the storagepool where template allocates vm disk.
+ * path (optional): Either pool or path to store the virtual disks should be specified
* graphics *(optional)*: A dict of graphics paramenters of this template
* type: The type of graphics. It can be VNC or spice or None.
* vnc: Graphical display using the Virtual Network
diff --git a/i18n.py b/i18n.py
index ea2c4ab..7e60079 100644
--- a/i18n.py
+++ b/i18n.py
@@ -190,6 +190,9 @@ messages = {
"KCHTMPL0031E": _("Memory value (%(mem)sMiB) must be equal or lesser than maximum memory value (%(maxmem)sMiB)"),
"KCHTMPL0032E": _("Unable to update template due error: %(err)s"),
"KCHTMPL0033E": _("Parameter 'disks' requires at least one disk object"),
+ "KCHTMPL0034E": _("Storage without libvirt pool is not supported on this architecture"),
+ "KCHTMPL0035E": _("Error while creating the virtual disk for the guest. Details: %(err)s"),
+ "KCHTMPL0036E": _("When setting template disks without libvirt, following parameters are required: 'index', 'format', 'path', 'size'"),
"KCHPOOL0001E": _("Storage pool %(name)s already exists"),
"KCHPOOL0002E": _("Storage pool %(name)s does not exist"),
diff --git a/model/storagepools.py b/model/storagepools.py
index af92ec9..5942b31 100644
--- a/model/storagepools.py
+++ b/model/storagepools.py
@@ -33,7 +33,7 @@ from wok.plugins.kimchi.model.host import DeviceModel
from wok.plugins.kimchi.model.libvirtstoragepool import StoragePoolDef
from wok.plugins.kimchi.osinfo import defaults as tmpl_defaults
from wok.plugins.kimchi.scan import Scanner
-from wok.plugins.kimchi.utils import pool_name_from_uri
+from wok.plugins.kimchi.utils import pool_name_from_uri, is_s390x
ISO_POOL_NAME = u'kimchi_isos'
@@ -57,6 +57,7 @@ STORAGE_SOURCES = {'netfs': {'addr': '/pool/source/host/@name',
class StoragePoolsModel(object):
+
def __init__(self, **kargs):
self.conn = kargs['conn']
self.objstore = kargs['objstore']
@@ -72,6 +73,9 @@ class StoragePoolsModel(object):
def _check_default_pools(self):
pools = {}
+ if is_s390x():
+ return
+
default_pool = tmpl_defaults['disks'][0]['pool']['name']
default_pool = default_pool.split('/')[-1]
@@ -437,9 +441,10 @@ class StoragePoolModel(object):
for tmpl in templates:
t_info = session.get('template', tmpl)
for disk in t_info['disks']:
- t_pool = disk['pool']['name']
- if pool_name_from_uri(t_pool) == pool_name:
- return True
+ if 'pool' in disk:
+ t_pool = disk['pool']['name']
+ if pool_name_from_uri(t_pool) == pool_name:
+ return True
return False
def deactivate(self, name):
diff --git a/model/storagevolumes.py b/model/storagevolumes.py
index 4708674..d721d3b 100644
--- a/model/storagevolumes.py
+++ b/model/storagevolumes.py
@@ -44,7 +44,6 @@ from wok.plugins.kimchi.model.diskutils import set_disk_used_by
from wok.plugins.kimchi.model.storagepools import StoragePoolModel
from wok.plugins.kimchi.utils import get_next_clone_name
-
VOLUME_TYPE_MAP = {0: 'file',
1: 'block',
2: 'directory',
diff --git a/model/templates.py b/model/templates.py
index 8df8c3b..c749f4b 100644
--- a/model/templates.py
+++ b/model/templates.py
@@ -28,13 +28,15 @@ import urlparse
from wok.exception import InvalidOperation, InvalidParameter
from wok.exception import NotFoundError, OperationFailed
-from wok.utils import probe_file_permission_as_user, run_setfacl_set_attr
+from wok.utils import probe_file_permission_as_user
+from wok.utils import run_setfacl_set_attr
from wok.xmlutils.utils import xpath_get_text
from wok.plugins.kimchi.config import get_kimchi_version
from wok.plugins.kimchi.kvmusertests import UserTests
from wok.plugins.kimchi.model.cpuinfo import CPUInfoModel
from wok.plugins.kimchi.utils import is_libvirtd_up, pool_name_from_uri
+from wok.plugins.kimchi.utils import create_disk_image
from wok.plugins.kimchi.vmtemplate import VMTemplate
ISO_TYPE = "ISO 9660 CD-ROM"
@@ -400,15 +402,26 @@ class LibvirtVMTemplate(VMTemplate):
def fork_vm_storage(self, vm_uuid):
# Provision storages:
- vol_list = self.to_volume_list(vm_uuid)
+ disk_and_vol_list = self.to_volume_list(vm_uuid)
try:
- for v in vol_list:
- pool = self._get_storage_pool(v['pool'])
- # outgoing text to libvirt, encode('utf-8')
- pool.createXML(v['xml'].encode('utf-8'), 0)
+ for v in disk_and_vol_list:
+ if v['pool'] is not None:
+ pool = self._get_storage_pool(v['pool'])
+ # outgoing text to libvirt, encode('utf-8')
+ pool.createXML(v['xml'].encode('utf-8'), 0)
+ else:
+ capacity = v['capacity']
+ format_type = v['format']
+ path = v['path']
+ create_disk_image(
+ format_type=format_type,
+ path=path,
+ capacity=capacity)
+
except libvirt.libvirtError as e:
raise OperationFailed("KCHVMSTOR0008E", {'error': e.message})
- return vol_list
+
+ return disk_and_vol_list
def set_cpu_info(self):
# undefined topology: consider these values to calculate maxvcpus
diff --git a/model/vms.py b/model/vms.py
index 7f607f5..3ad722e 100644
--- a/model/vms.py
+++ b/model/vms.py
@@ -61,7 +61,7 @@ from wok.plugins.kimchi.model.utils import remove_metadata_node
from wok.plugins.kimchi.model.utils import set_metadata_node
from wok.plugins.kimchi.osinfo import defaults, MEM_DEV_SLOTS
from wok.plugins.kimchi.screenshot import VMScreenshot
-from wok.plugins.kimchi.utils import get_next_clone_name
+from wok.plugins.kimchi.utils import get_next_clone_name, is_s390x
from wok.plugins.kimchi.utils import template_name_from_uri
from wok.plugins.kimchi.xmlutils.bootorder import get_bootorder_node
from wok.plugins.kimchi.xmlutils.bootorder import get_bootmenu_node
@@ -1395,6 +1395,13 @@ class VMModel(object):
except libvirt.libvirtError as e:
wok_log.error('Unable to get storage volume by path: %s' %
e.message)
+ try:
+ if is_s390x() and os.path.exists(path):
+ os.remove(path)
+ except Exception as e:
+ wok_log.error('Unable to delete storage path: %s' %
+ e.message)
+
except Exception as e:
raise OperationFailed('KCHVOL0017E', {'err': e.message})
diff --git a/osinfo.py b/osinfo.py
index 528cf14..b177830 100644
--- a/osinfo.py
+++ b/osinfo.py
@@ -158,6 +158,12 @@ def _get_tmpl_defaults():
'maxmemory': _get_default_template_mem()}
tmpl_defaults['storage']['disk.0'] = {'size': 10, 'format': 'qcow2',
'pool': 'default'}
+ is_on_s390x = True if _get_arch() == 's390x' else False
+
+ if is_on_s390x:
+ tmpl_defaults['storage']['disk.0']['path'] = '/var/lib/libvirt/images/'
+ del tmpl_defaults['storage']['disk.0']['pool']
+
tmpl_defaults['processor']['vcpus'] = 1
tmpl_defaults['processor']['maxvcpus'] = 1
tmpl_defaults['graphics'] = {'type': 'vnc', 'listen': '127.0.0.1'}
@@ -165,7 +171,12 @@ def _get_tmpl_defaults():
default_config = ConfigObj(tmpl_defaults)
# Load template configuration file
- config_file = os.path.join(kimchiPaths.sysconf_dir, 'template.conf')
+ if is_on_s390x:
+ config_file = os.path.join(
+ kimchiPaths.sysconf_dir,
+ 'template_s390x.conf')
+ else:
+ config_file = os.path.join(kimchiPaths.sysconf_dir, 'template.conf')
config = ConfigObj(config_file)
# Merge default configuration with file configuration
@@ -186,11 +197,27 @@ def _get_tmpl_defaults():
# Parse storage section to get disks values
storage_section = default_config.pop('storage')
defaults['disks'] = []
- for disk in storage_section.keys():
+
+ for index, disk in enumerate(storage_section.keys()):
data = storage_section[disk]
data['index'] = int(disk.split('.')[1])
- data['pool'] = {"name": '/plugins/kimchi/storagepools/' +
- storage_section[disk].pop('pool')}
+ # Right now 'Path' is only supported on s390x
+ if storage_section[disk].get('path') and is_on_s390x:
+ data['path'] = storage_section[disk].pop('path')
+ if 'size' not in storage_section[disk]:
+ data['size'] = tmpl_defaults['storage']['disk.0']['size']
+ else:
+ data['size'] = storage_section[disk].pop('size')
+
+ if 'format' not in storage_section[disk]:
+ data['format'] = tmpl_defaults['storage']['disk.0']['format']
+ else:
+ data['format'] = storage_section[disk].pop('format')
+ else:
+ storage_section[disk].get('pool')
+ data['pool'] = {"name": '/plugins/kimchi/storagepools/' +
+ storage_section[disk].pop('pool')}
+
defaults['disks'].append(data)
# Parse processor section to get vcpus and cpu_topology values
diff --git a/utils.py b/utils.py
index 26d3cf6..0fca191 100644
--- a/utils.py
+++ b/utils.py
@@ -24,6 +24,7 @@ import platform
import re
import sqlite3
import time
+import os
import urllib2
from httplib import HTTPConnection, HTTPException
from urlparse import urlparse
@@ -31,6 +32,7 @@ from urlparse import urlparse
from wok.exception import InvalidParameter, OperationFailed
from wok.plugins.kimchi import config
from wok.plugins.kimchi.osinfo import get_template_default
+from wok.stringutils import encode_value
from wok.utils import run_command, wok_log
from wok.xmlutils.utils import xpath_get_text
@@ -272,3 +274,35 @@ def is_libvirtd_up():
output, error, rc = run_command(cmd, silent=True)
return True if output == 'active\n' else False
+
+
+def is_s390x():
+ """
+ Check if current arch is 's390x'
+ Returns:
+ """
+ if os.uname()[4] == 's390x':
+ return True
+
+ return False
+
+
+def create_disk_image(format_type, path, capacity):
+ """
+ Create a disk image for the Guest
+ Args:
+ format: Format of the storage. e.g. qcow2
+ path: Path where the virtual disk will be created
+ capacity: Capacity of the virtual disk in GBs
+
+ Returns:
+
+ """
+ out, err, rc = run_command(
+ ["/usr/bin/qemu-img", "create", "-f", format_type, "-o",
+ "preallocation=metadata", path, encode_value(capacity) + "G"])
+
+ if rc != 0:
+ raise OperationFailed("KCHTMPL0035E", {'err': err})
+
+ return
\ No newline at end of file
diff --git a/vmtemplate.py b/vmtemplate.py
index babf050..2d3a351 100644
--- a/vmtemplate.py
+++ b/vmtemplate.py
@@ -31,7 +31,8 @@ from wok.exception import MissingParameter, OperationFailed
from wok.plugins.kimchi import imageinfo
from wok.plugins.kimchi import osinfo
from wok.plugins.kimchi.isoinfo import IsoImage
-from wok.plugins.kimchi.utils import check_url_path, pool_name_from_uri
+from wok.plugins.kimchi.utils import check_url_path, is_s390x
+from wok.plugins.kimchi.utils import pool_name_from_uri
from wok.plugins.kimchi.xmlutils.bootorder import get_bootorder_xml
from wok.plugins.kimchi.xmlutils.cpu import get_cpu_xml
from wok.plugins.kimchi.xmlutils.disk import get_disk_xml
@@ -42,6 +43,7 @@ from wok.plugins.kimchi.xmlutils.serial import get_serial_xml
class VMTemplate(object):
+
def __init__(self, args, scan=False, netboot=False):
"""
Construct a VM Template from a widely variable amount of information.
@@ -95,35 +97,55 @@ class VMTemplate(object):
disks = self.info.get('disks')
basic_disk = ['index', 'format', 'pool', 'size']
+ basic_path_disk = ['index', 'format', 'path', 'size']
ro_disk = ['index', 'format', 'pool', 'volume']
base_disk = ['index', 'base', 'pool', 'size', 'format']
for index, disk in enumerate(disks):
disk_info = dict(default_disk)
-
- pool = disk.get('pool', default_disk['pool'])
- pool_type = self._get_storage_type(pool['name'])
-
- if pool_type in ['iscsi', 'scsi']:
- disk_info = {'index': 0, 'format': 'raw', 'volume': None}
-
- disk_info.update(disk)
- pool_name = disk_info.get('pool', {}).get('name')
- if pool_name is None:
- raise MissingParameter('KCHTMPL0028E')
-
- keys = sorted(disk_info.keys())
- if ((keys != sorted(basic_disk)) and (keys != sorted(ro_disk)) and
- (keys != sorted(base_disk))):
- raise MissingParameter('KCHTMPL0028E')
-
- if pool_type in ['logical', 'iscsi', 'scsi']:
- if disk_info['format'] != 'raw':
- raise InvalidParameter('KCHTMPL0029E')
-
- disk_info['pool']['type'] = pool_type
- disk_info['index'] = disk_info.get('index', index)
- self.info['disks'][index] = disk_info
+ if disk.get('pool'):
+ pool = disk.get('pool', default_disk.get('pool'))
+ pool_type = self._get_storage_type(pool['name'])
+ if pool_type in ['iscsi', 'scsi']:
+ disk_info = {'index': 0, 'format': 'raw', 'volume': None}
+
+ # This check is required where 'path' disk
+ # exists and is replaced by 'pool' disk during
+ # template update
+ if 'path' in disk_info:
+ del disk_info['path']
+
+ disk_info.update(disk)
+ pool_name = disk_info.get('pool', {}).get('name')
+ if pool_name is None:
+ raise MissingParameter('KCHTMPL0028E')
+
+ keys = sorted(disk_info.keys())
+ if ((keys != sorted(basic_disk)) and
+ (keys != sorted(ro_disk)) and
+ (keys != sorted(base_disk)) and
+ (keys != sorted(basic_path_disk))):
+ raise MissingParameter('KCHTMPL0028E')
+
+ if pool_type in ['logical', 'iscsi', 'scsi']:
+ if disk_info['format'] != 'raw':
+ raise InvalidParameter('KCHTMPL0029E')
+
+ disk_info['pool']['type'] = pool_type
+ disk_info['index'] = disk_info.get('index', index)
+ self.info['disks'][index] = disk_info
+ elif is_s390x():
+ # For now support 'path' only on s390x
+ path = disk.get('path', default_disk['path'])
+ disk_info.update(disk)
+ keys = sorted(disk_info.keys())
+ if keys != sorted(basic_path_disk):
+ raise MissingParameter('KCHTMPL0036E')
+ disk_info['path'] = path
+ disk_info['index'] = disk_info.get('index', index)
+ self.info['disks'][index] = disk_info
+ else:
+ raise InvalidParameter('KCHTMPL0034E')
def _get_os_info(self, args, scan):
distro = version = 'unknown'
@@ -217,8 +239,9 @@ class VMTemplate(object):
params = dict(base_disk_params)
params['format'] = disk['format']
params['index'] = index
- params.update(locals().get('%s_disk_params' %
- disk['pool']['type'], {}))
+ if disk.get('pool'):
+ params.update(locals().get('%s_disk_params' %
+ disk['pool']['type'], {}))
volume = disk.get('volume')
if volume is not None:
@@ -226,9 +249,13 @@ class VMTemplate(object):
volume)
else:
img = "%s-%s.img" % (vm_uuid, params['index'])
- storage_path = self._get_storage_path(disk['pool']['name'])
+ if disk.get('pool'):
+ storage_path = self._get_storage_path(disk['pool']['name'])
+ params['pool_type'] = disk['pool']['type']
+ elif disk.get('path'):
+ storage_path = disk.get('path')
+ params['pool_type'] = None
params['path'] = os.path.join(storage_path, img)
- params['pool_type'] = disk['pool']['type']
disks_xml += get_disk_xml(params)[1]
return unicode(disks_xml, 'utf-8')
@@ -237,20 +264,24 @@ class VMTemplate(object):
ret = []
for i, d in enumerate(self.info['disks']):
# Create only .img. If storagepool is (i)SCSI, volumes will be LUNs
- if d['pool']['type'] in ["iscsi", "scsi"]:
+ if 'pool' in d and d['pool']['type'] in ["iscsi", "scsi"]:
continue
index = d.get('index', i)
volume = "%s-%s.img" % (vm_uuid, index)
- storage_path = self._get_storage_path(d['pool']['name'])
+ if 'path' in d:
+ storage_path = d['path']
+ else:
+ storage_path = self._get_storage_path(d['pool']['name'])
+
info = {'name': volume,
'capacity': d['size'],
'format': d['format'],
'path': '%s/%s' % (storage_path, volume),
- 'pool': d['pool']['name']}
+ 'pool': d['pool']['name'] if 'pool' in d else None}
- if 'logical' == d['pool']['type'] or \
+ if ('pool' in d and 'logical' == d['pool']['type']) or \
info['format'] not in ['qcow2', 'raw']:
info['allocation'] = info['capacity']
else:
@@ -447,8 +478,9 @@ class VMTemplate(object):
def validate(self):
for disk in self.info.get('disks'):
- pool_uri = disk.get('pool', {}).get('name')
- self._get_storage_pool(pool_uri)
+ if 'pool' in disk:
+ pool_uri = disk.get('pool', {}).get('name')
+ self._get_storage_pool(pool_uri)
self._network_validate()
self._iso_validate()
self.cpuinfo_validate()
@@ -499,10 +531,11 @@ class VMTemplate(object):
# validate storagepools and image-based templates integrity
for disk in self.info['disks']:
- pool_uri = disk['pool']['name']
- pool_name = pool_name_from_uri(pool_uri)
- if pool_name not in self._get_active_storagepools_name():
- invalid['storagepools'] = [pool_name]
+ if 'pool' in disk:
+ pool_uri = disk['pool']['name']
+ pool_name = pool_name_from_uri(pool_uri)
+ if pool_name not in self._get_active_storagepools_name():
+ invalid['storagepools'] = [pool_name]
if disk.get("base") is None:
continue
--
1.9.1
8 years, 3 months
[PATCH] [Wok] Removing Kimchi Peers dropdown from Wok navbar
by sguimaraes943@gmail.com
From: Samuel Guimarães <sguimaraes943(a)gmail.com>
This patch removes Peers dropdown from Wok navbar
Samuel Guimarães (1):
Removing Kimchi Peers dropdown from Wok navbar
ui/js/src/wok.main.js | 29 +----------------------------
1 file changed, 1 insertion(+), 28 deletions(-)
--
2.5.5
8 years, 3 months
[PATCH V4] [Wok 0/5] Issue #141 - Handle AsyncTasks in request log
by Lucio Correia
V4: review comments (use app uri in log entry and document req='TASK' usage)
V3: review comments
V2: rebase with master to fix conflict
Lucio Correia (5):
Create log_request() method for code simplification
Update Request Logger to handle AsyncTask status
Log AsyncTask success or failure
Save log entry IDs for requests that generate tasks
Change location of User Requests Log
src/wok/asynctask.py | 49 +++++++++--
src/wok/control/base.py | 63 +++++++--------
src/wok/control/utils.py | 1 -
src/wok/i18n.py | 2 +
src/wok/reqlogger.py | 205 ++++++++++++++++++++++++++++++++---------------
src/wok/root.py | 40 +--------
src/wok/utils.py | 12 ---
7 files changed, 218 insertions(+), 154 deletions(-)
--
1.9.1
8 years, 3 months
[RFC] Addition attribute required to specify console type for VM(s)/ template(s) for s390x specific architecture only.
by Archana Singh
Hi All,
Currently on x86 or ppc, console type does not need to be passed from
API and hence we do not have API to specify type of console in VM(s)/
template(s).
On s390x architecture, two type of console sclp or virtio are supported.
And hence we need to update VM(s)/template(s) API to have attribute to
get and modify type of console.
console (s390x only): Specify the console parameter.
type: sclp/virtio.
If not provided, default sclp.
Below are the list of current API and proposed API which need to have
addition parameter 'console' and its type:
1) GET list of VMs and its attribute and Create VM.
*Current:*
Collection: Virtual Machines
URI: /plugins/kimchi/vms
Methods:
GET: Retrieve a summarized list of all defined Virtual Machines
POST: Create a new Virtual Machine
name (optional): The name of the VM. Used to identify the VM in
this API. If omitted, a name will be chosen based on the template used.
persistent: If 'true', vm will persist after a Power Off or
host reboot. All virtual machines created by Kimchi are persistent.
template: The URI of a Template to use when building the VM
storagepool (optional): Assign a specific Storage Pool to the
new VM
graphics (optional): Specify the graphics parameter for this vm
type: The type of graphics. It can be VNC or spice or None.
vnc: Graphical display using the Virtual Network
Computing protocol
spice: Graphical display using the Simple Protocol for
Independent Computing Environments
null: Graphics is disabled or type not supported
listen: The network which the vnc/spice server listens on.
description: VM description
title: VM title
*Proposed:*
Collection: Virtual Machines
URI: /plugins/kimchi/vms
Methods:
GET: Retrieve a summarized list of all defined Virtual Machines
POST: Create a new Virtual Machine
name (optional): The name of the VM. Used to identify the VM in
this API. If omitted, a name will be chosen based on the template used.
persistent: If 'true', vm will persist after a Power Off or
host reboot. All virtual machines created by Kimchi are persistent.
template: The URI of a Template to use when building the VM
storagepool (optional): Assign a specific Storage Pool to the
new VM
graphics (optional): Specify the graphics paramenter for this vm
type: The type of graphics. It can be VNC or spice or None.
vnc: Graphical display using the Virtual Network
Computing protocol
spice: Graphical display using the Simple Protocol for
Independent Computing Environments
null: Graphics is disabled or type not supported
listen: The network which the vnc/spice server listens on.
* console (s390x only): Specify the console parameter for this vm.**
** type: sclp/virtio.**
** If not provided, default sclp.*
description: VM description
title: VM title
2) GET details of a VM.
*Current:*
Resource: Virtual Machine
URI: /plugins/kimchi/vms/:name
Methods:
GET: Retrieve the full description of a Virtual Machine
name: The name of the VM. Used to identify the VM in this API
state: Indicates the current state in the VM lifecycle
running: The VM is powered on
paused: The VMs virtual CPUs are paused
shutoff: The VM is powered off
stats: Virtual machine statistics:
cpu_utilization: A number between 0 and 100 which indicates
the percentage of CPU utilization.
mem_utilization: A number between 0 and 100 which indicates
the percentage of memory utilization.
net_throughput: Expresses total network throughput for
reads and writes across all virtual interfaces (kb/s).
net_throughput_peak: The highest recent value of
'net_throughput'.
io_throughput: Expresses the total IO throughput for reads
and writes across all virtual disks (kb/s).
io_throughput_peak: The highest recent value of
'io_throughput'.
uuid: UUID of the VM.
memory: The memory parameters of the VM in the unit of MiB.
current: The amount of memory that is assigned to the VM.
maxmemory: The maximum total of memory that the VM can
have. Amount over current will be used exclusively for memory hotplug
cpu_info: CPU-specific information.
vcpus: The number of CPUs assigned to the VM
maxvcpus: The maximum number of CPUs that can be assigned
to the VM
topology: Processor topology, includes:
sockets - The maximum number of sockets to use.
cores - The number of cores per socket.
threads - The number of threads per core.
screenshot: A link to a recent capture of the screen in PNG format
icon: A link to an icon that represents the VM
graphics: A dict to show detail of VM graphics.
type: The type of graphics. It can be VNC or spice or None.
vnc: Graphical display using the Virtual Network
Computing protocol
spice: Graphical display using the Simple Protocol for
Independent Computing Environments
null: Graphics is disabled or type not supported
listen: The network which the vnc/spice server listens on.
port: The real port number of the graphics, vnc or spice.
Users can use this port to connect to the vm with general vnc/spice clients.
passwd: console password
passwdValidTo: lifetime for the console password.
users: A list of system users who have permission to access the
VM. Default is: empty (i.e. only root-users may access).
groups: A list of system groups whose users have permission to
access the VM. Default is: empty (i.e. no groups given access).
bootorder: list of devices in boot order
description: VM description
title: VM title
*Proposed:*
Resource: Virtual Machine
URI: /plugins/kimchi/vms/:name
Methods:
GET: Retrieve the full description of a Virtual Machine
name: The name of the VM. Used to identify the VM in this API
state: Indicates the current state in the VM lifecycle
running: The VM is powered on
paused: The VMs virtual CPUs are paused
shutoff: The VM is powered off
stats: Virtual machine statistics:
cpu_utilization: A number between 0 and 100 which indicates
the percentage of CPU utilization.
mem_utilization: A number between 0 and 100 which indicates
the percentage of memory utilization.
net_throughput: Expresses total network throughput for
reads and writes across all virtual interfaces (kb/s).
net_throughput_peak: The highest recent value of
'net_throughput'.
io_throughput: Expresses the total IO throughput for reads
and writes across all virtual disks (kb/s).
io_throughput_peak: The highest recent value of
'io_throughput'.
uuid: UUID of the VM.
memory: The memory parameters of the VM in the unit of MiB.
current: The amount of memory that is assigned to the VM.
maxmemory: The maximum total of memory that the VM can
have. Amount over current will be used exclusively for memory hotplug
cpu_info: CPU-specific information.
vcpus: The number of CPUs assigned to the VM
maxvcpus: The maximum number of CPUs that can be assigned
to the VM
topology: Processor topology, includes:
sockets - The maximum number of sockets to use.
cores - The number of cores per socket.
threads - The number of threads per core.
screenshot: A link to a recent capture of the screen in PNG format
icon: A link to an icon that represents the VM
graphics: A dict to show detail of VM graphics.
type: The type of graphics. It can be VNC or spice or None.
vnc: Graphical display using the Virtual Network
Computing protocol
spice: Graphical display using the Simple Protocol for
Independent Computing Environments
null: Graphics is disabled or type not supported
listen: The network which the vnc/spice server listens on.
port: The real port number of the graphics, vnc or spice.
Users can use this port to connect to the vm with general vnc/spice clients.
passwd: console password
passwdValidTo: lifetime for the console password.
* console (s390x only, optional): Specify the console parameter
for this vm.**
** type: sclp/virtio.**
** If not provided, default sclp.*
users: A list of system users who have permission to access the
VM. Default is: empty (i.e. only root-users may access).
groups: A list of system groups whose users have permission to
access the VM. Default is: empty (i.e. no groups given access).
bootorder: list of devices in boot order
description: VM description
title: VM title
3) Update a VM details
*Current:*
Resource: Virtual Machine
URI: /plugins/kimchi/vms/:name
Method:
PUT: update the parameters of existing VM
name: New name for this VM (only applied for shutoff VM)
users: New list of system users.
groups: New list of system groups.
memory: New memory parameters of the VM in the unit of MiB. Provide
one or both.
current: New amount of memory that will be assigned to the VM.
maxmemory: New maximum total of memory that the VM can have.
graphics: A dict to show detail of VM graphics.
passwd (optional): console password. When omitted a random
password willbe generated.
passwdValidTo (optional): lifetime for the console password.
When omitted the password will be valid just for 30 seconds.
type (optional): graphics type. VNC or Spice.
cpu_info (optional): CPU-specific information.
maxvcpus (optional): The maximum number of vCPUs that can be
assigned to the VM. If topology is specified, maxvcpus must be a product
of sockets, cores and threads.
vcpus (optional): The number of vCPUs assigned to the VM.
Default is 1, unless a CPU topology is specified. In that case, vcpus
must be a multiple of a product of cores and threads, and will default
to maxvcpus value.
topology (optional): Specify sockets, threads, and cores to run
the virtual CPU threads on. All three are required.
sockets - The maximum number of sockets to use.
cores - The number of cores per socket.
threads - The number of threads per core.
bootorder: guest bootorder, types accepted: hd, cdrom, network or fd
bootmenu: prompts guest bootmenu. Bool type.
description: VM description
title: VM title
*Proposed:*
Resource: Virtual Machine
URI: /plugins/kimchi/vms/:name
Method:
PUT: update the parameters of existing VM
name: New name for this VM (only applied for shutoff VM)
users: New list of system users.
groups: New list of system groups.
memory: New memory parameters of the VM in the unit of MiB. Provide
one or both.
current: New amount of memory that will be assigned to the VM.
maxmemory: New maximum total of memory that the VM can have.
graphics: A dict to show detail of VM graphics.
passwd (optional): console password. When omitted a random
password willbe generated.
passwdValidTo (optional): lifetime for the console password.
When omitted the password will be valid just for 30 seconds.
type (optional): graphics type. VNC or Spice.
* console (s390x only, optional): Specify the console parameter for
this vm.**
** type: sclp/virtio.**
** If not provided, default sclp.*
cpu_info (optional): CPU-specific information.
maxvcpus (optional): The maximum number of vCPUs that can be
assigned to the VM. If topology is specified, maxvcpus must be a product
of sockets, cores and threads.
vcpus (optional): The number of vCPUs assigned to the VM.
Default is 1, unless a CPU topology is specified. In that case, vcpus
must be a multiple of a product of cores and threads, and will default
to maxvcpus value.
topology (optional): Specify sockets, threads, and cores to run
the virtual CPU threads on. All three are required.
sockets - The maximum number of sockets to use.
cores - The number of cores per socket.
threads - The number of threads per core.
bootorder: guest bootorder, types accepted: hd, cdrom, network or fd
bootmenu: prompts guest bootmenu. Bool type.
description: VM description
title: VM title
4) Get templates and create a template.
*
**Current:*
Collection: Templates
URI: /plugins/kimchi/templates
Methods:
GET: Retrieve a summarized list of all defined Templates
POST: Create a new Template
name: The name of the Template. Used to identify the Template
in this API
source_media: dictionary. The type of media to be used in the
installation.
type: the type of the media. Values: 'netboot' and 'disk'.
path: applicable for type = 'disk' only. Indicates the path
of the source media.
os_distro (optional): The operating system distribution
os_version (optional): The version of the operating system
distribution
memory (optional): The memory parameters of the template,
specify one or both. Default values are 1024MiB:
current: The amount of memory that will be assigned to the VM.
maxmemory: The maximum total of memory that the VM can
have. Amount over current will be used exclusively for memory hotplug
networks (optional): list of networks will be assigned to the
new VM. Default is '[default]'
disks (optional): An array of requested disks with the
following optional fields (either size or volume must be specified):
index: The device index
size: The device size in GB
format: Format of the image. Valid formats: qcow, qcow2,
qed, raw, vmdk, vpc
pool: Storage pool information
name: URI of the storagepool where disk will be created
graphics (optional): The graphics paramenters of this template
type: The type of graphics. It can be VNC or spice or None.
vnc: Graphical display using the Virtual Network
Computing protocol
spice: Graphical display using the Simple Protocol for
Independent Computing Environments
null: Graphics is disabled or type not supported
listen: The network which the vnc/spice server listens on.
cpu_info (optional): CPU-specific information.
maxvcpus (optional): The maximum number of vCPUs that can
be assigned to the VM. If topology is specified, maxvcpus must be a
product of sockets, cores and threads.
vcpus (optional): The number of vCPUs assigned to the VM.
Default is 1, unless a CPU topology is specified. In that case, vcpus
must be a multiple of a product of cores and threads, and will default
to maxvcpus value.
topology (optional): Specify sockets, threads, and cores to
run the virtual CPU threads on. All three are required.
sockets - The maximum number of sockets to use.
cores - The number of cores per socket.
threads - The number of threads per core.
*Proposed:*
Collection: Templates
URI: /plugins/kimchi/templates
Methods:
GET: Retrieve a summarized list of all defined Templates
POST: Create a new Template
name: The name of the Template. Used to identify the Template
in this API
source_media: dictionary. The type of media to be used in the
installation.
type: the type of the media. Values: 'netboot' and 'disk'.
path: applicable for type = 'disk' only. Indicates the path
of the source media.
os_distro (optional): The operating system distribution
os_version (optional): The version of the operating system
distribution
memory (optional): The memory parameters of the template,
specify one or both. Default values are 1024MiB:
current: The amount of memory that will be assigned to the VM.
maxmemory: The maximum total of memory that the VM can
have. Amount over current will be used exclusively for memory hotplug
networks (optional): list of networks will be assigned to the
new VM. Default is '[default]'
disks (optional): An array of requested disks with the
following optional fields (either size or volume must be specified):
index: The device index
size: The device size in GB
format: Format of the image. Valid formats: qcow, qcow2,
qed, raw, vmdk, vpc
pool: Storage pool information
name: URI of the storagepool where disk will be created
graphics (optional): The graphics paramenters of this template
type: The type of graphics. It can be VNC or spice or None.
vnc: Graphical display using the Virtual Network
Computing protocol
spice: Graphical display using the Simple Protocol for
Independent Computing Environments
null: Graphics is disabled or type not supported
listen: The network which the vnc/spice server listens on.
* console (s390x only, optional): Specify the console parameter
for this template.**
** type:sclp/virtio.**
** If not provided, default sclp.*
cpu_info (optional): CPU-specific information.
maxvcpus (optional): The maximum number of vCPUs that can
be assigned to the VM. If topology is specified, maxvcpus must be a
product of sockets, cores and threads.
vcpus (optional): The number of vCPUs assigned to the VM.
Default is 1, unless a CPU topology is specified. In that case, vcpus
must be a multiple of a product of cores and threads, and will default
to maxvcpus value.
topology (optional): Specify sockets, threads, and cores to
run the virtual CPU threads on. All three are required.
sockets - The maximum number of sockets to use.
cores - The number of cores per socket.
threads - The number of threads per core.
5) Get a template details.
*Current:-*
Resource: Template
URI: /plugins/kimchi/templates/:name
Methods:
GET: Retrieve the full description of a Template
name: A name for this template
folder: A virtual path which can be used to organize Templates
in a user interface. The format is an array of path components.
icon: A URI to a PNG image representing this template
os_distro: The operating system distribution
os_version: The version of the operating system distribution
memory: The memory parameters of the template, that will be
assigned to the VM in the unit of MiB.
current: The amount of memory that will be assigned to the VM.
maxmemory: The maximum total of memory that the VM can
have. Amount over current will be used exclusively for memory hotplug
cdrom: A volume name or URI to an ISO image
storagepool: URI of the storagepool where template allocates vm
storage.
networks (optional): list of networks will be assigned to the
new VM.
interfaces (optional): list of host network interfaces will be
assigned to the new VM. Only applicable for s390x or s390 architecture.
type: Type of host network interface. Type should be
'macvtap' for host network interface (Ethernet, Bond, VLAN) to be
connected as direct MacVTap; or 'ovs' for openvswitch host network
interface to be connected as virtual switch to a VM.
name: The host network interface. It should be the host
network interface (Ethernet, Bond, VLAN) for type 'macvtap' or host
openvswitch bridge interface for type 'ovs'.
mode (optional): Only applicable for interface type
macvtap, to indicates whether packets will be delivered directly to
target device(bridge) or to the external bridge(vepa-capable bridge).
bridge: If packets have a destination on the host from
which they originated, they are delivered directly to the target. For
direct delivery, both origin and destination devices need to be in
bridge mode. If either the origin or destination is in vepa mode,
VEPA-capable bridge is required.
vepa: All packets are sent to the external bridge. If
packets have a destination on the host from which they originated, the
VEPA-capable bridge will return the packets to the host.
disks: An array of requested disks with the following optional
fields (either size or volume must be specified):
index: The device index
size: The device size in GB
volume: A volume name that contains the initial disk contents
format: Format of the image. Valid formats: qcow, qcow2,
qed, raw, vmdk, vpc.
pool: Information about the pool where disk or volume will
be created
name: URI of the storagepool
type: Type of the storagepool (dir, nfs, scsci, iscsi, etc)
graphics: A dict of graphics paramenters of this template
type: The type of graphics. It can be VNC or spice or None.
vnc: Graphical display using the Virtual Network
Computing protocol
spice: Graphical display using the Simple Protocol for
Independent Computing Environments
null: Graphics is disabled or type not supported
listen: The network which the vnc/spice server listens on.
invalid: A dict indicates which paramenters of this template
are invalid.
networks (optional): An array of invalid network names.
cdrom (optional): An array of invalid cdrom names.
disks (optional): An array of invalid volume names.
storagepools (optional): An array of invalid storagepool names.
cpu_info: CPU-specific information.
vcpus: The number of CPUs assigned to the VM
maxvcpus: The maximum number of CPUs that can be assigned
to the VM
topology: Processor topology, includes:
sockets - The maximum number of sockets to use.
cores - The number of cores per socket.
threads - The number of threads per core.
*Proposed:-*
Resource: Template
URI: /plugins/kimchi/templates/:name
Methods:
GET: Retrieve the full description of a Template
name: A name for this template
folder: A virtual path which can be used to organize Templates
in a user interface. The format is an array of path components.
icon: A URI to a PNG image representing this template
os_distro: The operating system distribution
os_version: The version of the operating system distribution
memory: The memory parameters of the template, that will be
assigned to the VM in the unit of MiB.
current: The amount of memory that will be assigned to the VM.
maxmemory: The maximum total of memory that the VM can
have. Amount over current will be used exclusively for memory hotplug
cdrom: A volume name or URI to an ISO image
storagepool: URI of the storagepool where template allocates vm
storage.
networks (optional): list of networks will be assigned to the
new VM.
interfaces (optional): list of host network interfaces will be
assigned to the new VM. Only applicable for s390x or s390 architecture.
type: Type of host network interface. Type should be
'macvtap' for host network interface (Ethernet, Bond, VLAN) to be
connected as direct MacVTap; or 'ovs' for openvswitch host network
interface to be connected as virtual switch to a VM.
name: The host network interface. It should be the host
network interface (Ethernet, Bond, VLAN) for type 'macvtap' or host
openvswitch bridge interface for type 'ovs'.
mode (optional): Only applicable for interface type
macvtap, to indicates whether packets will be delivered directly to
target device(bridge) or to the external bridge(vepa-capable bridge).
bridge: If packets have a destination on the host from
which they originated, they are delivered directly to the target. For
direct delivery, both origin and destination devices need to be in
bridge mode. If either the origin or destination is in vepa mode,
VEPA-capable bridge is required.
vepa: All packets are sent to the external bridge. If
packets have a destination on the host from which they originated, the
VEPA-capable bridge will return the packets to the host.
disks: An array of requested disks with the following optional
fields (either size or volume must be specified):
index: The device index
size: The device size in GB
volume: A volume name that contains the initial disk contents
format: Format of the image. Valid formats: qcow, qcow2,
qed, raw, vmdk, vpc.
pool: Information about the pool where disk or volume will
be created
name: URI of the storagepool
type: Type of the storagepool (dir, nfs, scsci, iscsi, etc)
graphics: A dict of graphics paramenters of this template
type: The type of graphics. It can be VNC or spice or None.
vnc: Graphical display using the Virtual Network
Computing protocol
spice: Graphical display using the Simple Protocol for
Independent Computing Environments
null: Graphics is disabled or type not supported
listen: The network which the vnc/spice server listens on.
* console (s390x only, optional): Specify the console parameter
for this template.**
** type:sclp/virtio.**
** If not provided, default sclp.*
invalid: A dict indicates which paramenters of this template
are invalid.
networks (optional): An array of invalid network names.
cdrom (optional): An array of invalid cdrom names.
disks (optional): An array of invalid volume names.
storagepools (optional): An array of invalid storagepool names.
cpu_info: CPU-specific information.
vcpus: The number of CPUs assigned to the VM
maxvcpus: The maximum number of CPUs that can be assigned
to the VM
topology: Processor topology, includes:
sockets - The maximum number of sockets to use.
cores - The number of cores per socket.
threads - The number of threads per core.
6) Update existing template.
*Current:*
Resource: Template
URI: /plugins/kimchi/templates/:name
Method:
PUT: update the parameters of existed template
name: A name for this template
folder: A virtual path which can be used to organize Templates in
the user interface. The format is an array of path components.
icon: A URI to a PNG image representing this template
os_distro: The operating system distribution
os_version: The version of the operating system distribution
memory: The memory parameters of the template, specify one or both of:
current: The amount of memory that will be assigned to the VM.
maxmemory: The maximum total of memory that the VM can have.
Amount over current will be used exclusively for memory hotplug
cdrom: A volume name or URI to an ISO image
networks (optional): list of networks will be assigned to the new VM.
interfaces (optional): list of host network interfaces will be
assigned to the new VM. Only applicable for s390x or s390 architecture.
type: Type of host network interface. Type should be 'macvtap'
for host network interface (Ethernet, Bond, VLAN) to be connected as
direct MacVTap; or 'ovs' for openvswitch host network interface to be
connected as virtual switch to a VM.
name: The host network interface. It should be the host network
interface (Ethernet, Bond, VLAN) for type 'macvtap' or host openvswitch
bridge interface for type 'ovs'.
mode (optional): Only applicable for interface type macvtap, to
indicates whether packets will be delivered directly to target
device(bridge) or to the external bridge(vepa-capable bridge).
bridge: If packets have a destination on the host from
which they originated, they are delivered directly to the target. For
direct delivery, both origin and destination devices need to be in
bridge mode. If either the origin or destination is in vepa mode,
VEPA-capable bridge is required.
vepa: All packets are sent to the external bridge. If
packets have a destination on the host from which they originated, the
VEPA-capable bridge will return the packets to the host.
disks: An array of requested disks with the following optional
fields (either size or volume must be specified):
index: The device index
size: The device size in GB
volume: A volume name that contains the initial disk contents
format: Format of the image. Valid formats: qcow, qcow2, qed,
raw, vmdk, vpc.
pool: Storage pool information
name: URI of the storagepool where template allocates vm disk.
graphics (optional): A dict of graphics paramenters of this template
type: The type of graphics. It can be VNC or spice or None.
vnc: Graphical display using the Virtual Network Computing
protocol
spice: Graphical display using the Simple Protocol for
Independent Computing Environments
null: Graphics is disabled or type not supported
listen: The network which the vnc/spice server listens on.
cpu_info (optional): CPU-specific information.
maxvcpus (optional): The maximum number of vCPUs that can be
assigned to the VM. If topology is specified, maxvcpus must be a product
of sockets, cores and threads.
vcpus (optional): The number of vCPUs assigned to the VM.
Default is 1, unless a CPU topology is specified. In that case, vcpus
must be a multiple of a product of cores and threads, and will default
to maxvcpus value.
topology (optional): Specify sockets, threads, and cores to run
the virtual CPU threads on. All three are required.
sockets - The maximum number of sockets to use.
cores - The number of cores per socket.
threads - The number of threads per core.
*Proposed:-*
Resource: Template
URI: /plugins/kimchi/templates/:name
Method:
PUT: update the parameters of existed template
name: A name for this template
folder: A virtual path which can be used to organize Templates in
the user interface. The format is an array of path components.
icon: A URI to a PNG image representing this template
os_distro: The operating system distribution
os_version: The version of the operating system distribution
memory: The memory parameters of the template, specify one or both of:
current: The amount of memory that will be assigned to the VM.
maxmemory: The maximum total of memory that the VM can have.
Amount over current will be used exclusively for memory hotplug
cdrom: A volume name or URI to an ISO image
networks (optional): list of networks will be assigned to the new VM.
interfaces (optional): list of host network interfaces will be
assigned to the new VM. Only applicable for s390x or s390 architecture.
type: Type of host network interface. Type should be 'macvtap'
for host network interface (Ethernet, Bond, VLAN) to be connected as
direct MacVTap; or 'ovs' for openvswitch host network interface to be
connected as virtual switch to a VM.
name: The host network interface. It should be the host network
interface (Ethernet, Bond, VLAN) for type 'macvtap' or host openvswitch
bridge interface for type 'ovs'.
mode (optional): Only applicable for interface type macvtap, to
indicates whether packets will be delivered directly to target
device(bridge) or to the external bridge(vepa-capable bridge).
bridge: If packets have a destination on the host from
which they originated, they are delivered directly to the target. For
direct delivery, both origin and destination devices need to be in
bridge mode. If either the origin or destination is in vepa mode,
VEPA-capable bridge is required.
vepa: All packets are sent to the external bridge. If
packets have a destination on the host from which they originated, the
VEPA-capable bridge will return the packets to the host.
disks: An array of requested disks with the following optional
fields (either size or volume must be specified):
index: The device index
size: The device size in GB
volume: A volume name that contains the initial disk contents
format: Format of the image. Valid formats: qcow, qcow2, qed,
raw, vmdk, vpc.
pool: Storage pool information
name: URI of the storagepool where template allocates vm disk.
graphics (optional): A dict of graphics paramenters of this template
type: The type of graphics. It can be VNC or spice or None.
vnc: Graphical display using the Virtual Network Computing
protocol
spice: Graphical display using the Simple Protocol for
Independent Computing Environments
null: Graphics is disabled or type not supported
listen: The network which the vnc/spice server listens on.
* console (s390x only, optional): Specify the console parameter for
this template.**
** type:sclp/virtio.**
** If not provided, default sclp.*
cpu_info (optional): CPU-specific information.
maxvcpus (optional): The maximum number of vCPUs that can be
assigned to the VM. If topology is specified, maxvcpus must be a product
of sockets, cores and threads.
vcpus (optional): The number of vCPUs assigned to the VM.
Default is 1, unless a CPU topology is specified. In that case, vcpus
must be a multiple of a product of cores and threads, and will default
to maxvcpus value.
topology (optional): Specify sockets, threads, and cores to run
the virtual CPU threads on. All three are required.
sockets - The maximum number of sockets to use.
cores - The number of cores per socket.
threads - The number of threads per core.
Thanks,
Archana Singh
8 years, 3 months
[PATCHv4] [Kimchi] Issue# 973 Emphasize resource name in dlg
by Socorro Stoppler
From: Socorro <socorro(a)linux.vnet.ibm.com>
v4:
Add style for <strong> to only ones in confirmation dialog. Thanks
Samuel for the consultation :)
v3:
In some distros, the resource name is not being displayed in bold due to
a problem with Open Sans. Per Samuel, there are some cases, mainly with
Firefox in that some style with font weight set to 600 does not work and 700
is usually too bold to set as a fallback. Therefore, just use the same style
as <abbr> and <acronynm> tags which creates a dotted bottom
v2:
Display resource name (with name in bold) in confirmation dialog
v1:
When confirmation dialogs are shown, also display the name of the resource being
acted on (i.e. guest name, network, storage, template) as part of the message.
Signed-off-by: Socorro <socorro(a)linux.vnet.ibm.com>
---
ui/css/kimchi.css | 4 ++++
ui/css/src/modules/_guests.scss | 4 ++++
ui/js/src/kimchi.guest_main.js | 14 +++++++++-----
ui/js/src/kimchi.network.js | 6 ++++--
ui/js/src/kimchi.storage_main.js | 8 +++++---
ui/js/src/kimchi.template_main.js | 5 +++--
ui/pages/i18n.json.tmpl | 20 ++++++++++----------
7 files changed, 39 insertions(+), 22 deletions(-)
diff --git a/ui/css/kimchi.css b/ui/css/kimchi.css
index dff8013..6cf2cc9 100644
--- a/ui/css/kimchi.css
+++ b/ui/css/kimchi.css
@@ -294,6 +294,10 @@
font-size: 32px;
}
+#wok-confirm-modal .modal-body strong {
+ border-bottom: 1px dotted;
+}
+
#guest-add-window .modal-body {
margin: 0;
padding: 0;
diff --git a/ui/css/src/modules/_guests.scss b/ui/css/src/modules/_guests.scss
index 040b351..8b8345c 100644
--- a/ui/css/src/modules/_guests.scss
+++ b/ui/css/src/modules/_guests.scss
@@ -46,6 +46,10 @@
}
}
+#wok-confirm-modal .modal-body strong {
+ border-bottom: 1px dotted;
+}
+
#guest-add-window {
.modal-body {
margin: 0;
diff --git a/ui/js/src/kimchi.guest_main.js b/ui/js/src/kimchi.guest_main.js
index 9c1aa54..34217e4 100644
--- a/ui/js/src/kimchi.guest_main.js
+++ b/ui/js/src/kimchi.guest_main.js
@@ -127,8 +127,9 @@ kimchi.vmpoweroff = function(event) {
var vm_id = vm.attr("id");
var vmObject = vm.data();
var vm_persistent = vmObject.persistent == true;
- var content_msg = vm_persistent ? i18n['KCHVM6003M'] :
- i18n['KCHVM6009M'];
+ var content_msg_1 = i18n['KCHVM6003M'].replace('%1', '<strong>'+vm_id+'</strong>');
+ var content_msg_2 = i18n['KCHVM6009M'].replace('%1', '<strong>'+vm_id+'</strong>');
+ var content_msg = vm_persistent ? content_msg_1 : content_msg_2;
var settings = {
title: i18n['KCHVM6002M'],
content: content_msg,
@@ -153,9 +154,10 @@ kimchi.vmshutdown = function(event) {
var button = event.target;
var vm = $(button).closest('li[name=guest]');
var vm_id = vm.attr("id");
+ var confirmMessage = i18n['KCHVM6007M'].replace('%1', '<strong>'+vm_id+'</strong>');
var settings = {
title: i18n['KCHVM6006M'],
- content: i18n['KCHVM6007M'],
+ content: confirmMessage,
confirm: i18n['KCHAPI6002M'],
cancel: i18n['KCHAPI6003M']
};
@@ -174,9 +176,10 @@ kimchi.vmreset = function(event) {
$(button).addClass('loading');
var vm = $(button).closest('li[name=guest]');
var vm_id = $(vm).attr("id");
+ var confirmMessage = i18n['KCHVM6005M'].replace('%1', '<strong>'+vm_id+'</strong>');
var settings = {
title: i18n['KCHVM6004M'],
- content: i18n['KCHVM6005M'],
+ content: confirmMessage,
confirm: i18n['KCHAPI6002M'],
cancel: i18n['KCHAPI6003M']
};
@@ -204,9 +207,10 @@ kimchi.vmdelete = function(event) {
var button = event.target;
var vm = $(button).closest('li[name=guest]');
var vm_id = $(vm).attr("id");
+ var confirmMessage = i18n['KCHVM6001M'].replace('%1', '<strong>'+vm_id+'</strong>');
var settings = {
title: i18n['KCHVM6008M'],
- content: i18n['KCHVM6001M'],
+ content: confirmMessage,
confirm: i18n['KCHAPI6002M'],
cancel: i18n['KCHAPI6003M']
};
diff --git a/ui/js/src/kimchi.network.js b/ui/js/src/kimchi.network.js
index ac6bf74..7ce5b28 100644
--- a/ui/js/src/kimchi.network.js
+++ b/ui/js/src/kimchi.network.js
@@ -161,9 +161,10 @@ kimchi.addNetworkActions = function(network) {
return false;
}
if (!network.persistent) {
+ var confirmMessage = i18n['KCHNET6004M'].replace('%1', '<strong>'+network.name+'</strong>');
var settings = {
title : i18n['KCHAPI6001M'],
- content : i18n['KCHNET6004M'],
+ content : confirmMessage,
confirm : i18n['KCHAPI6002M'],
cancel : i18n['KCHAPI6003M']
};
@@ -180,9 +181,10 @@ kimchi.addNetworkActions = function(network) {
if (network.state === "up" || network.in_use) {
return false;
}
+ var confirmMessage = i18n['KCHNET6002M'].replace('%1', '<strong>'+network.name+'</strong>');
wok.confirm({
title : i18n['KCHAPI6006M'],
- content : i18n['KCHNET6002M'],
+ content : confirmMessage,
confirm : i18n['KCHAPI6002M'],
cancel : i18n['KCHAPI6003M']
}, function() {
diff --git a/ui/js/src/kimchi.storage_main.js b/ui/js/src/kimchi.storage_main.js
index 6c99f93..18e6eea 100644
--- a/ui/js/src/kimchi.storage_main.js
+++ b/ui/js/src/kimchi.storage_main.js
@@ -310,14 +310,15 @@ kimchi.storageBindClick = function() {
$('.pool-delete').on('click', function(event) {
event.preventDefault();
var $pool = $(this);
+ var poolName = $pool.data('name');
+ var confirmMessage = i18n['KCHPOOL6001M'].replace('%1', '<strong>'+poolName+'</strong>');
var settings = {
title : i18n['KCHAPI6001M'],
- content : i18n['KCHPOOL6001M'],
+ content : confirmMessage,
confirm : i18n['KCHAPI6002M'],
cancel : i18n['KCHAPI6003M']
};
wok.confirm(settings, function() {
- var poolName = $pool.data('name');
kimchi.deleteStoragePool(poolName, function() {
kimchi.doListStoragePools();
}, function(err) {
@@ -339,9 +340,10 @@ kimchi.storageBindClick = function() {
$('.pool-deactivate').on('click', function(event) {
event.preventDefault();
var poolName = $(this).data('name');
+ var confirmMessage = i18n['KCHPOOL6012M'].replace('%1', '<strong>'+poolName+'</strong>');
var settings = {
title : i18n['KCHAPI6001M'],
- content : i18n['KCHPOOL6012M'],
+ content : confirmMessage,
confirm : i18n['KCHAPI6002M'],
cancel : i18n['KCHAPI6003M']
};
diff --git a/ui/js/src/kimchi.template_main.js b/ui/js/src/kimchi.template_main.js
index 302d906..cf98a7b 100644
--- a/ui/js/src/kimchi.template_main.js
+++ b/ui/js/src/kimchi.template_main.js
@@ -124,14 +124,15 @@ kimchi.templateBindClick = function() {
$('.template-delete a').on('click', function(event) {
event.preventDefault();
var $template = $(this);
+ var templateName = $template.data('template');
+ var confirmMessage = i18n['KCHTMPL6003M'].replace('%1', '<strong>'+templateName+'</strong>');
var settings = {
title: i18n['KCHAPI6001M'],
- content: i18n['KCHTMPL6003M'],
+ content: confirmMessage,
confirm: i18n['KCHAPI6002M'],
cancel: i18n['KCHAPI6003M']
};
wok.confirm(settings, function() {
- var templateName = $template.data('template');
kimchi.deleteTemplate(templateName, function() {
kimchi.doListTemplates();
}, function(err) {
diff --git a/ui/pages/i18n.json.tmpl b/ui/pages/i18n.json.tmpl
index f9e148d..7beee19 100644
--- a/ui/pages/i18n.json.tmpl
+++ b/ui/pages/i18n.json.tmpl
@@ -47,24 +47,24 @@
"KCHTMPL6001W": "$_("No ISO found")",
"KCHTMPL6002M": "$_("This may take a long time. Do you want to continue?")",
- "KCHTMPL6003M": "$_("This will permanently delete the template. Would you like to continue?")",
+ "KCHTMPL6003M": "$_("This will permanently delete the %1 template. Would you like to continue?")",
"KCHTMPL6004M": "$_("View Table")",
"KCHTMPL6005M": "$_("View Gallery")",
"KCHTMPL6006M": "$_("Not Available")",
"KCHTMPL6007M": "$_("Please check the invalid Storage Pools")",
- "KCHVM6001M": "$_("This will delete the virtual machine and its virtual disks. This operation cannot be undone. Would you like to continue?")",
+ "KCHVM6001M": "$_("This will delete the %1 virtual machine and its virtual disks. This operation cannot be undone. Would you like to continue?")",
"KCHVM6002M": "$_("Power off Confirmation")",
"KCHVM6003M": "$_("This action may produce undesirable results, "
- "for example unflushed disk cache in the guest. "
+ "for example unflushed disk cache in the %1 guest. "
"Would you like to continue?")",
"KCHVM6004M": "$_("Reset Confirmation")",
"KCHVM6005M": "$_("There is a risk of data loss caused by reset without"
- " the guest OS shutdown. Would you like to continue?")",
+ " the %1 guest OS shutdown. Would you like to continue?")",
"KCHVM6006M": "$_("Shut Down Confirmation")",
- "KCHVM6007M": "$_("Note the guest OS may ignore this request. Would you like to continue?")",
+ "KCHVM6007M": "$_("Note the %1 guest OS may ignore this request. Would you like to continue?")",
"KCHVM6008M": "$_("Virtual Machine delete Confirmation")",
- "KCHVM6009M": "$_("This virtual machine is not persistent. Power Off will delete it. Continue?")",
+ "KCHVM6009M": "$_("The %1 virtual machine is not persistent. Power Off will delete it. Continue?")",
"KCHVM0001E": "$_("Input is not a number")",
"KCHVM0002E": "$_("Memory value cannot be higher than Max Memory value")",
@@ -89,11 +89,11 @@
"KCHVMED6012M": "$_("Following devices will be affected, confirm?")",
"KCHNET6001M": "$_("unavailable")",
- "KCHNET6002M": "$_("This action will interrupt network connectivity for any virtual machine that depend on this network.")",
- "KCHNET6004M": "$_("This network is not persistent. Instead of stop, this action will permanently delete it. Would you like to continue?")",
+ "KCHNET6002M": "$_("This action will interrupt network connectivity for any virtual machine that depend on the %1 network.")",
+ "KCHNET6004M": "$_("The %1 network is not persistent. Instead of stop, this action will permanently delete it. Would you like to continue?")",
"KCHNET6001W": "$_("The bridged VLAN tag may not work well with NetworkManager enabled. You should consider disabling it.")",
- "KCHPOOL6001M": "$_("This will permanently delete the storage pool. Would you like to continue?")",
+ "KCHPOOL6001M": "$_("This will permanently delete the %1 storage pool. Would you like to continue?")",
"KCHPOOL6002M": "$_("This storage pool is empty.")",
"KCHPOOL6003M": "$_("It will format your disk and you will loose any data in there, are you sure to continue? ")",
"KCHPOOL6004M": "$_("SCSI Fibre Channel")",
@@ -108,7 +108,7 @@
"KCHPOOL6006E": "$_("No logical device selected.")",
"KCHPOOL6009E": "$_("This is not a valid Server Name or IP. Please, modify it.")",
"KCHPOOL6011M": "$_("No available partitions found.")",
- "KCHPOOL6012M": "$_("This storage pool is not persistent. Instead of deactivate, this action will permanently delete it. Would you like to continue?")",
+ "KCHPOOL6012M": "$_("The %1 storage pool is not persistent. Instead of deactivate, this action will permanently delete it. Would you like to continue?")",
"KCHPOOL6013M": "$_("Unable to retrieve partitions information.")",
"KCHPOOL6014M": "$_("In progress...")",
"KCHPOOL6015M": "$_("Failed!")",
--
2.7.4
8 years, 3 months
[PATCH v3][Kimchi 0/2] Allow vm update graphics type
by Ramon Medeiros
Changes:
v3:
Tested patch on Fedora, RHEL, Ubuntu and Opensuse - working correctly
Add rest test
v2:
Fix typos
Add tests
Ramon Medeiros (2):
Issue #836: Allow user change guest graphics type
Create test to verify graphics type change
API.json | 6 ++++++
docs/API.md | 1 +
i18n.py | 2 +-
model/vms.py | 10 ++++++++++
tests/test_model.py | 18 +++++++-----------
tests/test_rest.py | 10 ++++++++++
6 files changed, 35 insertions(+), 12 deletions(-)
--
2.5.5
8 years, 3 months
[PATCH][Kimchi] Issue #994: SPICE graphics does not need <channel> tag
by Ramon Medeiros
Signed-off-by: Ramon Medeiros <ramonn(a)linux.vnet.ibm.com>
---
xmlutils/graphics.py | 14 +-------------
1 file changed, 1 insertion(+), 13 deletions(-)
diff --git a/xmlutils/graphics.py b/xmlutils/graphics.py
index 5465bb8..4297c4f 100644
--- a/xmlutils/graphics.py
+++ b/xmlutils/graphics.py
@@ -24,22 +24,10 @@ from lxml.builder import E
def get_graphics_xml(params):
"""
<graphics type='%(type)s' autoport='yes' listen='%(listen)s'/>
-
- - For spice graphics:
-
- <channel type='spicevmc'>
- <target type='virtio' name='com.redhat.spice.0'/>
- </channel>
"""
graphics = E.graphics(type=params['type'], autoport='yes',
listen=params['listen'])
graphics_xml = ET.tostring(graphics, encoding='utf-8', pretty_print=True)
- if params['type'] == 'vnc':
- return graphics_xml
+ return graphics_xml
- # For spice graphics, a channel also must be configured
- channel = E.channel(type='spicevmc')
- channel.append(E.target(type='virtio', name='com.redhat.spice.0'))
- channel_xml = ET.tostring(channel, encoding='utf-8', pretty_print=True)
- return graphics_xml + channel_xml
--
2.5.5
8 years, 3 months