[PATCH 0/2 V3] Detect and enable help page from plugins tabs
by Rodrigo Trujillo
This patch set changes the way Kimchi loads Help pages of the tabs of
the plugins.
It also changes the Sample plugin, in order to demonstrate and show
properly how to configure the a Help page
Rodrigo Trujillo (2):
Fix problems to open plugin's help pages
Changes in sample plugin to fix and improve help
configure.ac | 1 -
plugins/sample/Makefile.am | 12 +++++
plugins/sample/sample.conf.in | 5 ++
plugins/sample/ui/config/tab-ext.xml | 11 ++++-
plugins/sample/ui/pages/Makefile.am | 2 +-
.../sample/ui/pages/help/en_US/sample-tab1.html | 1 +
.../sample/ui/pages/help/en_US/sample-tab2.html | 1 +
plugins/sample/ui/pages/sample-tab1.html.tmpl | 30 ++++++++++++
plugins/sample/ui/pages/sample-tab2.html.tmpl | 30 ++++++++++++
plugins/sample/ui/pages/tab.html.tmpl | 30 ------------
ui/js/src/kimchi.main.js | 55 +++++++++++++++++-----
11 files changed, 133 insertions(+), 45 deletions(-)
create mode 100644 plugins/sample/ui/pages/help/en_US/sample-tab1.html
create mode 100644 plugins/sample/ui/pages/help/en_US/sample-tab2.html
create mode 100644 plugins/sample/ui/pages/sample-tab1.html.tmpl
create mode 100644 plugins/sample/ui/pages/sample-tab2.html.tmpl
delete mode 100644 plugins/sample/ui/pages/tab.html.tmpl
--
1.9.3
10 years, 2 months
[PATCH 0/5] Power (ppc) support patches
by Paulo Vital
This patch set enables Power(ppc) support by default on Kimchi.
Whithout them, the upstream code of Kimchi is not fully compatible
with the Power architecture.
Eli Qiao (2):
Add tablet to vmtemplate,to provides an absolute pointer device which
often helps with getting a consistent mouse cursor position in VNC.
Fix Bug 110927 - Sosreport throwing kimchi error Signed-off-by: Eli
Qiao <taget(a)linux.vnet.ibm.com>
Mark Wu (1):
Add sos plugin for kimchi
Paulo Vital (2):
PowerKVM: Workaround of numpy byte order bug on PowerPC
Add PowerKVM information as ISO otpion to installation.
contrib/kimchi.spec.fedora.in | 3 +++
src/kimchi/Makefile.am | 4 +++-
src/kimchi/isoinfo.py | 1 +
src/kimchi/osinfo.py | 5 +++--
src/kimchi/sos.py | 37 +++++++++++++++++++++++++++++++++++++
src/kimchi/vmtemplate.py | 5 +++++
src/kimchi/websocket.py | 7 +++++--
7 files changed, 57 insertions(+), 5 deletions(-)
create mode 100644 src/kimchi/sos.py
--
1.9.3
10 years, 2 months
[RFC: PATCH v1] Prevent disks from being added more than once
by Christy Perez
The concept of a ref count for disks had been added, but this count
was dependant upon the pool name for a disk. However, the pool name
wasn't being stored in the VM XML so it wasn't possible to retreive
the pool for the disk in order to update the ref count.
To fix this, this patch changes the way that disks are added when
created in libvirt storage pools. Instead of files, they are treated
as volumes in pools.
Note: Because of this modification, a small inconsistency in the API,
which states that the pool for a vm's "storages" is returned, is
corrected. The pool is returned as an empty string if the disk or
volume was not create from a pool (e.g. a remote ISO).
Signed-off-by: Christy Perez <christy(a)linux.vnet.ibm.com>
---
src/kimchi/model/storagevolumes.py | 13 ++++++--
src/kimchi/model/vmstorages.py | 68 +++++++++++++++++++++++++++++++++++---
src/kimchi/vmdisks.py | 33 ++++++++++++++----
src/kimchi/vmtemplate.py | 41 ++++++++++++++++-------
4 files changed, 129 insertions(+), 26 deletions(-)
diff --git a/src/kimchi/model/storagevolumes.py b/src/kimchi/model/storagevolumes.py
index f9f226f..af97748 100644
--- a/src/kimchi/model/storagevolumes.py
+++ b/src/kimchi/model/storagevolumes.py
@@ -249,19 +249,26 @@ def _get_ref_cnt(self, pool, name, path):
try:
ref_cnt = session.get('storagevolume', vol_id)['ref_cnt']
except NotFoundError:
+ kimchi_log.info('Volume %s not found in obj store.' % vol_id)
# Fix storage volume created outside kimchi scope
ref_cnt = 0
- # try to find this volume in exsisted vm
+ # try to find this volume in exsisting vm
vms = VMsModel.get_vms(self.conn)
for vm in vms:
dom = VMModel.get_vm(vm, self.conn)
storages = get_vm_disk_list(dom)
for disk in storages:
- d_info = get_vm_disk(dom, disk)
+ d_info = get_vm_disk(dom, disk, self.conn)
if path == d_info['path']:
ref_cnt = ref_cnt + 1
- session.store('storagevolume', vol_id,
+ try:
+ session.store('storagevolume', vol_id,
{'ref_cnt': ref_cnt})
+ except Exception as e:
+ # Just log an error if the obj store fails:
+ kimchi_log.warning('Unable to store storage volume id in '
+ 'objectstore due error: %s', e.message)
+
except Exception as e:
# This exception is going to catch errors returned by 'with',
# specially ones generated by 'session.store'. It is outside
diff --git a/src/kimchi/model/vmstorages.py b/src/kimchi/model/vmstorages.py
index 4d6c0b2..1b2c0fe 100644
--- a/src/kimchi/model/vmstorages.py
+++ b/src/kimchi/model/vmstorages.py
@@ -32,7 +32,7 @@
from kimchi.model.vms import DOM_STATE_MAP, VMModel
from kimchi.model.storagevolumes import StorageVolumeModel
from kimchi.model.utils import get_vm_config_flag
-from kimchi.utils import check_url_path
+from kimchi.utils import check_url_path, kimchi_log
from kimchi.osinfo import lookup
from kimchi.vmdisks import get_device_xml, get_vm_disk, get_vm_disk_list
from kimchi.vmdisks import DEV_TYPE_SRC_ATTR_MAP
@@ -73,6 +73,11 @@ def _get_storage_xml(params, ignore_source=False):
source = E.source(protocol=output.scheme, name=output.path)
source.append(host)
disk.append(source)
+ elif src_type == 'volume':
+ source = E.source()
+ source.set('pool', params.get('pool'))
+ source.set('volume', params.get('vol'))
+ disk.append(source)
else:
# Fixing source attribute
source = E.source()
@@ -138,6 +143,8 @@ def create(self, vm_name, params):
# Path will never be blank due to API.json verification.
# There is no need to cover this case here.
params['format'] = 'raw'
+ vol_info = None
+ vol_store_name = None
if not ('vol' in params) ^ ('path' in params):
raise InvalidParameter("KCHVMSTOR0017E")
if params.get('vol'):
@@ -146,6 +153,7 @@ def create(self, vm_name, params):
vol_info = StorageVolumeModel(
conn=self.conn,
objstore=self.objstore).lookup(pool, params['vol'])
+ vol_store_name = '%s:%s' % (pool, params['vol'])
except KeyError:
raise InvalidParameter("KCHVMSTOR0012E")
except Exception as e:
@@ -158,6 +166,10 @@ def create(self, vm_name, params):
params['format'] = vol_info['format']
params['path'] = vol_info['path']
params['src_type'] = _check_path(params['path'])
+ if params['src_type'] is 'file' and params.get('pool') and \
+ params.get('vol'):
+ params['src_type'] = 'volume'
+ # change from 'file' to volume if in a pool ^^
if (params['bus'] not in HOTPLUG_TYPE
and DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
raise InvalidOperation('KCHVMSTOR0011E')
@@ -171,6 +183,16 @@ def create(self, vm_name, params):
dom.attachDeviceFlags(dev_xml, get_vm_config_flag(dom, 'all'))
except Exception as e:
raise OperationFailed("KCHVMSTOR0008E", {'error': e.message})
+
+ try:
+ new_ref_cnt = vol_info['ref_cnt'] + 1
+ with self.objstore as session:
+ session.store('storagevolume', vol_store_name, {'ref_cnt': new_ref_cnt})
+ except Exception as e:
+ # Just log an error if the obj store fails:
+ kimchi_log.warning('Unable to store storage volume id in '
+ 'objectstore due error: %s', e.message)
+
return params['dev']
def _get_storage_device_name(self, vm_name, params):
@@ -192,25 +214,41 @@ def get_list(self, vm_name):
dom = VMModel.get_vm(vm_name, self.conn)
return get_vm_disk_list(dom)
-
class VMStorageModel(object):
def __init__(self, **kargs):
self.conn = kargs['conn']
+ self.objstore = kargs['objstore']
def lookup(self, vm_name, dev_name):
# Retrieve disk xml and format return dict
dom = VMModel.get_vm(vm_name, self.conn)
- return get_vm_disk(dom, dev_name)
+ disk = get_vm_disk(dom, dev_name, self.conn)
+ # Also include the pool and volume
+ pool_name = ''
+ vol_name = ''
+ try:
+ pool_name = disk.get('pool')
+ vol_name = disk.get('volume')
+ except Exception as e:
+ kimchi_log.warning('VMDisk lookup error: %s' % e.message)
+
+ disk['pool'] = pool_name
+ disk['volume'] = vol_name
+ return disk
def delete(self, vm_name, dev_name):
# Get storage device xml
dom = VMModel.get_vm(vm_name, self.conn)
+ disk_info = None
+ disk_xml = None
+ pool_name = ''
+ vol_name = ''
try:
- bus_type = self.lookup(vm_name, dev_name)['bus']
+ disk_info = self.lookup(vm_name, dev_name)
+ bus_type = disk_info['bus']
except NotFoundError:
raise
- dom = VMModel.get_vm(vm_name, self.conn)
if (bus_type not in HOTPLUG_TYPE and
DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
raise InvalidOperation('KCHVMSTOR0011E')
@@ -224,10 +262,30 @@ def delete(self, vm_name, dev_name):
except Exception as e:
raise OperationFailed("KCHVMSTOR0010E", {'error': e.message})
+ # Get the pool and vol of a disk so we can
+ # decrement its ref_cnt in the obj store
+ pool_name = disk_info.get('pool')
+ vol_name = disk_info.get('volume')
+
+ if(pool_name and vol_name):
+ try:
+ vol_id = '%s:%s' % (pool_name, vol_name)
+ with self.objstore as session:
+ vol = session.get('storagevolume', vol_id)
+ if vol:
+ ref_cnt = vol['ref_cnt']
+ if ref_cnt > 0:
+ ref_cnt = ref_cnt - 1
+ session.store('storagevolume', vol_id, {'ref_cnt': ref_cnt})
+ except Exception as e:
+ kimchi_log.warning('Unable to decrement volume ref count due to %s.'
+ % e.message)
+
def update(self, vm_name, dev_name, params):
path = params.get('path')
if path and len(path) != 0:
params['src_type'] = _check_path(path)
+ # change from 'file' to 'volume' if pool ^^
ignore_source = False
else:
params['src_type'] = 'file'
diff --git a/src/kimchi/vmdisks.py b/src/kimchi/vmdisks.py
index 6012ada..185a499 100644
--- a/src/kimchi/vmdisks.py
+++ b/src/kimchi/vmdisks.py
@@ -17,6 +17,8 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+import libvirt
+import os
from lxml import objectify
from kimchi.exception import NotFoundError
@@ -34,37 +36,56 @@ def get_device_xml(dom, dev_name):
return None
return disk[0]
+def get_pool_xml(conn, pool_name):
+ conn = conn.get()
+ return objectify.fromstring(conn.\
+ storagePoolLookupByName(pool_name).XMLDesc(0))
-def get_vm_disk(dom, dev_name):
+def get_vm_disk(dom, dev_name, conn):
# Retrieve disk xml and format return dict
disk = get_device_xml(dom, dev_name)
if disk is None:
raise NotFoundError(
"KCHVMSTOR0007E",
{'dev_name': dev_name, 'vm_name': dom.name()})
- path = ""
+ path = ''
dev_bus = 'ide'
+ pool_name = ''
+ vol_name = ''
try:
source = disk.source
if source is not None:
- src_type = disk.attrib['type']
+ src_type = disk.get('type')
if src_type == 'network':
host = source.host
path = (source.attrib['protocol'] + '://' +
host.attrib['name'] + ':' +
host.attrib['port'] + source.attrib['name'])
+ elif src_type == 'volume':
+ pool_name = disk.source.get('pool')
+ pool = get_pool_xml(conn, pool_name)
+ pool_path = str(pool.target.path)
+ vol_name = disk.source.attrib['volume']
+ path = os.path.join(pool_path, vol_name)
else:
path = source.attrib[DEV_TYPE_SRC_ATTR_MAP[src_type]]
# Retrieve storage bus type
dev_bus = disk.target.attrib['bus']
- except:
- pass
+ except Exception as e:
+ kimchi_log.warning("get_vm_disk exception: %s " % e.message)
+
dev_type = disk.attrib['device']
+
+ # Pool and volume may be empty strings, if the user passed a disk name.
+ # If the disk was from a storage pool, let's use that so we can keep track
+ # of its ref_cnt in the objects store.
return {'dev': dev_name,
'type': dev_type,
'path': path,
'format': disk.driver.attrib['type'],
- 'bus': dev_bus}
+ 'bus': dev_bus,
+ 'pool': pool_name,
+ 'volume': vol_name}
def get_vm_disk_list(dom):
diff --git a/src/kimchi/vmtemplate.py b/src/kimchi/vmtemplate.py
index 5f22db9..1940911 100644
--- a/src/kimchi/vmtemplate.py
+++ b/src/kimchi/vmtemplate.py
@@ -187,24 +187,41 @@ def _get_cdrom_xml(self, libvirt_stream_protocols, qemu_stream_dns):
return network_file % (params)
def _get_disks_xml(self, vm_uuid):
- storage_path = self._get_storage_path()
+ def TYPE(v):
+ return {'type': v}
+
+ #storage_path = self._get_storage_path()
+ _pool = pool_name_from_uri(self.info['storagepool'])
ret = ""
for i, disk in enumerate(self.info['disks']):
index = disk.get('index', i)
- volume = "%s-%s.img" % (vm_uuid, index)
- src = os.path.join(storage_path, volume)
+ _volume = "%s-%s.img" % (vm_uuid, index)
+ #src = os.path.join(storage_path, volume)
dev = "%s%s" % (self._bus_to_dev[self.info['disk_bus']],
string.lowercase[index])
fmt = 'raw' if self._get_storage_type() in ['logical'] else 'qcow2'
- params = {'src': src, 'dev': dev, 'bus': self.info['disk_bus'],
- 'type': fmt}
- ret += """
- <disk type='file' device='disk'>
- <driver name='qemu' type='%(type)s' cache='none'/>
- <source file='%(src)s' />
- <target dev='%(dev)s' bus='%(bus)s' />
- </disk>
- """ % params
+ #params = {'src': src, 'dev': dev, 'bus': self.info['disk_bus'],
+ # 'type': fmt}
+ #ret += """
+ #<disk type='file' device='disk'>
+ # <driver name='qemu' type='%(type)s' cache='none'/>
+ # <source file='%(src)s' />
+ # <target dev='%(dev)s' bus='%(bus)s' />
+ #</disk>
+ #""" % params
+
+ # Instead do:
+ #<disk type='volume'>
+ # <driver name='qemu' type='%(type)s' cache='none'/>
+ # <source pool='%(pool)s' volume='%(volume)s' />
+ # <target dev='%(dev)s' bus='%(bus)s />
+ #</disk>
+ disk = E.disk(
+ E.driver(TYPE(fmt), name='qemu', cache='none'),
+ E.source(pool=_pool, volume=_volume),
+ E.target(dev=dev, bus=self.info['disk_bus']),
+ TYPE('volume'))
+ ret += etree.tostring(disk)
return ret
def _get_graphics_xml(self, params):
--
1.9.3
10 years, 2 months
[PATCH 0/2 V4] Detect and enable help page from plugins tabs
by Rodrigo Trujillo
This patch set changes the way Kimchi loads Help pages of the tabs of
the plugins.
It also changes the Sample plugin, in order to demonstrate and show
properly how to configure the a Help page
Rodrigo Trujillo (2):
Fix problems to open plugin's help pages
Changes in sample plugin to fix and improve help
configure.ac | 1 -
plugins/sample/Makefile.am | 12 +++++
plugins/sample/sample.conf.in | 5 ++
plugins/sample/ui/config/tab-ext.xml | 11 ++++-
plugins/sample/ui/pages/Makefile.am | 2 +-
.../sample/ui/pages/help/en_US/sample-tab1.html | 1 +
.../sample/ui/pages/help/en_US/sample-tab2.html | 1 +
plugins/sample/ui/pages/sample-tab1.html.tmpl | 30 ++++++++++++
plugins/sample/ui/pages/sample-tab2.html.tmpl | 30 ++++++++++++
plugins/sample/ui/pages/tab.html.tmpl | 30 ------------
ui/js/src/kimchi.main.js | 53 ++++++++++++++++------
11 files changed, 129 insertions(+), 47 deletions(-)
create mode 100644 plugins/sample/ui/pages/help/en_US/sample-tab1.html
create mode 100644 plugins/sample/ui/pages/help/en_US/sample-tab2.html
create mode 100644 plugins/sample/ui/pages/sample-tab1.html.tmpl
create mode 100644 plugins/sample/ui/pages/sample-tab2.html.tmpl
delete mode 100644 plugins/sample/ui/pages/tab.html.tmpl
--
1.9.3
10 years, 2 months
[PATCH 0/2] PCI Passthrough: Add device to VM
by huoyuxin@linux.vnet.ibm.com
From: Yu Xin Huo <huoyuxin(a)linux.vnet.ibm.com>
Yu Xin Huo (2):
Passthrough: Add PCI Devices to VM
update po files
po/en_US.po | 15 ++++++
po/kimchi.pot | 15 ++++++
po/pt_BR.po | 15 ++++++
po/zh_CN.po | 15 ++++++
ui/css/theme-default/guest-edit.css | 86 ++++++++++++++++++++++++++++++++++-
ui/js/src/kimchi.api.js | 55 ++++++++++++++++++++++
ui/js/src/kimchi.guest_edit_main.js | 66 +++++++++++++++++++++++++++
ui/pages/guest-edit.html.tmpl | 28 +++++++++++
8 files changed, 293 insertions(+), 2 deletions(-)
10 years, 2 months
Error in the log when using VMs not created by kimchi
by Wen Wang
Hi all,
When kimchi deal with VMs that are not created by kimchi or build before
we introducing "metadata", an error "metadata not found: Requested
metadata element is not present" will continuously appear in the log, I
have one suggestion from the feedback that is it possible to have this
part removed? I mean the error message. One proper suggestion is
:"Whichever function is causing that can be redirected to device called
/dev/null so that it won't come to /var/log/messages".
Best Regards
Wang Wen
10 years, 2 months
[PATCH v11 0/6] Host Device Passthrough
by Zhou Zheng Sheng
Hi all,
Host device passthrough is to directly assign host device to guest
exclusively, so there is no virtualization overhead, and it improves
guest performance greatly. It's useful if you have a server with lots
of PCIe slots and cards.
This v11 patch series improve disto compatibility and device filtering.
Firstly, the patches adapt to Ubuntu 14.04, RHEL 6.5, RHEL 7, Fedora 20
and Fedora 19. It just relies on libvirt node-device API, kernel vfio
framework and /sys/kernel/iommu_group. So any distribution providing
these features should work. On old distributions like RHEL 6.5, they
are shipped with 2.6.X kernel which do not support vfio and sysfs iommu
group. We also try to be compatible, but as far as we tested, the PCI
passthrough feature using the traditional pci-stub + kvm approach is
buggy and not mature. So in this patch series, the back-end provides a
capability in /config/capabilities for the front-end to check, and then
freezes PCI passthrough web UI in this case. Didn't test on SuSe, just
because the author could not find a physical SuSe server. The patches
should work on SuSe as long as it provides the dependencies.
Secondly, there is 2 changes in PCI device filtering. Previously, we
only allowed to assign the "leaf" devices to guest. For example,
instead of assigning a USB controller, we assign the connected USB
device. We also made a PCI device whitelist according to the class
code. After some tests, we find that it's hardly useful if we only
allow "leaf" device, because in many cases the user wants to assign a
parent device. For example, the user may want to assign an HBA card to
guest, while there are many children LUNs under this card. The PCI
device code is also not a good way for checking if a device is suitable
to be passed through. There are too many vendors and devices, you'll
always find some "good" devices are out of the whitelist, and if we
grant the relared class code, it'll introduce "bad" devices.
So in this patch we just filter out video cards and PCI bridges. They
are not for passthrough absolutely. We also allow to passthrough a
parent device. The back-end provides API to check the affected devices
if you passthrough a particular one. The affected devices are the
devices in the same iommu group and their children devices.
As regard to the front-end, we only implemented PCI device passthrough,
PCI devices are the mostly useful and interesting devices to passthrough.
The back-end actually supports passing through LUNs and USB devices.
To test the patches, firstly reboot your host os, enable vt-d in BIOS.
Before loading Linux kernel, append "intel_iommu=on" to kernel
arguments. If you want to make it persistent, edit "grub.conf" and
append it. Then just apply the patch, start Kimchi daemon, edit a
shutdown guest, you'll see "Host PCI Device" tab. In the listing,
select "To Add", then click "+" besides one of the device. You'll find
PCI devices in the same group are also added. Then close the dialogue
and start the guest. In guest OS, "lspci" can show you the passthrough
devices.
In future, we plan to add more helpful information to assist user. For
example, when the user selects an NIC card, the front-end shows the
configured IP address. When the user selects an HBA card, the front-end
shows the related block devices such as sda sdb ... So the user can
avoid assigning a device in use by the host.
Yu Xin Huo (1):
Host device passthrough (Front-end): Add PCI Devices to VM
Zhou Zheng Sheng (5):
Host device passthrough: List all types of host devices
Host device passthrough: List eligible device to passthrough
Host device passthrough: Directly assign and dissmis host device from
VM
Host device passthrough: List VMs that are holding a host device
Host device passthrough: Add unit tests and documents
docs/API.md | 66 ++++++-
src/kimchi/API.json | 31 +++
src/kimchi/control/host.py | 7 +
src/kimchi/control/vm/hostdevs.py | 44 +++++
src/kimchi/featuretests.py | 10 +-
src/kimchi/i18n.py | 8 +
src/kimchi/mockmodel.py | 127 +++++++++++-
src/kimchi/model/config.py | 6 +-
src/kimchi/model/host.py | 48 +++--
src/kimchi/model/hostdev.py | 351 +++++++++++++++++++++++++++++++++
src/kimchi/model/libvirtstoragepool.py | 18 +-
src/kimchi/model/vmhostdevs.py | 324 ++++++++++++++++++++++++++++++
src/kimchi/rollbackcontext.py | 3 +
src/kimchi/xmlutils.py | 26 ++-
tests/test_model.py | 31 +++
tests/test_rest.py | 12 +-
tests/test_storagepool.py | 7 +-
ui/css/theme-default/guest-edit.css | 86 +++++++-
ui/js/src/kimchi.api.js | 55 ++++++
ui/js/src/kimchi.guest_edit_main.js | 81 ++++++++
ui/pages/guest-edit.html.tmpl | 28 +++
21 files changed, 1312 insertions(+), 57 deletions(-)
create mode 100644 src/kimchi/control/vm/hostdevs.py
create mode 100644 src/kimchi/model/hostdev.py
create mode 100644 src/kimchi/model/vmhostdevs.py
--
1.9.3
10 years, 2 months
[PATCHv5 0/2] Repository related fixes
by lvroyce@linux.vnet.ibm.com
From: Royce Lv <lvroyce(a)linux.vnet.ibm.com>
v3>v5,
fixed style error.
Royce Lv (2):
Fix: Avoid passing unexpected config params to repository manager
Fix: Add rollback to update repository
src/kimchi/API.json | 2 +-
src/kimchi/i18n.py | 1 +
src/kimchi/repositories.py | 40 +++++++++++++++++++++++++---------------
tests/test_model.py | 10 ++++++++--
4 files changed, 35 insertions(+), 18 deletions(-)
--
1.8.3.2
10 years, 2 months
[PATCH] Bug 440 Fix
by huoyuxin@linux.vnet.ibm.com
From: Yu Xin Huo <huoyuxin(a)linux.vnet.ibm.com>
2 Issues:
1. In menu widget, it handle the passin params incorrectly.
2. Filter out storage pools without any available volume.
Signed-off-by: Yu Xin Huo <huoyuxin(a)linux.vnet.ibm.com>
---
ui/js/src/kimchi.guest_storage_add.main.js | 2 +-
ui/js/widgets/select-menu.js | 6 +++---
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/ui/js/src/kimchi.guest_storage_add.main.js b/ui/js/src/kimchi.guest_storage_add.main.js
index a8c5acb..6e01d3e 100644
--- a/ui/js/src/kimchi.guest_storage_add.main.js
+++ b/ui/js/src/kimchi.guest_storage_add.main.js
@@ -61,7 +61,7 @@ kimchi.guest_storage_add_main = function() {
var options = [];
if (result && result.length) {
$.each(result, function(index, storagePool) {
- if ((storagePool.state=="active") && (storagePool.type !== 'kimchi-iso')) {
+ if ((storagePool.state=="active") && (storagePool.type !== 'kimchi-iso') && storagePool.nr_volumes) {
options.push({
label: storagePool.name,
value: storagePool.name
diff --git a/ui/js/widgets/select-menu.js b/ui/js/widgets/select-menu.js
index ad53200..c4b0209 100644
--- a/ui/js/widgets/select-menu.js
+++ b/ui/js/widgets/select-menu.js
@@ -36,8 +36,10 @@
var selectedClass = 'active';
var itemTag = 'li';
var item;
+ that.listControl.find('li').remove();
+ that.label.text("");
+ that.target.val("");
if (options.length > 0) {
- that.listControl.find('li').remove();
$.each(options, function(index, option) {
item = $('<' + itemTag + '>' + option.label +'</' + itemTag + '>');
item.data('value', option.value);
@@ -58,8 +60,6 @@
that.target.change();
}
});
- } else {
- kimchi.message.error.code('KCHAPI6006E');
}
},
--
1.7.1
10 years, 2 months
[PATCH] pep8: Use blacklist instead of whitelist
by Crístian Viana
Currently, the command "make check-local" runs the PEP8 verification
rules only on files listed in a configuration files. New files must
still be added manually and not all files are being checked.
List the files which *shouldn't* be checked against the PEP8 rules instead
of listing the files which should be checked. Also, fix the errors on
those new files.
The blacklisted files are: src/kimchi/{i18n,websocket,websockify}.py.
Signed-off-by: Crístian Viana <vianac(a)linux.vnet.ibm.com>
---
Makefile.am | 48 ++-------------------------------------------
src/kimchi/__init__.py | 2 +-
src/kimchi/basemodel.py | 4 +++-
src/kimchi/netinfo.py | 2 +-
src/kimchi/screenshot.py | 17 +++++++++-------
src/kimchi/sslcert.py | 5 +++--
src/kimchi/vmdisks.py | 6 +++---
src/kimchi/vnc.py | 2 +-
src/kimchi/xmlutils.py | 2 +-
tests/test_authorization.py | 20 +++++++++++--------
tests/test_exception.py | 10 +++++-----
tests/test_server.py | 5 +----
tests/test_vmtemplate.py | 2 +-
13 files changed, 44 insertions(+), 81 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 3293d9e..c04ba32 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -38,51 +38,7 @@ EXTRA_DIST = \
$(NULL)
-# When fixing a file to conform with pep8, add it to the WL here.
-# So it will be checked from now on.
-PEP8_WHITELIST = \
- plugins/__init__.py \
- plugins/sample/__init__.py \
- plugins/sample/model.py \
- src/kimchid.in \
- src/kimchi/asynctask.py \
- src/kimchi/auth.py \
- src/kimchi/cachebust.py \
- src/kimchi/config.py.in \
- src/kimchi/control/*.py \
- src/kimchi/control/vm/*.py \
- src/kimchi/disks.py \
- src/kimchi/distroloader.py \
- src/kimchi/exception.py \
- src/kimchi/featuretests.py \
- src/kimchi/imageinfo.py \
- src/kimchi/iscsi.py \
- src/kimchi/isoinfo.py \
- src/kimchi/kvmusertests.py \
- src/kimchi/mockmodel.py \
- src/kimchi/model/*.py \
- src/kimchi/objectstore.py \
- src/kimchi/osinfo.py \
- src/kimchi/proxy.py \
- src/kimchi/repositories.py \
- src/kimchi/rollbackcontext.py \
- src/kimchi/root.py \
- src/kimchi/scan.py \
- src/kimchi/server.py \
- src/kimchi/swupdate.py \
- src/kimchi/template.py \
- src/kimchi/utils.py \
- src/kimchi/vmtemplate.py \
- tests/test_config.py.in \
- tests/test_mockmodel.py \
- tests/test_model.py \
- tests/test_osinfo.py \
- tests/test_plugin.py \
- tests/test_rest.py \
- tests/test_rollbackcontext.py \
- tests/test_storagepool.py \
- tests/utils.py \
- $(NULL)
+PEP8_BLACKLIST = "src/kimchi/i18n.py,src/kimchi/websocket.py,src/kimchi/websockify.py"
SKIP_PYFLAKES_ERR = "\./src/kimchi/websocket\.py"
@@ -98,7 +54,7 @@ check-local:
while read LINE; do echo "$$LINE"; false; done
$(PEP8) --version
- $(PEP8) --filename '*.py,*.py.in' $(PEP8_WHITELIST)
+ $(PEP8) --filename '*.py,*.py.in' --exclude="$(PEP8_BLACKLIST)" .
# Link built mo files in the source tree to enable use of translations from
diff --git a/src/kimchi/__init__.py b/src/kimchi/__init__.py
index 1237e99..edf8e5d 100644
--- a/src/kimchi/__init__.py
+++ b/src/kimchi/__init__.py
@@ -15,4 +15,4 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
diff --git a/src/kimchi/basemodel.py b/src/kimchi/basemodel.py
index 93aab0c..096c66b 100644
--- a/src/kimchi/basemodel.py
+++ b/src/kimchi/basemodel.py
@@ -46,7 +46,9 @@ class BaseModel(object):
class Singleton(type):
_instances = {}
+
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
- cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
+ inst = super(Singleton, cls).__call__(*args, **kwargs)
+ cls._instances[cls] = inst
return cls._instances[cls]
diff --git a/src/kimchi/netinfo.py b/src/kimchi/netinfo.py
index 2eaf4ac..bb50479 100644
--- a/src/kimchi/netinfo.py
+++ b/src/kimchi/netinfo.py
@@ -185,7 +185,7 @@ def get_interface_type(iface):
def get_interface_info(iface):
- if not iface in ethtool.get_devices():
+ if iface not in ethtool.get_devices():
raise ValueError('unknown interface: %s' % iface)
ipaddr = ''
diff --git a/src/kimchi/screenshot.py b/src/kimchi/screenshot.py
index 8528a39..e599d40 100644
--- a/src/kimchi/screenshot.py
+++ b/src/kimchi/screenshot.py
@@ -15,7 +15,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
import glob
@@ -39,6 +39,7 @@ from kimchi.utils import kimchi_log
(fd, pipe) = tempfile.mkstemp()
stream_test_result = None
+
class VMScreenshot(object):
OUTDATED_SECS = 5
THUMBNAIL_SIZE = (256, 256)
@@ -48,8 +49,9 @@ class VMScreenshot(object):
def __init__(self, args):
self.vm_uuid = args['uuid']
args.setdefault('thumbnail',
- os.path.join(config.get_screenshot_path(),
- '%s-%s.png' % (self.vm_uuid, str(uuid.uuid4()))))
+ os.path.join(config.get_screenshot_path(),
+ '%s-%s.png' %
+ (self.vm_uuid, str(uuid.uuid4()))))
self.info = args
@staticmethod
@@ -66,8 +68,8 @@ class VMScreenshot(object):
if now - last_update > self.OUTDATED_SECS:
self._clean_extra(self.LIVE_WINDOW)
self._generate_thumbnail()
- return '/data/screenshots/%s' % os.path.basename(self.info['thumbnail'])
-
+ return '/data/screenshots/%s' %\
+ os.path.basename(self.info['thumbnail'])
def _clean_extra(self, window=-1):
"""
@@ -77,7 +79,8 @@ class VMScreenshot(object):
try:
now = time.time()
clear_list = glob.glob("%s/%s-*.png" %
- (config.get_screenshot_path(), self.vm_uuid))
+ (config.get_screenshot_path(),
+ self.vm_uuid))
for f in clear_list:
if now - os.path.getmtime(f) > window:
os.unlink(f)
@@ -122,7 +125,7 @@ class VMScreenshot(object):
else:
counter = 0
ret = os.waitpid(pid, os.WNOHANG)
- while ret == (0,0) and counter < 3:
+ while ret == (0, 0) and counter < 3:
counter += 1
time.sleep(1)
ret = os.waitpid(pid, os.WNOHANG)
diff --git a/src/kimchi/sslcert.py b/src/kimchi/sslcert.py
index bf4d261..e772dc8 100644
--- a/src/kimchi/sslcert.py
+++ b/src/kimchi/sslcert.py
@@ -19,7 +19,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import time
@@ -34,6 +34,7 @@ class SSLCert(object):
def _gen(self):
def keygen_cb(*args):
pass
+
def passphrase_cb(*args):
return ''
@@ -54,7 +55,6 @@ class SSLCert(object):
subject.CN = 'kimchi'
subject.O = 'kimchi-project.org'
-
t = long(time.time()) + time.timezone
now = ASN1.ASN1_UTCTIME()
now.set_time(t)
@@ -80,6 +80,7 @@ class SSLCert(object):
def key_pem(self):
return self._key
+
def main():
c = SSLCert()
print c.cert_text()
diff --git a/src/kimchi/vmdisks.py b/src/kimchi/vmdisks.py
index b61c883..f1c3f02 100644
--- a/src/kimchi/vmdisks.py
+++ b/src/kimchi/vmdisks.py
@@ -39,9 +39,9 @@ def get_vm_disk(dom, dev_name):
# Retrieve disk xml and format return dict
disk = get_device_xml(dom, dev_name)
if disk is None:
- raise NotFoundError(
- "KCHVMSTOR0007E",
- {'dev_name': dev_name, 'vm_name': dom.name()})
+ raise NotFoundError("KCHVMSTOR0007E",
+ {'dev_name': dev_name,
+ 'vm_name': dom.name()})
path = ""
dev_bus = disk.target.attrib['bus']
try:
diff --git a/src/kimchi/vnc.py b/src/kimchi/vnc.py
index cfa7c6d..09a4cad 100644
--- a/src/kimchi/vnc.py
+++ b/src/kimchi/vnc.py
@@ -16,7 +16,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import base64
import errno
diff --git a/src/kimchi/xmlutils.py b/src/kimchi/xmlutils.py
index 8612e66..d3db32a 100644
--- a/src/kimchi/xmlutils.py
+++ b/src/kimchi/xmlutils.py
@@ -26,7 +26,7 @@ from xml.etree import ElementTree
def xpath_get_text(xml, expr):
doc = libxml2.parseDoc(xml)
res = doc.xpathEval(expr)
- ret = [None if x.children == None else x.children.content for x in res]
+ ret = [None if x.children is None else x.children.content for x in res]
doc.freeDoc()
return ret
diff --git a/tests/test_authorization.py b/tests/test_authorization.py
index 2c342a5..71b416f 100644
--- a/tests/test_authorization.py
+++ b/tests/test_authorization.py
@@ -40,7 +40,7 @@ ssl_port = None
def setUpModule():
global test_server, model, host, port, ssl_port
- patch_auth(sudo = False)
+ patch_auth(sudo=False)
model = kimchi.mockmodel.MockModel('/tmp/obj-store-test')
host = '127.0.0.1'
port = get_free_port('http')
@@ -111,23 +111,27 @@ class AuthorizationTests(unittest.TestCase):
resp = self.request('/templates/test', '{}', 'DELETE')
self.assertEquals(403, resp.status)
-
# Non-root users can only get vms authorized to them
model.templates_create({'name': u'test', 'cdrom': '/nonexistent.iso'})
model.vms_create({'name': u'test-me', 'template': '/templates/test'})
- model.vm_update(u'test-me', {'users': [ kimchi.mockmodel.fake_user.keys()[0] ], 'groups': []})
+ model.vm_update(u'test-me',
+ {'users': [kimchi.mockmodel.fake_user.keys()[0]],
+ 'groups': []})
- model.vms_create({'name': u'test-usera', 'template': '/templates/test'})
- model.vm_update(u'test-usera', {'users': [ 'userA' ], 'groups': []})
+ model.vms_create({'name': u'test-usera',
+ 'template': '/templates/test'})
+ model.vm_update(u'test-usera', {'users': ['userA'], 'groups': []})
- model.vms_create({'name': u'test-groupa', 'template': '/templates/test'})
- model.vm_update(u'test-groupa', {'groups': [ 'groupA' ]})
+ model.vms_create({'name': u'test-groupa',
+ 'template': '/templates/test'})
+ model.vm_update(u'test-groupa', {'groups': ['groupA']})
resp = self.request('/vms', '{}', 'GET')
self.assertEquals(200, resp.status)
vms_data = json.loads(resp.read())
- self.assertEquals([ u'test-groupa', u'test-me' ], sorted([ v['name'] for v in vms_data ]))
+ self.assertEquals([u'test-groupa', u'test-me'],
+ sorted([v['name'] for v in vms_data]))
resp = self.request('/vms', req, 'POST')
self.assertEquals(403, resp.status)
diff --git a/tests/test_exception.py b/tests/test_exception.py
index 90c1ea1..a533015 100644
--- a/tests/test_exception.py
+++ b/tests/test_exception.py
@@ -15,7 +15,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import json
import os
@@ -77,8 +77,8 @@ class ExceptionTests(unittest.TestCase):
req = json.dumps({})
resp = json.loads(request(host, ssl_port, '/vms', req, 'POST').read())
self.assertEquals('400 Bad Request', resp.get('code'))
- msg = u"KCHVM0016E: Specify a template to create a virtual machine from"
- self.assertEquals(msg, resp.get('reason'))
+ m = u"KCHVM0016E: Specify a template to create a virtual machine from"
+ self.assertEquals(m, resp.get('reason'))
self.assertNotIn('call_stack', resp)
def test_development_env(self):
@@ -106,7 +106,7 @@ class ExceptionTests(unittest.TestCase):
# test 400 missing required parameter
req = json.dumps({})
resp = json.loads(request(host, ssl_port, '/vms', req, 'POST').read())
- msg = u"KCHVM0016E: Specify a template to create a virtual machine from"
+ m = u"KCHVM0016E: Specify a template to create a virtual machine from"
self.assertEquals('400 Bad Request', resp.get('code'))
- self.assertEquals(msg, resp.get('reason'))
+ self.assertEquals(m, resp.get('reason'))
self.assertIn('call_stack', resp)
diff --git a/tests/test_server.py b/tests/test_server.py
index 9beba6c..bebc383 100644
--- a/tests/test_server.py
+++ b/tests/test_server.py
@@ -15,7 +15,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import os
import unittest
@@ -24,7 +24,6 @@ import unittest
import utils
import kimchi.mockmodel
-#utils.silence_server()
class ServerTests(unittest.TestCase):
def test_server_start(self):
@@ -44,5 +43,3 @@ class ServerTests(unittest.TestCase):
finally:
os.unlink('/tmp/obj-store-test')
s.stop()
-
-
diff --git a/tests/test_vmtemplate.py b/tests/test_vmtemplate.py
index 4ae1d36..2a6fb8e 100644
--- a/tests/test_vmtemplate.py
+++ b/tests/test_vmtemplate.py
@@ -15,7 +15,7 @@
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import os
import unittest
--
1.9.3
10 years, 2 months