[PATCH 00/15 V2] Reorganize controller module
by Aline Manera
From: Aline Manera <alinefm(a)br.ibm.com>
V1 -> V2:
- Remove 'instance' parameter from generate_action_handler()
- Update Makefile and spec files
- Remove controller content when it is moved to new files
- Update authors in new files
- Fix identation error while using pep8 1.4
- Other minor fixes
Aline Manera (15):
Move generate_action_handler() function to Resource() class
Move common functions for Resource and Collection to control/utils.py
Move login() and logout() functions from controller.py to root.py
Move basic controller resources to control/base.py
Move all resources related to vms to control/vms.py
Move all resources related to templates to control/templates.py
Move all resources related to debug reports to
control/debugreports.py
Move all resources related to storage pools to
control/storagepools.py
Move all resources related to storage volume to
control/storagevolumes.py
Move all resources related to interfaces to control/interfaces.py
Move all resources related to networks to control/networks.py
Move all resources related to config to control/config.py
Move all resources related to host to control/host.py
Move all resources related to plugins to control/plugins.py
Move all resources related to tasks to control/tasks.py
Makefile.am | 1 +
configure.ac | 1 +
contrib/kimchi.spec.fedora.in | 1 +
contrib/kimchi.spec.suse.in | 1 +
plugins/sample/__init__.py | 2 +-
src/kimchi/Makefile.am | 3 +-
src/kimchi/control/Makefile.am | 28 ++
src/kimchi/control/__init__.py | 21 +
src/kimchi/control/base.py | 292 +++++++++++++
src/kimchi/control/config.py | 69 ++++
src/kimchi/control/debugreports.py | 52 +++
src/kimchi/control/host.py | 63 +++
src/kimchi/control/interfaces.py | 45 ++
src/kimchi/control/networks.py | 48 +++
src/kimchi/control/plugins.py | 45 ++
src/kimchi/control/storagepools.py | 127 ++++++
src/kimchi/control/storagevolumes.py | 81 ++++
src/kimchi/control/tasks.py | 41 ++
src/kimchi/control/templates.py | 52 +++
src/kimchi/control/utils.py | 105 +++++
src/kimchi/control/vms.py | 65 +++
src/kimchi/controller.py | 755 ----------------------------------
src/kimchi/root.py | 62 ++-
tests/test_mockmodel.py | 6 +-
24 files changed, 1191 insertions(+), 775 deletions(-)
create mode 100644 src/kimchi/control/Makefile.am
create mode 100644 src/kimchi/control/__init__.py
create mode 100644 src/kimchi/control/base.py
create mode 100644 src/kimchi/control/config.py
create mode 100644 src/kimchi/control/debugreports.py
create mode 100644 src/kimchi/control/host.py
create mode 100644 src/kimchi/control/interfaces.py
create mode 100644 src/kimchi/control/networks.py
create mode 100644 src/kimchi/control/plugins.py
create mode 100644 src/kimchi/control/storagepools.py
create mode 100644 src/kimchi/control/storagevolumes.py
create mode 100644 src/kimchi/control/tasks.py
create mode 100644 src/kimchi/control/templates.py
create mode 100644 src/kimchi/control/utils.py
create mode 100644 src/kimchi/control/vms.py
delete mode 100644 src/kimchi/controller.py
--
1.7.10.4
10 years, 12 months
[PATCH V3 0/6] template supports networks
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
V2 -> V3
fix typo.
support creating a vm without network.
V1 -> V2:
update mockmodel and test case
add 'networks' option for template get/create/update
ShaoHe Feng (6):
template supports networks: let template xml support more networks
template supports networks: update API
template supports networks: update controller and json schema
template supports networks: update model
template supports networks: update mockmodel
template supports networks: update test case
docs/API.md | 4 +++
src/kimchi/API.json | 12 +++++++
src/kimchi/controller.py | 3 +-
src/kimchi/mockmodel.py | 7 +++-
src/kimchi/model.py | 6 ++++
src/kimchi/osinfo.py | 5 +--
src/kimchi/vmtemplate.py | 20 ++++++++---
tests/test_model.py | 86 +++++++++++++++++++++++++++++++++++++-----------
tests/test_rest.py | 56 +++++++++++++++++++++++++++++++
9 files changed, 172 insertions(+), 27 deletions(-)
--
1.8.4.2
10 years, 12 months
[PATCH 0/2] pep8 cleanup for featuretests.py and simplify domain xml
by Aline Manera
From: Aline Manera <alinefm(a)br.ibm.com>
Aline Manera (2):
pep8 cleanup for featuretests.py
Simplify domain xml in featuretests.py
Makefile.am | 1 +
src/kimchi/featuretests.py | 24 +++++-------------------
2 files changed, 6 insertions(+), 19 deletions(-)
--
1.7.10.4
10 years, 12 months
[PATCH 1/2] move RollbackContext from tests/utils to src/kimchi/rollbackcontext
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
Then kimchi source code can make use of it
Also add src/kimchi/rollbackcontext.py in dist list
Signed-off-by: Zhou Zheng Sheng <zhshzhou(a)linux.vnet.ibm.com>
Signed-off-by: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
---
src/kimchi/Makefile.am | 59 +++++++++++++++++------------------
src/kimchi/rollbackcontext.py | 71 +++++++++++++++++++++++++++++++++++++++++++
tests/test_model.py | 25 +++++++--------
tests/test_rest.py | 3 +-
tests/utils.py | 45 ---------------------------
5 files changed, 116 insertions(+), 87 deletions(-)
create mode 100644 src/kimchi/rollbackcontext.py
diff --git a/src/kimchi/Makefile.am b/src/kimchi/Makefile.am
index 47a3bd2..2f05ab7 100644
--- a/src/kimchi/Makefile.am
+++ b/src/kimchi/Makefile.am
@@ -21,35 +21,36 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
kimchi_PYTHON = \
- asynctask.py \
- auth.py \
- controller.py \
- disks.py \
- distroloader.py \
- exception.py \
- __init__.py \
- isoinfo.py \
- netinfo.py \
- network.py \
- networkxml.py \
- mockmodel.py \
- model.py \
- objectstore.py \
- osinfo.py \
- root.py \
- scan.py \
- screenshot.py \
- server.py \
- sslcert.py \
- template.py \
- vmtemplate.py \
- vnc.py \
- websocket.py \
- websockify.py \
- xmlutils.py \
- utils.py \
- cachebust.py \
- featuretests.py
+ __init__.py \
+ asynctask.py \
+ auth.py \
+ cachebust.py \
+ controller.py \
+ disks.py \
+ distroloader.py \
+ exception.py \
+ featuretests.py \
+ isoinfo.py \
+ mockmodel.py \
+ model.py \
+ netinfo.py \
+ network.py \
+ networkxml.py \
+ objectstore.py \
+ osinfo.py \
+ rollbackcontext.py \
+ root.py \
+ scan.py \
+ screenshot.py \
+ server.py \
+ sslcert.py \
+ template.py \
+ utils.py \
+ vmtemplate.py \
+ vnc.py \
+ websocket.py \
+ websockify.py \
+ xmlutils.py
nodist_kimchi_PYTHON = config.py
diff --git a/src/kimchi/rollbackcontext.py b/src/kimchi/rollbackcontext.py
new file mode 100644
index 0000000..2afd114
--- /dev/null
+++ b/src/kimchi/rollbackcontext.py
@@ -0,0 +1,71 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2013
+#
+# Authors:
+# Adam Litke <agl(a)linux.vnet.ibm.com>
+# ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# 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
+#
+
+import sys
+
+
+class RollbackContext(object):
+ '''
+ A context manager for recording and playing rollback.
+ The first exception will be remembered and re-raised after rollback
+
+ Sample usage:
+ with RollbackContext() as rollback:
+ step1()
+ rollback.prependDefer(lambda: undo step1)
+ def undoStep2(arg): pass
+ step2()
+ rollback.prependDefer(undoStep2, arg)
+ '''
+ def __init__(self, *args):
+ self._finally = []
+
+ def __enter__(self):
+ return self
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ firstException = exc_value
+
+ for undo, args, kwargs in self._finally:
+ try:
+ undo(*args, **kwargs)
+ except Exception as e:
+ # keep the earliest exception info
+ if not firstException:
+ firstException = e
+ # keep the original traceback info
+ traceback = sys.exc_info()[2]
+
+ # re-raise the earliest exception
+ if firstException is not None:
+ if type(firstException) is str:
+ sys.stderr.write(firstException)
+ else:
+ raise firstException, None, traceback
+
+ def defer(self, func, *args, **kwargs):
+ self._finally.append((func, args, kwargs))
+
+ def prependDefer(self, func, *args, **kwargs):
+ self._finally.insert(0, (func, args, kwargs))
diff --git a/tests/test_model.py b/tests/test_model.py
index e19364f..7ecd8c6 100644
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -38,6 +38,7 @@ import utils
from kimchi import netinfo
from kimchi.exception import InvalidOperation, InvalidParameter
from kimchi.exception import NotFoundError, OperationFailed
+from kimchi.rollbackcontext import RollbackContext
class ModelTests(unittest.TestCase):
@@ -72,7 +73,7 @@ class ModelTests(unittest.TestCase):
def test_vm_lifecycle(self):
inst = kimchi.model.Model(objstore_loc=self.tmp_store)
- with utils.RollbackContext() as rollback:
+ with RollbackContext() as rollback:
params = {'name': 'test', 'disks': []}
inst.templates_create(params)
rollback.prependDefer(inst.template_delete, 'test')
@@ -97,7 +98,7 @@ class ModelTests(unittest.TestCase):
def test_vm_storage_provisioning(self):
inst = kimchi.model.Model(objstore_loc=self.tmp_store)
- with utils.RollbackContext() as rollback:
+ with RollbackContext() as rollback:
params = {'name': 'test', 'disks': [{'size': 1}]}
inst.templates_create(params)
rollback.prependDefer(inst.template_delete, 'test')
@@ -115,7 +116,7 @@ class ModelTests(unittest.TestCase):
def test_storagepool(self):
inst = kimchi.model.Model('qemu:///system', self.tmp_store)
- with utils.RollbackContext() as rollback:
+ with RollbackContext() as rollback:
path = '/tmp/kimchi-images'
name = 'test-pool'
if not os.path.exists(path):
@@ -168,7 +169,7 @@ class ModelTests(unittest.TestCase):
def test_storagevolume(self):
inst = kimchi.model.Model('qemu:///system', self.tmp_store)
- with utils.RollbackContext() as rollback:
+ with RollbackContext() as rollback:
path = '/tmp/kimchi-images'
pool = 'test-pool'
vol = 'test-volume.img'
@@ -223,7 +224,7 @@ class ModelTests(unittest.TestCase):
def test_template_storage_customise(self):
inst = kimchi.model.Model(objstore_loc=self.tmp_store)
- with utils.RollbackContext() as rollback:
+ with RollbackContext() as rollback:
path = '/tmp/kimchi-images'
pool = 'test-pool'
if not os.path.exists(path):
@@ -295,7 +296,7 @@ class ModelTests(unittest.TestCase):
orig_params = {'name': 'test', 'memory': '1024', 'cpus': '1'}
inst.templates_create(orig_params)
- with utils.RollbackContext() as rollback:
+ with RollbackContext() as rollback:
params_1 = {'name': 'kimchi-vm1', 'template': '/templates/test'}
params_2 = {'name': 'kimchi-vm2', 'template': '/templates/test'}
inst.vms_create(params_1)
@@ -326,7 +327,7 @@ class ModelTests(unittest.TestCase):
def test_network(self):
inst = kimchi.model.Model('qemu:///system', self.tmp_store)
- with utils.RollbackContext() as rollback:
+ with RollbackContext() as rollback:
name = 'test-network'
networks = inst.networks_get_list()
@@ -480,7 +481,7 @@ class ModelTests(unittest.TestCase):
def test_delete_running_vm(self):
inst = kimchi.model.Model(objstore_loc=self.tmp_store)
- with utils.RollbackContext() as rollback:
+ with RollbackContext() as rollback:
params = {'name': u'test', 'disks': []}
inst.templates_create(params)
rollback.prependDefer(inst.template_delete, 'test')
@@ -501,7 +502,7 @@ class ModelTests(unittest.TestCase):
def test_vm_list_sorted(self):
inst = kimchi.model.Model(objstore_loc=self.tmp_store)
- with utils.RollbackContext() as rollback:
+ with RollbackContext() as rollback:
params = {'name': 'test', 'disks': []}
inst.templates_create(params)
rollback.prependDefer(inst.template_delete, 'test')
@@ -517,7 +518,7 @@ class ModelTests(unittest.TestCase):
def test_use_test_host(self):
inst = kimchi.model.Model('test:///default', objstore_loc=self.tmp_store)
- with utils.RollbackContext() as rollback:
+ with RollbackContext() as rollback:
params = {'name': 'test', 'disks': [],
'storagepool': '/storagepools/default-pool',
'domain': 'test',
@@ -546,7 +547,7 @@ class ModelTests(unittest.TestCase):
inst.debugreport_delete(namePrefix + '*')
except NotFoundError:
pass
- with utils.RollbackContext() as rollback:
+ with RollbackContext() as rollback:
report_list = inst.debugreports_get_list()
self.assertFalse(reportName in report_list)
try:
@@ -617,7 +618,7 @@ class ModelTests(unittest.TestCase):
@unittest.skipUnless(utils.running_as_root(), 'Must be run as root')
def test_deep_scan(self):
inst = kimchi.model.Model('qemu:///system', objstore_loc=self.tmp_store)
- with utils.RollbackContext() as rollback:
+ with RollbackContext() as rollback:
path = '/tmp/kimchi-images/tmpdir'
if not os.path.exists(path):
os.makedirs(path)
diff --git a/tests/test_rest.py b/tests/test_rest.py
index 73946c0..1b7312f 100644
--- a/tests/test_rest.py
+++ b/tests/test_rest.py
@@ -33,8 +33,9 @@ from functools import partial
import kimchi.mockmodel
import kimchi.server
from kimchi.asynctask import AsyncTask
+from kimchi.rollbackcontext import RollbackContext
from utils import fake_user, get_free_port, https_request, patch_auth, request
-from utils import RollbackContext, run_server
+from utils import run_server
test_server = None
diff --git a/tests/utils.py b/tests/utils.py
index a7596e8..960e0be 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -140,51 +140,6 @@ def https_request(host, port, path, data=None, method='GET', headers=None):
return _request(conn, path, data, method, headers)
-class RollbackContext(object):
- '''
- A context manager for recording and playing rollback.
- The first exception will be remembered and re-raised after rollback
-
- Sample usage:
- with RollbackContext() as rollback:
- step1()
- rollback.prependDefer(lambda: undo step1)
- def undoStep2(arg): pass
- step2()
- rollback.prependDefer(undoStep2, arg)
- '''
- def __init__(self, *args):
- self._finally = []
-
- def __enter__(self):
- return self
-
- def __exit__(self, exc_type, exc_value, traceback):
- firstException = exc_value
-
- for undo, args, kwargs in self._finally:
- try:
- undo(*args, **kwargs)
- except Exception as e:
- # keep the earliest exception info
- if not firstException:
- firstException = e
- # keep the original traceback info
- traceback = sys.exc_info()[2]
-
- # re-raise the earliest exception
- if firstException is not None:
- if type(firstException) is str:
- sys.stderr.write(firstException)
- else:
- raise firstException, None, traceback
-
- def defer(self, func, *args, **kwargs):
- self._finally.append((func, args, kwargs))
-
- def prependDefer(self, func, *args, **kwargs):
- self._finally.insert(0, (func, args, kwargs))
-
def patch_auth():
"""
Override the authenticate function with a simple test against an
--
1.8.4.2
10 years, 12 months
[PATCH V2] fix whitespace in test_mockmodel
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
V1 -> V2
remove the unuseful comment
Commit e467b32 brings a whitespace, fix it.
Also fix pep8.
ShaoHe Feng (1):
fix whitespace in test_mockmodel
Makefile.am | 1 +
tests/test_mockmodel.py | 25 +++++++++++++++----------
2 files changed, 16 insertions(+), 10 deletions(-)
--
1.8.4.2
10 years, 12 months
[PATCH v3 0/5] Support Creating iSCSI storage pool
by Zhou Zheng Sheng
This patch series is about creating iSCSI storage pool.
After this patch, you can create an ISCSI storage pool as the following.
Thanks the reviewers. I took most of your advices in v3 series.
curl -u root -H 'Content-type: application/json' \
-H 'Accept: application/json' \
-d '{"source": {
"target": "iqn.2013-01.example.com.targetname",
"host": "192.168.X.X",
"port": 326X,
"auth": {"username": "testUser", "password": "123456"}},
"type": "iscsi",
"name": "testIscsiPool"}' \
http://127.0.0.1:8000/storagepools
Note the "port" and "auth" is optional.
Zhou Zheng Sheng (5):
storagepool: refactor _get_pool_xml()
This patch is to refactor current storage pool XML generation code
to be more extensible.
v2 -> v3: Extract a StoragePoolDef class and define "prepare()" and
"create()" method.
storagepool: rename and consolidate arguments of creating (back end)
This patch is to consolidate argument serving the same purpose
under the same name.
v2 -> v3: Fix typo.
storagepool: rename and consolidate arguments of creating (front end)
This patch is the respective front-end changes for the above patch.
v2 -> v3: No change.
storagepool: Support Creating iSCSI storagepool in model.py
This patch is to validate iSCSI host and auth, and create libvirt
iSCSI storage pool.
v2 -> v3: Support iSCSI CHAP auth. Add more test cases.
test_model: test creating iSCSI storage pool
v2 -> v3: Do not create directory for storage pool, pool.build()
create it automatically.
Makefile.am | 2 +
docs/API.md | 28 ++--
src/kimchi/Makefile.am | 1 +
src/kimchi/iscsi.py | 89 ++++++++++++
src/kimchi/model.py | 223 +++++++++++++++++++++++++------
tests/Makefile.am | 1 +
tests/test_model.py | 89 ++++++------
tests/test_storagepool.py | 156 +++++++++++++++++++++
ui/js/src/kimchi.storagepool_add_main.js | 13 +-
9 files changed, 513 insertions(+), 89 deletions(-)
create mode 100644 src/kimchi/iscsi.py
create mode 100644 tests/test_storagepool.py
--
1.7.11.7
10 years, 12 months
[PATCH] pep8 cleanup for root.py
by Aline Manera
From: Aline Manera <alinefm(a)br.ibm.com>
This patch cleans up pep8 style issue in root.py
Also move error_production_handler and error_development_handler functions
to Root() class as they are used only in it.
Signed-off-by: Aline Manera <alinefm(a)br.ibm.com>
---
Makefile.am | 1 +
src/kimchi/root.py | 49 +++++++++++++++++++++++++++----------------------
2 files changed, 28 insertions(+), 22 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index e57d3b6..622d4f0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -41,6 +41,7 @@ PEP8_WHITELIST = \
src/kimchi/asynctask.py \
src/kimchi/config.py.in \
src/kimchi/disks.py \
+ src/kimchi/root.py \
src/kimchi/server.py \
plugins/__init__.py \
plugins/sample/__init__.py \
diff --git a/src/kimchi/root.py b/src/kimchi/root.py
index c43897c..d1fe818 100644
--- a/src/kimchi/root.py
+++ b/src/kimchi/root.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 cherrypy
import json
@@ -30,30 +30,19 @@ from kimchi import template
from kimchi.config import get_api_schema_file
-def error_production_handler(status, message, traceback, version):
- data = {'code': status, 'reason': message}
- res = template.render('error.html', data)
- if type(res) is unicode:
- res = res.encode("utf-8")
- return res
-
-def error_development_handler(status, message, traceback, version):
- data = {'code': status, 'reason': message, 'call_stack': cherrypy._cperror.format_exc()}
- res = template.render('error.html', data)
- if type(res) is unicode:
- res = res.encode("utf-8")
- return res
-
-
class Root(controller.Resource):
- _handled_error = ['error_page.400',
- 'error_page.404', 'error_page.405',
- 'error_page.406', 'error_page.415', 'error_page.500']
def __init__(self, model, dev_env):
+ self._handled_error = ['error_page.400', 'error_page.404',
+ 'error_page.405', 'error_page.406',
+ 'error_page.415', 'error_page.500']
+
if not dev_env:
- self._cp_config = dict([(key, error_production_handler) for key in self._handled_error])
+ self._cp_config = dict([(key, self.error_production_handler)
+ for key in self._handled_error])
else:
- self._cp_config = dict([(key, error_development_handler) for key in self._handled_error])
+ self._cp_config = dict([(key, self.error_development_handler)
+ for key in self._handled_error])
+
controller.Resource.__init__(self, model)
self.vms = controller.VMs(model)
self.templates = controller.Templates(model)
@@ -69,6 +58,21 @@ class Root(controller.Resource):
self.plugins = controller.Plugins(model)
self.api_schema = json.load(open(get_api_schema_file()))
+ def error_production_handler(status, message, traceback, version):
+ data = {'code': status, 'reason': message}
+ res = template.render('error.html', data)
+ if type(res) is unicode:
+ res = res.encode("utf-8")
+ return res
+
+ def error_development_handler(status, message, traceback, version):
+ data = {'code': status, 'reason': message,
+ 'call_stack': cherrypy._cperror.format_exc()}
+ res = template.render('error.html', data)
+ if type(res) is unicode:
+ res = res.encode("utf-8")
+ return res
+
def get(self):
return self.default('kimchi-ui.html')
@@ -77,8 +81,9 @@ class Root(controller.Resource):
if page.endswith('.html'):
return template.render(page, None)
raise cherrypy.HTTPError(404)
+
@cherrypy.expose
def tabs(self, page, **kwargs):
if page.endswith('.html'):
- return template.render('tabs/'+ page, None)
+ return template.render('tabs/' + page, None)
raise cherrypy.HTTPError(404)
--
1.7.10.4
10 years, 12 months
[PATCH V2 0/6] template supports networks
by shaohef@linux.vnet.ibm.com
From: ShaoHe Feng <shaohef(a)linux.vnet.ibm.com>
V1 -> V2:
update mockmodel and test case
add 'networks' option for template get/create/update
ShaoHe Feng (6):
template supports networks: let template xml support more networks
template supports networks: update API
template supports networks: update controller and json schema
template supports networks: update model
template supports networks: update mockmodel
template supports networks: update test case
docs/API.md | 4 +++
src/kimchi/API.json | 14 ++++++++
src/kimchi/controller.py | 3 +-
src/kimchi/mockmodel.py | 7 +++-
src/kimchi/model.py | 6 ++++
src/kimchi/osinfo.py | 5 +--
src/kimchi/vmtemplate.py | 20 ++++++++---
tests/test_model.py | 87 +++++++++++++++++++++++++++++++++++++-----------
tests/test_rest.py | 68 +++++++++++++++++++++++++++++++++++++
9 files changed, 187 insertions(+), 27 deletions(-)
--
1.8.4.2
10 years, 12 months
[PATCH V2] Organize python imports
by Rodrigo Trujillo
Follow this rule:
1) Import common modules
import ...
import ...
from ... import ...
from ... import ...
2) Import kimchi modules
import kimchi.<mod>
import kimchi.<mod>
from kimchi import ...
from kimchi import ...
Signed-off-by: Rodrigo Trujillo <rodrigo.trujillo(a)linux.vnet.ibm.com>
---
plugins/sample/__init__.py | 8 ++++++--
plugins/sample/model.py | 2 +-
src/kimchi/model.py | 4 ++--
src/kimchi/server.py | 2 +-
src/kimchi/sslcert.py | 2 +-
tests/test_exception.py | 8 +++++---
tests/test_mockmodel.py | 6 ++++--
tests/test_model.py | 19 +++++++++++--------
tests/test_networkxml.py | 4 +++-
tests/test_osinfo.py | 5 ++++-
tests/test_plugin.py | 6 +++++-
tests/test_rest.py | 12 +++++++++---
tests/test_server.py | 4 ++--
tests/test_vmtemplate.py | 4 +++-
tests/utils.py | 15 +++++++++------
15 files changed, 66 insertions(+), 35 deletions(-)
diff --git a/plugins/sample/__init__.py b/plugins/sample/__init__.py
index a20f5e6..7064904 100644
--- a/plugins/sample/__init__.py
+++ b/plugins/sample/__init__.py
@@ -22,12 +22,16 @@
import json
import os
+
+
from cherrypy import expose
-from kimchi.controller import Resource, Collection
+
+
+from kimchi.controller import Collection, Resource
from model import Model
-model = Model()
+model = Model()
class Drawings(Resource):
def __init__(self):
diff --git a/plugins/sample/model.py b/plugins/sample/model.py
index f6da5d0..9a2f22f 100644
--- a/plugins/sample/model.py
+++ b/plugins/sample/model.py
@@ -20,7 +20,7 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
-from kimchi.exception import NotFoundError, InvalidOperation
+from kimchi.exception import InvalidOperation, NotFoundError
class Model(object):
diff --git a/src/kimchi/model.py b/src/kimchi/model.py
index 3bc5d6d..d5d0dd8 100644
--- a/src/kimchi/model.py
+++ b/src/kimchi/model.py
@@ -42,9 +42,9 @@ import time
import uuid
-from collections import defaultdict
from cherrypy.process.plugins import BackgroundTask
from cherrypy.process.plugins import SimplePlugin
+from collections import defaultdict
from xml.etree import ElementTree
@@ -69,7 +69,7 @@ from kimchi.networkxml import to_network_xml
from kimchi.objectstore import ObjectStore
from kimchi.scan import Scanner
from kimchi.screenshot import VMScreenshot
-from kimchi.utils import kimchi_log, is_digit, get_enabled_plugins
+from kimchi.utils import get_enabled_plugins, is_digit, kimchi_log
from kimchi.vmtemplate import VMTemplate
diff --git a/src/kimchi/server.py b/src/kimchi/server.py
index 6ff6fa0..114a3a0 100644
--- a/src/kimchi/server.py
+++ b/src/kimchi/server.py
@@ -33,7 +33,7 @@ from kimchi import config
from kimchi import model
from kimchi import mockmodel
from kimchi.root import Root
-from kimchi.utils import import_class, get_enabled_plugins
+from kimchi.utils import get_enabled_plugins, import_class
LOGGING_LEVEL = {"debug": logging.DEBUG,
diff --git a/src/kimchi/sslcert.py b/src/kimchi/sslcert.py
index 70441f2..529699d 100644
--- a/src/kimchi/sslcert.py
+++ b/src/kimchi/sslcert.py
@@ -28,7 +28,7 @@
import time
-from M2Crypto import X509, EVP, RSA, ASN1
+from M2Crypto import ASN1, EVP, RSA, X509
class SSLCert(object):
diff --git a/tests/test_exception.py b/tests/test_exception.py
index 9b5355a..df1f507 100644
--- a/tests/test_exception.py
+++ b/tests/test_exception.py
@@ -20,13 +20,15 @@
# 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 unittest
-import os
import json
+import os
+import unittest
+
import kimchi.mockmodel
import kimchi.server
-from utils import *
+from utils import get_free_port, patch_auth, request, run_server
+
test_server = None
model = None
diff --git a/tests/test_mockmodel.py b/tests/test_mockmodel.py
index b819172..5a3c73e 100644
--- a/tests/test_mockmodel.py
+++ b/tests/test_mockmodel.py
@@ -20,15 +20,17 @@
# 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 unittest
import cherrypy
import json
import os
+import time
+import unittest
+
import kimchi.mockmodel
import kimchi.controller
+from utils import get_free_port, patch_auth, request, run_server
-from utils import *
#utils.silence_server()
test_server = None
diff --git a/tests/test_model.py b/tests/test_model.py
index fb7d6dd..e19364f 100644
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -21,21 +21,24 @@
# 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 unittest
-import threading
import os
-import time
-import tempfile
-import psutil
import platform
+import psutil
+import tempfile
+import threading
+import time
+import unittest
import uuid
+
+import iso_gen
import kimchi.model
import kimchi.objectstore
-from kimchi.exception import *
-from kimchi import netinfo
import utils
-import iso_gen
+from kimchi import netinfo
+from kimchi.exception import InvalidOperation, InvalidParameter
+from kimchi.exception import NotFoundError, OperationFailed
+
class ModelTests(unittest.TestCase):
def setUp(self):
diff --git a/tests/test_networkxml.py b/tests/test_networkxml.py
index 4eeeaa2..3073bce 100644
--- a/tests/test_networkxml.py
+++ b/tests/test_networkxml.py
@@ -20,10 +20,12 @@
# 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 ipaddr
import unittest
+
+
import kimchi.networkxml as nxml
from kimchi.xmlutils import xpath_get_text
-import ipaddr
class NetworkXmlTests(unittest.TestCase):
diff --git a/tests/test_osinfo.py b/tests/test_osinfo.py
index f92567d..fda8ada 100644
--- a/tests/test_osinfo.py
+++ b/tests/test_osinfo.py
@@ -21,7 +21,10 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
import unittest
-from kimchi.osinfo import *
+
+
+from kimchi.osinfo import lookup
+
class OSInfoTests(unittest.TestCase):
def test_default_lookup(self):
diff --git a/tests/test_plugin.py b/tests/test_plugin.py
index 20cc598..42c87a9 100644
--- a/tests/test_plugin.py
+++ b/tests/test_plugin.py
@@ -20,17 +20,21 @@
# 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 unittest
import json
import os
import sys
+import unittest
+
+
from functools import partial
+
import kimchi.mockmodel
import kimchi.server
import utils
from kimchi import config
+
test_server = None
model = None
host = None
diff --git a/tests/test_rest.py b/tests/test_rest.py
index f597796..73946c0 100644
--- a/tests/test_rest.py
+++ b/tests/test_rest.py
@@ -20,16 +20,22 @@
# 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 unittest
+import base64
import json
-import time
import os
+import time
+import unittest
+
+
from functools import partial
+
import kimchi.mockmodel
import kimchi.server
-from utils import *
from kimchi.asynctask import AsyncTask
+from utils import fake_user, get_free_port, https_request, patch_auth, request
+from utils import RollbackContext, run_server
+
test_server = None
model = None
diff --git a/tests/test_server.py b/tests/test_server.py
index 9bb0034..734a618 100644
--- a/tests/test_server.py
+++ b/tests/test_server.py
@@ -20,12 +20,12 @@
# 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 unittest
import json
import os
+import unittest
-import utils
+import utils
import kimchi.mockmodel
#utils.silence_server()
diff --git a/tests/test_vmtemplate.py b/tests/test_vmtemplate.py
index 81382c7..7f032e7 100644
--- a/tests/test_vmtemplate.py
+++ b/tests/test_vmtemplate.py
@@ -23,9 +23,11 @@
import unittest
import uuid
-from kimchi.vmtemplate import *
+
+from kimchi.vmtemplate import VMTemplate
from kimchi.xmlutils import xpath_get_text
+
class VMTemplateTests(unittest.TestCase):
def test_minimal_construct(self):
fields = (('name', 'test'), ('os_distro', 'unknown'),
diff --git a/tests/utils.py b/tests/utils.py
index c114813..a7596e8 100644
--- a/tests/utils.py
+++ b/tests/utils.py
@@ -21,16 +21,19 @@
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
#
-import httplib
+import base64
import cherrypy
-import threading
-import time
+import httplib
import os
-import sys
import socket
-from contextlib import closing
+import sys
+import threading
+import time
import unittest
-import base64
+
+
+from contextlib import closing
+
import kimchi.server
import kimchi.model
--
1.8.1.4
10 years, 12 months
[PATCH v4 1/2] logical pool fixes: only list leaf devices, and read file instead of run "cat"
by Zhou Zheng Sheng
Some devices are parent of other devices. We should just list the leaf
devices but not parent devices. For example, if a disk contains
partitions, we should only list the partitions. If a disk is held by
multipath device, we should not list the disk.
Currently we strip the last charactter from "vda1" to get "vda" and
ignore the parent "vda" device. This may fails on disk contains lots of
logical partitions, for example "vda10"'s parent is not "vda1". Another
problem is this method can not find the parent-child relation ship
between a multipath device and its slaves.
The most accurate information is on sysfs, and lsblk lists all children
device of the requested device based on sysfs. So when "lsblk -P
devices" prints only one line, it's the device itself, when it prints
more lines, they are the children devices. This patch use this method to
detect if a device a leaf one.
This patch also avoids start new "cat" process to read uevent file, it
opens the uevent file and read it directly.
v2:
Assign string literal to constants thus avoid breaking the line.
v3:
Save N lsblk invocations when list all devices by collecting major:min
and device node path in one run. N is number of block devices.
Use short-circuiting operator "and" instead of all to save extra lsblk
invocation.
v4:
Remove a redundant "else" as suggested by Aline.
Signed-off-by: Zhou Zheng Sheng <zhshzhou(a)linux.vnet.ibm.com>
---
src/kimchi/disks.py | 83 ++++++++++++++++++++++++++++++++---------------------
1 file changed, 50 insertions(+), 33 deletions(-)
diff --git a/src/kimchi/disks.py b/src/kimchi/disks.py
index a054961..a7e5616 100644
--- a/src/kimchi/disks.py
+++ b/src/kimchi/disks.py
@@ -27,27 +27,13 @@ from kimchi.exception import OperationFailed
from kimchi.utils import kimchi_log
-def _get_partition_path(name):
- """ Returns device path given a partition name """
- dev_path = None
- maj_min = None
-
- keys = ["NAME", "MAJ:MIN"]
- dev_list = _get_lsblk_devs(keys)
-
- for dev in dev_list:
- if dev['name'] == name:
- maj_min = dev['maj:min']
- break
+def _get_dev_node_path(maj_min):
+ """ Returns device node path given the device number 'major:min' """
+ uevent = "/sys/dev/block/%s/uevent" % maj_min
+ with open(uevent) as ueventf:
+ content = ueventf.read()
- uevent_cmd = "cat /sys/dev/block/%s/uevent" % maj_min
- uevent = subprocess.Popen(uevent_cmd, stdout=subprocess.PIPE,
- stderr=subprocess.PIPE, shell=True)
- out, err = uevent.communicate()
- if uevent.returncode != 0:
- raise OperationFailed("Error getting partition path for %s", name)
-
- data = dict(re.findall(r'(\S+)=(".*?"|\S+)', out.replace("\n", " ")))
+ data = dict(re.findall(r'(\S+)=(".*?"|\S+)', content.replace("\n", " ")))
return "/dev/%s" % data["DEVNAME"]
@@ -63,6 +49,39 @@ def _get_lsblk_devs(keys, devs=[]):
return _parse_lsblk_output(out, keys)
+def _get_dev_major_min(name):
+ maj_min = None
+
+ keys = ["NAME", "MAJ:MIN"]
+ dev_list = _get_lsblk_devs(keys)
+
+ for dev in dev_list:
+ if dev['name'] == name:
+ maj_min = dev['maj:min']
+ break
+ else:
+ msg = "Failed to find major and minor number for %s" % name
+ raise OperationFailed(msg)
+
+ return maj_min
+
+
+def _is_dev_leaf(devNodePath):
+ try:
+ # By default, lsblk prints a device information followed by children
+ # device information
+ childrenCount = len(
+ _get_lsblk_devs(["NAME"], [devNodePath])) - 1
+ except OperationFailed as e:
+ # lsblk is known to fail on multipath devices
+ # Assume these devices contain children
+ kimchi_log.error(
+ "Error getting device info for %s: %s", devNodePath, e)
+ return False
+
+ return childrenCount == 0
+
+
def _parse_lsblk_output(output, keys):
# output is on format key="value",
# where key can be NAME, TYPE, FSTYPE, SIZE, MOUNTPOINT, etc
@@ -82,32 +101,30 @@ def _parse_lsblk_output(output, keys):
def get_partitions_names():
names = []
- ignore_names = []
- keys = ["NAME", "TYPE", "FSTYPE", "MOUNTPOINT"]
+ keys = ["NAME", "TYPE", "FSTYPE", "MOUNTPOINT", "MAJ:MIN"]
# output is on format key="value",
# where key can be NAME, TYPE, FSTYPE, MOUNTPOINT
for dev in _get_lsblk_devs(keys):
# split()[0] to avoid the second part of the name, after the
# whiteline
name = dev['name'].split()[0]
- # Only list unmounted and unformated partition or disk.
- if not all([dev['type'] in ['part', 'disk'],
- dev['fstype'] == "",
- dev['mountpoint'] == ""]):
-
- # the whole disk must be ignored in it has at least one
- # mounted/formatted partition
- if dev['type'] == 'part':
- ignore_names.append(name[:-1])
+ devNodePath = _get_dev_node_path(dev['maj:min'])
+ # Only list unmounted and unformated and leaf and (partition or disk)
+ # leaf means a partition, a disk has no partition, or a disk not held
+ # by any multipath device.
+ if not (dev['type'] in ['part', 'disk'] and
+ dev['fstype'] == "" and
+ dev['mountpoint'] == "" and
+ _is_dev_leaf(devNodePath)):
continue
names.append(name)
- return list(set(names) - set(ignore_names))
+ return names
def get_partition_details(name):
- dev_path = _get_partition_path(name)
+ dev_path = _get_dev_node_path(_get_dev_major_min(name))
keys = ["TYPE", "FSTYPE", "SIZE", "MOUNTPOINT"]
try:
--
1.7.11.7
10 years, 12 months