[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
[PATCH v2 0/2] pep8: Fix errors
by Crístian Viana
This is the difference between this and the previous patchset (v1):
- Add the files *config.py to the PEP8 blacklist.
- Split the previous patch into two separate patches: one which fixes
all the files and another one which enables PEP8 for every file except
the ones blacklisted.
Crístian Viana (2):
pep8: Fix errors in all files
pep8: Use blacklist instead of whitelist
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(-)
--
1.9.3
10 years, 2 months
[PATCH 0/2] Delete imported novnc code
by Aline Manera
Aline Manera (2):
Add novnc as Kimchi dependency
Delete imported novnc code
Makefile.am | 8 +-
configure.ac | 17 -
contrib/DEBIAN/control.in | 1 +
contrib/kimchi.spec.fedora.in | 18 +-
contrib/kimchi.spec.suse.in | 18 +-
docs/README.md | 7 +-
src/kimchi/Makefile.am | 1 +
src/kimchi/config.py.in | 14 +-
tests/Makefile.am | 1 +
tests/test_config.py.in | 14 +-
ui/css/Makefile.am | 6 +-
ui/css/fonts/Makefile.am | 18 -
ui/css/fonts/novnc/Makefile.am | 20 -
ui/css/fonts/novnc/Orbitron700.ttf | Bin 38580 -> 0 bytes
ui/css/fonts/novnc/Orbitron700.woff | Bin 17472 -> 0 bytes
ui/css/novnc/Makefile.am | 20 -
ui/css/novnc/base.css | 405 ------
ui/js/Makefile.am | 2 +-
ui/js/novnc/Makefile.am | 22 -
ui/js/novnc/base64.js | 115 --
ui/js/novnc/des.js | 273 ----
ui/js/novnc/display.js | 770 -----------
ui/js/novnc/input.js | 1946 ---------------------------
ui/js/novnc/jsunzip.js | 676 ----------
ui/js/novnc/main.js | 103 --
ui/js/novnc/rfb.js | 1866 -------------------------
ui/js/novnc/util.js | 381 ------
ui/js/novnc/web-socket-js/Makefile.am | 24 -
ui/js/novnc/web-socket-js/README.txt | 109 --
ui/js/novnc/web-socket-js/WebSocketMain.swf | Bin 177114 -> 0 bytes
ui/js/novnc/web-socket-js/swfobject.js | 4 -
ui/js/novnc/web-socket-js/web_socket.js | 391 ------
ui/js/novnc/websock.js | 422 ------
ui/js/novnc/webutil.js | 216 ---
ui/js/src/kimchi.api.js | 3 +-
ui/pages/vnc_auto.html.tmpl | 44 -
ui/pages/websockify/console.html | 2 +-
37 files changed, 41 insertions(+), 7896 deletions(-)
delete mode 100644 ui/css/fonts/Makefile.am
delete mode 100644 ui/css/fonts/novnc/Makefile.am
delete mode 100644 ui/css/fonts/novnc/Orbitron700.ttf
delete mode 100644 ui/css/fonts/novnc/Orbitron700.woff
delete mode 100644 ui/css/novnc/Makefile.am
delete mode 100644 ui/css/novnc/base.css
delete mode 100644 ui/js/novnc/Makefile.am
delete mode 100644 ui/js/novnc/base64.js
delete mode 100644 ui/js/novnc/des.js
delete mode 100644 ui/js/novnc/display.js
delete mode 100644 ui/js/novnc/input.js
delete mode 100755 ui/js/novnc/jsunzip.js
delete mode 100644 ui/js/novnc/main.js
delete mode 100644 ui/js/novnc/rfb.js
delete mode 100644 ui/js/novnc/util.js
delete mode 100644 ui/js/novnc/web-socket-js/Makefile.am
delete mode 100644 ui/js/novnc/web-socket-js/README.txt
delete mode 100644 ui/js/novnc/web-socket-js/WebSocketMain.swf
delete mode 100644 ui/js/novnc/web-socket-js/swfobject.js
delete mode 100644 ui/js/novnc/web-socket-js/web_socket.js
delete mode 100644 ui/js/novnc/websock.js
delete mode 100644 ui/js/novnc/webutil.js
delete mode 100644 ui/pages/vnc_auto.html.tmpl
--
1.9.3
10 years, 2 months
[PATCH] Remove static qemu URIs and add function to lookup the system URI
by bbaude@redhat.com
From: Brent Baude <bbaude(a)redhat.com>
This patch removes the static QEMU URIs that are defined and replaces
them with a function to lookup the system URI. This helps Kimchi work
with a remote libvirtd.
---
src/kimchi/config.py.in | 4 ++--
src/kimchi/featuretests.py | 10 +++++-----
src/kimchi/kvmusertests.py | 3 ++-
src/kimchi/model/libvirtconnection.py | 25 +++++++++++++++++++++++++
src/kimchi/model/model.py | 6 +++---
src/kimchi/model/networks.py | 2 +-
tests/test_model.py | 17 +++++++++--------
7 files changed, 47 insertions(+), 20 deletions(-)
diff --git a/src/kimchi/config.py.in b/src/kimchi/config.py.in
index 91e5f48..51cd442 100644
--- a/src/kimchi/config.py.in
+++ b/src/kimchi/config.py.in
@@ -23,7 +23,6 @@ import os
import platform
import threading
-
from ConfigParser import SafeConfigParser
@@ -61,8 +60,9 @@ def get_version():
def find_qemu_binary(find_emulator=False):
+ from kimchi.model.libvirtconnection import LibvirtConnection
try:
- connect = libvirt.open('qemu:///system')
+ connect = libvirt.open(LibvirtConnection.getSystemURI())
except Exception, e:
raise Exception("Unable to get qemu binary location: %s" % e)
try:
diff --git a/src/kimchi/featuretests.py b/src/kimchi/featuretests.py
index 8964098..a2a942b 100644
--- a/src/kimchi/featuretests.py
+++ b/src/kimchi/featuretests.py
@@ -27,7 +27,7 @@ import threading
from lxml.builder import E
-
+from kimchi.model.libvirtconnection import LibvirtConnection
from kimchi.rollbackcontext import RollbackContext
from kimchi.utils import kimchi_log
@@ -104,7 +104,7 @@ class FeatureTests(object):
conn = None
try:
FeatureTests.disable_screen_error_logging()
- conn = libvirt.open('qemu:///system')
+ conn = libvirt.open(LibvirtConnection.getSystemURI())
dom = conn.defineXML(xml)
dom.undefine()
return True
@@ -122,7 +122,7 @@ class FeatureTests(object):
xml = ET.tostring(obj)
return xml
try:
- conn = libvirt.open('qemu:///system')
+ conn = libvirt.open(LibvirtConnection.getSystemURI())
FeatureTests.disable_screen_error_logging()
conn.findStoragePoolSources('netfs', _get_xml(), 0)
except libvirt.libvirtError as e:
@@ -174,7 +174,7 @@ class FeatureTests(object):
def libvirt_support_fc_host():
try:
FeatureTests.disable_screen_error_logging()
- conn = libvirt.open('qemu:///system')
+ conn = libvirt.open(LibvirtConnection.getSystemURI())
pool = None
pool = conn.storagePoolDefineXML(SCSI_FC_XML, 0)
except libvirt.libvirtError as e:
@@ -194,7 +194,7 @@ class FeatureTests(object):
with RollbackContext() as rollback:
FeatureTests.disable_screen_error_logging()
rollback.prependDefer(FeatureTests.enable_screen_error_logging)
- conn = libvirt.open('qemu:///system')
+ conn = libvirt.open(LibvirtConnection.getSystemURI())
rollback.prependDefer(conn.close)
dom = conn.defineXML(SIMPLE_VM_XML)
rollback.prependDefer(dom.undefine)
diff --git a/src/kimchi/kvmusertests.py b/src/kimchi/kvmusertests.py
index 1ac2beb..ae1df25 100644
--- a/src/kimchi/kvmusertests.py
+++ b/src/kimchi/kvmusertests.py
@@ -24,6 +24,7 @@ import libvirt
from kimchi.rollbackcontext import RollbackContext
+from kimchi.model.libvirtconnection import LibvirtConnection
class UserTests(object):
@@ -49,7 +50,7 @@ class UserTests(object):
xml = cls.SIMPLE_VM_XML % (vm_name, vm_uuid)
with RollbackContext() as rollback:
- conn = libvirt.open('qemu:///system')
+ conn = libvirt.open(LibvirtConnection.getSystemURI())
rollback.prependDefer(conn.close)
dom = conn.defineXML(xml)
rollback.prependDefer(dom.undefine)
diff --git a/src/kimchi/model/libvirtconnection.py b/src/kimchi/model/libvirtconnection.py
index 80348a3..bac276f 100644
--- a/src/kimchi/model/libvirtconnection.py
+++ b/src/kimchi/model/libvirtconnection.py
@@ -117,3 +117,28 @@ class LibvirtConnection(object):
# However the values need to be considered wisely to not affect
# hosts which are hosting a lot of virtual machines
return conn
+
+ @staticmethod
+ def getSystemURI():
+ """
+ This method looks up the livbirt URI for the system instead of
+ relying on a statically defined URI.
+ """
+ try:
+ uriconn = libvirt.openReadOnly(None)
+ return uriconn.getURI()
+ except:
+ err = 'Unable to connect to libvirtd to determine the URI'
+ kimchi_log.error(err)
+
+ @staticmethod
+ def isQemuURI(libvirt_uri):
+ """
+ This method will return True or Value when the system libvirt
+ URI is a qemu based URI. For example:
+ qemu:///system or qemu+tcp://someipaddress/system
+ """
+ if libvirt_uri.startswith('qemu'):
+ return True
+ else:
+ return False
diff --git a/src/kimchi/model/model.py b/src/kimchi/model/model.py
index ac70852..b8b2f9d 100644
--- a/src/kimchi/model/model.py
+++ b/src/kimchi/model/model.py
@@ -38,12 +38,12 @@ DEFAULT_POOLS = {'default': {'path': '/var/lib/libvirt/images'},
class Model(BaseModel):
- def __init__(self, libvirt_uri='qemu:///system', objstore_loc=None):
+ def __init__(self, libvirt_uri=LibvirtConnection.getSystemURI(),
+ objstore_loc=None):
self.objstore = ObjectStore(objstore_loc)
self.conn = LibvirtConnection(libvirt_uri)
kargs = {'objstore': self.objstore, 'conn': self.conn}
-
- if 'qemu:///' in libvirt_uri:
+ if (self.conn.isQemuURI(libvirt_uri)):
for pool_name, pool_arg in DEFAULT_POOLS.iteritems():
self._default_pool_check(pool_name, pool_arg)
diff --git a/src/kimchi/model/networks.py b/src/kimchi/model/networks.py
index 0ea9449..f01bed0 100644
--- a/src/kimchi/model/networks.py
+++ b/src/kimchi/model/networks.py
@@ -41,7 +41,7 @@ KIMCHI_BRIDGE_PREFIX = 'kb'
class NetworksModel(object):
def __init__(self, **kargs):
self.conn = kargs['conn']
- if 'qemu:///' in self.conn.get().getURI():
+ if self.conn.isQemuURI(self.conn.get().getURI()):
self._default_network_check()
def _default_network_check(self):
diff --git a/tests/test_model.py b/tests/test_model.py
index 1f2e79c..e23acf3 100644
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -44,6 +44,7 @@ from kimchi.model import model
from kimchi.rollbackcontext import RollbackContext
from kimchi.utils import add_task
+from kimchi.model.libvirtconnection import LibvirtConnection
invalid_repository_urls = ['www.fedora.org', # missing protocol
'://www.fedora.org', # missing protocol
@@ -457,7 +458,7 @@ class ModelTests(unittest.TestCase):
@unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
def test_storagepool(self):
- inst = model.Model('qemu:///system', self.tmp_store)
+ inst = model.Model(LibvirtConnection.getSystemURI(), self.tmp_store)
poolDefs = [
{'type': 'dir',
@@ -524,7 +525,7 @@ class ModelTests(unittest.TestCase):
@unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
def test_storagevolume(self):
- inst = model.Model('qemu:///system', self.tmp_store)
+ inst = model.Model(LibvirtConnection.getSystemURI(), self.tmp_store)
with RollbackContext() as rollback:
path = '/tmp/kimchi-images'
@@ -742,7 +743,7 @@ class ModelTests(unittest.TestCase):
@unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
def test_template_clone(self):
- inst = model.Model('qemu:///system',
+ inst = model.Model(LibvirtConnection.getSystemURI(),
objstore_loc=self.tmp_store)
with RollbackContext() as rollback:
orig_params = {'name': 'test-template', 'memory': 1024,
@@ -761,7 +762,7 @@ class ModelTests(unittest.TestCase):
@unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
def test_template_update(self):
- inst = model.Model('qemu:///system',
+ inst = model.Model(LibvirtConnection.getSystemURI(),
objstore_loc=self.tmp_store)
with RollbackContext() as rollback:
net_name = 'test-network'
@@ -801,7 +802,7 @@ class ModelTests(unittest.TestCase):
'new-test', params)
def test_vm_edit(self):
- inst = model.Model('qemu:///system',
+ inst = model.Model(LibvirtConnection.getSystemURI(),
objstore_loc=self.tmp_store)
orig_params = {'name': 'test', 'memory': '1024', 'cpus': '1',
@@ -914,7 +915,7 @@ class ModelTests(unittest.TestCase):
@unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
def test_network(self):
- inst = model.Model('qemu:///system', self.tmp_store)
+ inst = model.Model(LibvirtConnection.getSystemURI(), self.tmp_store)
with RollbackContext() as rollback:
@@ -1240,7 +1241,7 @@ class ModelTests(unittest.TestCase):
@unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
def test_get_hostinfo(self):
- inst = model.Model('qemu:///system',
+ inst = model.Model(LibvirtConnection.getSystemURI(),
objstore_loc=self.tmp_store)
info = inst.host_lookup()
distro, version, codename = platform.linux_distribution()
@@ -1279,7 +1280,7 @@ class ModelTests(unittest.TestCase):
@unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
def test_deep_scan(self):
- inst = model.Model('qemu:///system',
+ inst = model.Model(LibvirtConnection.getSystemURI(),
objstore_loc=self.tmp_store)
with RollbackContext() as rollback:
path = '/tmp/kimchi-images/tmpdir'
--
1.9.3
10 years, 2 months
Why do we use mockmodel?
by Crístian Viana
Hi!
After creating a few patches for Kimchi, it occurred to me that the
mockmodel design has more cons than pros. So I started wondering why we
still use it.
I understand - and totally agree - that we should have an extensive test
infrastructure to make sure the code runs as designed and to make it
very easy to find regression bugs on every new feature we implement. And
as Kimchi works very integrated to its host system, it may not be easy
to create expected/failed situations for things we don't always have
control.
But for every new feature we implement, we currently have to:
1) Implement the feature itself
2) Create tests for (1)
3) Implement the feature in a mock environment
4) Create tests for (3)
And by looking at some existing code, many of the mock tests don't
actually test anything. They're just there so we can say we have a mock
implementation and a test for it. Why create a mock function and a test
for the mock function if what we need is to test the real code? And a
lot of times, the mock implementation (and the tests) are just
copy/paste of the original feature. For me, that seems very tedious and
useless.
Why don't we get rid of the mockmodel and keep only the "real" model? I
understand that it's not so simple to remove it right away, that's why
I'm starting this discussion so we could see how to do it better - if
we're actually going to do it. What would we miss if we didn't have the
mockmodel anymore? I believe we'll need to be more careful when writing
tests which run on a real environment (i.e. we can't "leak" VMs,
networks, templates, or anything else) but at least we'll always test
real code and we won't be writing code that won't be used.
Please share your opinion with us.
Best regards,
Crístian.
10 years, 2 months
[PATCH] Display "README" with markdown style on Github
by Crístian Viana
The file "README" is a markdown file but as it doesn't have the suffix
".md", Github doesn't render it with markdown style.
Rename the symlink "README" in order to be displayed with markdown style
on Github.
Signed-off-by: Crístian Viana <vianac(a)linux.vnet.ibm.com>
---
README | 1 -
README.md | 1 +
2 files changed, 1 insertion(+), 1 deletion(-)
delete mode 120000 README
create mode 120000 README.md
diff --git a/README b/README
deleted file mode 120000
index 0e01b43..0000000
--- a/README
+++ /dev/null
@@ -1 +0,0 @@
-docs/README.md
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 120000
index 0000000..0e01b43
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+docs/README.md
\ No newline at end of file
--
1.9.3
10 years, 2 months
[PATCH] Backend support for templates with sockets, cores, and threads
by Christy Perez
In order to allow a guest to use SMT/hyperthreading, we should
enable passing in of the sockets, cores, and threads values when
creating a template.
All three values must be specified, as per the topology descr at
http://libvirt.org/formatdomain.html#elementsCPU
Signed-off-by: Christy Perez <christy(a)linux.vnet.ibm.com>
---
docs/API.md | 7 +++++++
src/kimchi/API.json | 28 ++++++++++++++++++++++++++--
src/kimchi/control/templates.py | 11 ++++++++---
src/kimchi/osinfo.py | 2 +-
src/kimchi/vmtemplate.py | 22 ++++++++++++++++++++++
5 files changed, 64 insertions(+), 6 deletions(-)
diff --git a/docs/API.md b/docs/API.md
index d75c55f..cb4d541 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -200,6 +200,13 @@ Represents a snapshot of the Virtual Machine's primary monitor.
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.
+ * topology: Specify sockets, threads, and cores to run the virtual CPU
+ threads on.
+ All three are required in order to specify cpu topology.
+ * sockets - The number of sockets to use.
+ * cores - The number of cores per socket.
+ * threads - The number of threads per core.
### Sub-Collection: Virtual Machine Network Interfaces
diff --git a/src/kimchi/API.json b/src/kimchi/API.json
index c3fc5e3..d510634 100644
--- a/src/kimchi/API.json
+++ b/src/kimchi/API.json
@@ -26,6 +26,28 @@
]
}
}
+ },
+ "cpu_info": {
+ "description": "Configure CPU specifics for a VM.",
+ "type": "object",
+ "properties": {
+ "topology": {
+ "description": "Configure the guest CPU topology.",
+ "type": "object",
+ "properties": {
+ "sockets": {
+ "type": "number"
+ },
+ "cores": {
+ "type": "number"
+ },
+ "threads": {
+ "type": "number"
+ }
+ },
+ "required": [ "sockets", "cores", "threads" ]
+ }
+ }
}
},
"properties": {
@@ -438,7 +460,8 @@
"type": "array",
"items": { "type": "string" }
},
- "graphics": { "$ref": "#/kimchitype/graphics" }
+ "graphics": { "$ref": "#/kimchitype/graphics" },
+ "cpu_info": { "$ref": "#/kimchitype/cpu_info" }
},
"additionalProperties": false,
"error": "KCHAPI0001E"
@@ -608,7 +631,8 @@
"type": "array",
"items": { "type": "string" }
},
- "graphics": { "$ref": "#/kimchitype/graphics" }
+ "graphics": { "$ref": "#/kimchitype/graphics" },
+ "cpu_info": { "$ref": "#/kimchitype/cpu_info" }
},
"additionalProperties": false,
"error": "KCHAPI0001E"
diff --git a/src/kimchi/control/templates.py b/src/kimchi/control/templates.py
index e17fa54..5ef35ce 100644
--- a/src/kimchi/control/templates.py
+++ b/src/kimchi/control/templates.py
@@ -38,13 +38,14 @@ def __init__(self, model, ident):
self.update_params = ["name", "folder", "icon", "os_distro",
"storagepool", "os_version", "cpus",
"memory", "cdrom", "disks", "networks",
- "graphics"]
+ "graphics", "cpu_info"]
self.uri_fmt = "/templates/%s"
self.clone = self.generate_action_handler('clone')
@property
def data(self):
- return {'name': self.ident,
+ return_data = {
+ 'name': self.ident,
'icon': self.info['icon'],
'invalid': self.info['invalid'],
'os_distro': self.info['os_distro'],
@@ -56,4 +57,8 @@ def data(self):
'storagepool': self.info['storagepool'],
'networks': self.info['networks'],
'folder': self.info.get('folder', []),
- 'graphics': self.info['graphics']}
+ 'graphics': self.info['graphics']
+ }
+ if (self.info.get('cpu_info')):
+ return_data['cpu_info'] = self.info['cpu_info']
+ return return_data
diff --git a/src/kimchi/osinfo.py b/src/kimchi/osinfo.py
index 1ad353c..8492bb7 100644
--- a/src/kimchi/osinfo.py
+++ b/src/kimchi/osinfo.py
@@ -32,7 +32,7 @@
'power': ('ppc', 'ppc64')}
-common_spec = {'cpus': 1, 'cpu_cores': 1, 'cpu_threads': 1, 'memory': 1024,
+common_spec = {'cpus': 1, 'cpu_sockets': '1', 'cpu_cores': 1, 'cpu_threads': 1, 'memory': 1024,
'disks': [{'index': 0, 'size': 10}], 'cdrom_bus': 'ide',
'cdrom_index': 2, 'mouse_bus': 'ps2'}
diff --git a/src/kimchi/vmtemplate.py b/src/kimchi/vmtemplate.py
index 761bac5..c64e61d 100644
--- a/src/kimchi/vmtemplate.py
+++ b/src/kimchi/vmtemplate.py
@@ -359,6 +359,22 @@ def _get_input_output_xml(self):
input_output += sound % self.info
return input_output
+ def _get_cpu_xml(self):
+
+ cpu_info = self.info.get('cpu_info')
+ if cpu_info is not None:
+ cpu_topo = cpu_info.get('topology')
+ if cpu_topo is not None:
+ return """
+ <cpu>
+ <topology sockets='%(sockets)s'
+ cores='%(cores)s'
+ threads='%(threads)s'/>
+ </cpu>
+ """ % cpu_topo
+
+ return ""
+
def to_vm_xml(self, vm_name, vm_uuid, **kwargs):
params = dict(self.info)
params['name'] = vm_name
@@ -371,6 +387,11 @@ def to_vm_xml(self, vm_name, vm_uuid, **kwargs):
graphics = kwargs.get('graphics')
params['graphics'] = self._get_graphics_xml(graphics)
+ if params.get('cpu_info') is not None:
+ params['cpu_info'] = self._get_cpu_xml()
+ else:
+ params['cpu_info'] = ''
+
# Current implementation just allows to create disk in one single
# storage pool, so we cannot mix the types (scsi volumes vs img file)
storage_type = self._get_storage_type()
@@ -401,6 +422,7 @@ def to_vm_xml(self, vm_name, vm_uuid, **kwargs):
<uuid>%(uuid)s</uuid>
<memory unit='MiB'>%(memory)s</memory>
<vcpu>%(cpus)s</vcpu>
+ %(cpu_info)s
<os>
<type arch='%(arch)s'>hvm</type>
<boot dev='hd'/>
--
1.9.3
10 years, 2 months
A question about iSCSI storage pool
by Yu Xin Huo
I got a iSCSI target to work on my redhat with a USB disk to test iSCSI
storage pool and found below:
1. When create a iSCSI storage pool, I selected a target in dropdown list.
2. Once the pool is created, I see a volume named 'unit:0:0:1'.
3. When edit template, in the 'storage pool' dropdown, 'unit:0:0:1' is
listed there.
So 'unit:0:0:1' which indeed is a *volume* but listed as a *pool* in
template? or something I am misunderstanding?
10 years, 2 months
Kimchi UI design proposals
by Don S. Spangler
I recently created a page on the Kimchi wiki (UI Design Proposals
<https://github.com/kimchi-project/kimchi/wiki/UI-Design-Proposals>)
around developing a set of UI design proposals with the following goals:
* Provide a complete user interface and visual style for all major
tabs and tasks
* Maintain clean design and interactions in keeping with Kimchi directions
* Design flexible framework to allow for consistency when adding new
capabilities
* Enable design to support responsiveness and touch / mobile (tablet /
phone) interactions
We plan on making iterative updates to the screens and would like to
open it up to feedback. The initial focus has been the major content
areas (host, guest, template, storage, and networks) and will be working
on details of the interactions, including page level blueprints. The
layouts to support responsiveness are particularly important and would
be part of the next updates.
We look forward to your feedback, including areas that may need more
clarification and issues around implementation.
Thanks!
Don Spangler
10 years, 2 months