[PATCH v4] [Kimchi] Feature request (#860): Support Guest Autostart
by bianca@linux.vnet.ibm.com
From: Bianca Carvalho <bianca(a)linux.vnet.ibm.com>
Include 'autostart' option in API.json and vms.py (lookup and update)
using libvirt dom.setAutostart to set as true or false. Also edit
test_model.py to include those changes and updated API.md file.
Also included API tests to test_rest.py in test_edit_vm function.
Signed-off-by: Bianca Carvalho <bianca(a)linux.vnet.ibm.com>
---
API.json | 4 ++++
docs/API.md | 3 +++
model/vms.py | 11 ++++++++---
tests/test_model.py | 6 ++++++
tests/test_rest.py | 18 ++++++++++++++++++
5 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/API.json b/API.json
index a3af02d..8592f3a 100644
--- a/API.json
+++ b/API.json
@@ -342,6 +342,10 @@
"error": "KCHVM0053E",
"type": "boolean"
},
+ "autostart": {
+ "description": "Enable/Disable guest autostart",
+ "type": "boolean"
+ },
"users": {
"description": "Array of users who have permission to the VM",
"type": "array",
diff --git a/docs/API.md b/docs/API.md
index 7bd677f..7c29f04 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -151,6 +151,8 @@ server.
* bootorder: list of devices in boot order
* description: VM description
* title: VM title
+ * autostart: show if autostart is enabled.
+
* **DELETE**: Remove the Virtual Machine
* **PUT**: update the parameters of existing VM
* name: New name for this VM (only applied for shutoff VM)
@@ -183,6 +185,7 @@ server.
* bootmenu: prompts guest bootmenu. Bool type.
* description: VM description
* title: VM title
+ * autostart: enable/disable guest autostart (true or false params).
* **POST**: *See Virtual Machine Actions*
diff --git a/model/vms.py b/model/vms.py
index 7f607f5..bb00c09 100644
--- a/model/vms.py
+++ b/model/vms.py
@@ -80,12 +80,13 @@ DOM_STATE_MAP = {0: 'nostate',
7: 'pmsuspended'}
# update parameters which are updatable when the VM is online
-VM_ONLINE_UPDATE_PARAMS = ['graphics', 'groups', 'memory', 'users']
+VM_ONLINE_UPDATE_PARAMS = ['graphics', 'groups', 'memory', 'users',
+ 'autostart']
# update parameters which are updatable when the VM is offline
VM_OFFLINE_UPDATE_PARAMS = ['cpu_info', 'graphics', 'groups', 'memory',
'name', 'users', 'bootorder', 'bootmenu',
- 'description', 'title']
+ 'description', 'title', 'autostart']
XPATH_DOMAIN_DISK = "/domain/devices/disk[@device='disk']/source/@file"
XPATH_DOMAIN_DISK_BY_FILE = "./devices/disk[@device='disk']/source[@file='%s']"
@@ -270,6 +271,9 @@ class VMModel(object):
with lock:
dom = self.get_vm(name, self.conn)
+ if "autostart" in params:
+ dom.setAutostart(1 if params['autostart'] == True else 0)
+
# You can only change <maxMemory> offline, updating guest XML
if ("memory" in params) and ('maxmemory' in params['memory']) and\
(DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
@@ -1314,7 +1318,8 @@ class VMModel(object):
'access': 'full',
'persistent': True if dom.isPersistent() else False,
'bootorder': boot,
- 'bootmenu': bootmenu
+ 'bootmenu': bootmenu,
+ 'autostart': dom.autostart()
}
def _vm_get_disk_paths(self, dom):
diff --git a/tests/test_model.py b/tests/test_model.py
index d9ffd5e..8f3a578 100644
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -1362,6 +1362,12 @@ class ModelTests(unittest.TestCase):
inst.vm_update(u'пeω-∨м', {"bootmenu": False})
self.assertEquals("no", inst.vm_lookup(u'пeω-∨м')['bootmenu'])
+ # enable/disable autostart
+ inst.vm_update(u'пeω-∨м', {"autostart": True})
+ self.assertEquals("yes", inst.vm_lookup(u'пeω-∨м')['autostart'])
+ inst.vm_update(u'пeω-∨м', {"autostart": False})
+ self.assertEquals("no", inst.vm_lookup(u'пeω-∨м')['autostart'])
+
def test_get_interfaces(self):
inst = model.Model('test:///default',
objstore_loc=self.tmp_store)
diff --git a/tests/test_rest.py b/tests/test_rest.py
index b1b9f12..0ecf11b 100644
--- a/tests/test_rest.py
+++ b/tests/test_rest.py
@@ -301,6 +301,24 @@ class RestTests(unittest.TestCase):
resp = self.request('/plugins/kimchi/vms/∨м-црdαtеd', req, 'PUT')
self.assertEquals(400, resp.status)
+ # set vm autostart tests (powered off)
+ resp = self.request('/plugins/kimchi/vms/vm-1/poweroff', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ req = json.dumps({"autostart": True})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/vms/vm-1', '{}', 'GET').read()
+ self.assertEquals(resp["autostart"], True)
+
+ # set vm autostart tests (running)
+ resp = self.request('/plugins/kimchi/vms/vm-1/start', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ req = json.dumps({"autostart": False})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/vms/vm-1', '{}', 'GET').read()
+ self.assertEquals(resp["autostart"], True)
+
def test_vm_lifecycle(self):
# Create a Template
req = json.dumps({'name': 'test',
--
2.7.4
8 years, 3 months
[PATCH V3] [Wok 0/2] Issue #122 - Make AsyncTask stoppable.
by pvital@linux.vnet.ibm.com
From: Paulo Vital <pvital(a)linux.vnet.ibm.com>
V3:
- Updated exception code used - again
V2:
- Modified exception code used
- Updated i18n messages
V1:
This patch-set gives to user a way to 'stop' a Task that is still running by
setting the Task status to "killed".
Since an AsyncTask is basic a thread running in the system and this thread can
execute a pure Python method or a background command (by using run_command()
from wok.utils), the developer must pass to AsyncTask constructor a method to be
executed by the DELETE operation, called here as 'kill_cb'.
If none kill_cb is passed, the task will not be able to stopped and an error
message will be raised to user if DELETE operation is executed. Otherwise, the
kill_cb method will be executed by kill() method (responsible to execute the
DELETE operation) of AsyncTask class and its status set to 'killed'.
The unit tests present how you can use it.
Paulo Vital (2):
Issue #122 - Make AsyncTask stoppable.
Issue #122 - Add unit test to stop AsyncTask.
docs/API/tasks.md | 2 ++
src/wok/asynctask.py | 18 +++++++++++++++++-
src/wok/i18n.py | 2 ++
src/wok/model/tasks.py | 13 +++++++++++++
tests/test_api.py | 26 ++++++++++++++++++++++++--
tests/test_tasks.py | 19 ++++++++++++++++++-
6 files changed, 76 insertions(+), 4 deletions(-)
--
2.7.4
8 years, 3 months
[PATCH v2] [Kimchi] Issue #626: Snapshot revert does not release storage volume
by bianca@linux.vnet.ibm.com
From: Bianca Carvalho <bianca(a)linux.vnet.ibm.com>
Edited function get_disk_used_by in diskutils.py file to remove
used_by verification in objstore and edited all function calls.
Also removed set_disk_used_by function from diskutils.py.
Signed-off-by: Bianca Carvalho <bianca(a)linux.vnet.ibm.com>
---
model/diskutils.py | 61 ++++++++++---------------------------------------
model/storagevolumes.py | 14 ++----------
model/vms.py | 11 ---------
model/vmstorages.py | 15 +++---------
4 files changed, 17 insertions(+), 84 deletions(-)
diff --git a/model/diskutils.py b/model/diskutils.py
index 6faab7c..a3162d7 100644
--- a/model/diskutils.py
+++ b/model/diskutils.py
@@ -17,10 +17,6 @@
# 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 wok.exception import OperationFailed, NotFoundError
-from wok.utils import wok_log
-
-from wok.plugins.kimchi.config import get_kimchi_version
from wok.plugins.kimchi.model.vms import VMModel, VMsModel
from wok.plugins.kimchi.xmlutils.disk import get_vm_disk_info, get_vm_disks
@@ -31,49 +27,16 @@ from wok.plugins.kimchi.xmlutils.disk import get_vm_disk_info, get_vm_disks
"""
-def get_disk_used_by(objstore, conn, path):
- try:
- with objstore as session:
- try:
- used_by = session.get('storagevolume', path)['used_by']
- except (KeyError, NotFoundError):
- wok_log.info('Volume %s not found in obj store.' % path)
- used_by = []
- # try to find this volume in existing vm
- vms_list = VMsModel.get_vms(conn)
- for vm in vms_list:
- dom = VMModel.get_vm(vm, conn)
- storages = get_vm_disks(dom)
- for disk in storages.keys():
- d_info = get_vm_disk_info(dom, disk)
- if path == d_info['path']:
- used_by.append(vm)
- try:
- session.store('storagevolume', path,
- {'used_by': used_by},
- get_kimchi_version())
- except Exception as e:
- # Let the exception be raised. If we allow disks'
- # used_by to be out of sync, data corruption could
- # occour if a disk is added to two guests
- # unknowingly.
- wok_log.error('Unable to store storage volume id in'
- ' objectstore due error: %s',
- e.message)
- raise OperationFailed('KCHVOL0017E',
- {'err': 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
- # to avoid conflict with the __exit__ function of 'with'
- raise OperationFailed('KCHVOL0017E', {'err': e.message})
- return used_by
-
+def get_disk_used_by(conn, path):
+ used_by = []
+ # try to find this volume in existing vm
+ vms_list = VMsModel.get_vms(conn)
+ for vm in vms_list:
+ dom = VMModel.get_vm(vm, conn)
+ storages = get_vm_disks(dom)
+ for disk in storages.keys():
+ d_info = get_vm_disk_info(dom, disk)
+ if path == d_info['path']:
+ used_by.append(vm)
-def set_disk_used_by(objstore, path, new_used_by):
- try:
- with objstore as session:
- session.store('storagevolume', path, {'used_by': new_used_by},
- get_kimchi_version())
- except Exception as e:
- raise OperationFailed('KCHVOL0017E', {'err': e.message})
+ return used_by
diff --git a/model/storagevolumes.py b/model/storagevolumes.py
index 4708674..a6ce97b 100644
--- a/model/storagevolumes.py
+++ b/model/storagevolumes.py
@@ -40,7 +40,6 @@ from wok.plugins.kimchi.config import READONLY_POOL_TYPE
from wok.plugins.kimchi.isoinfo import IsoImage
from wok.plugins.kimchi.kvmusertests import UserTests
from wok.plugins.kimchi.model.diskutils import get_disk_used_by
-from wok.plugins.kimchi.model.diskutils import set_disk_used_by
from wok.plugins.kimchi.model.storagepools import StoragePoolModel
from wok.plugins.kimchi.utils import get_next_clone_name
@@ -163,9 +162,7 @@ class StorageVolumesModel(object):
vol_info = StorageVolumeModel(conn=self.conn,
objstore=self.objstore).lookup(pool_name,
name)
-
vol_path = vol_info['path']
- set_disk_used_by(self.objstore, vol_info['path'], [])
if params.get('upload', False):
upload_volumes[vol_path] = {'lock': threading.Lock(),
@@ -251,11 +248,6 @@ class StorageVolumesModel(object):
finally:
os.remove(file_path)
- vol_info = StorageVolumeModel(conn=self.conn,
- objstore=self.objstore).lookup(pool_name,
- name)
- set_disk_used_by(self.objstore, vol_info['path'], [])
-
cb('OK', True)
def get_list(self, pool_name):
@@ -335,7 +327,7 @@ class StorageVolumeModel(object):
except UnicodeDecodeError:
isvalid = False
- used_by = get_disk_used_by(self.objstore, self.conn, path)
+ used_by = get_disk_used_by(self.conn, path)
if (self.libvirt_user is None):
self.libvirt_user = UserTests().probe_user()
ret, _ = probe_file_permission_as_user(path, self.libvirt_user)
@@ -493,9 +485,7 @@ class StorageVolumeModel(object):
'pool': orig_pool_name,
'err': e.get_error_message()})
- new_vol = self.lookup(new_pool_name, new_vol_name)
- cb('adding volume to the object store')
- set_disk_used_by(self.objstore, new_vol['path'], [])
+ self.lookup(new_pool_name, new_vol_name)
cb('OK', True)
diff --git a/model/vms.py b/model/vms.py
index 7f607f5..b2ee122 100644
--- a/model/vms.py
+++ b/model/vms.py
@@ -1398,17 +1398,6 @@ class VMModel(object):
except Exception as e:
raise OperationFailed('KCHVOL0017E', {'err': e.message})
- try:
- with self.objstore as session:
- if path in session.get_list('storagevolume'):
- used_by = session.get('storagevolume', path)['used_by']
- used_by.remove(name)
- session.store('storagevolume', path,
- {'used_by': used_by},
- get_kimchi_version())
- except Exception as e:
- raise OperationFailed('KCHVOL0017E', {'err': e.message})
-
try:
with self.objstore as session:
session.delete('vm', dom.UUIDString(), ignore_missing=True)
diff --git a/model/vmstorages.py b/model/vmstorages.py
index b55b156..2e9f783 100644
--- a/model/vmstorages.py
+++ b/model/vmstorages.py
@@ -26,7 +26,6 @@ from wok.utils import wok_log
from wok.plugins.kimchi.model.config import CapabilitiesModel
from wok.plugins.kimchi.model.diskutils import get_disk_used_by
-from wok.plugins.kimchi.model.diskutils import set_disk_used_by
from wok.plugins.kimchi.model.storagevolumes import StorageVolumeModel
from wok.plugins.kimchi.model.utils import get_vm_config_flag
from wok.plugins.kimchi.model.vms import DOM_STATE_MAP, VMModel
@@ -151,7 +150,6 @@ class VMStoragesModel(object):
if params.get('vol'):
used_by = vol_info['used_by']
used_by.append(vm_name)
- set_disk_used_by(self.objstore, params['path'], used_by)
return dev
@@ -191,7 +189,7 @@ class VMStorageModel(object):
# in the obj store, its ref count would have been updated
# by get_disk_used_by()
if path is not None:
- used_by = get_disk_used_by(self.objstore, self.conn, path)
+ used_by = get_disk_used_by(self.conn, path)
else:
wok_log.error("Unable to decrement volume used_by on"
" delete because no path could be found.")
@@ -202,7 +200,6 @@ class VMStorageModel(object):
if used_by is not None and vm_name in used_by:
used_by.remove(vm_name)
- set_disk_used_by(self.objstore, path, used_by)
else:
wok_log.error("Unable to update %s:%s used_by on delete."
% (vm_name, dev_name))
@@ -223,11 +220,9 @@ class VMStorageModel(object):
if new_disk_path != old_disk_path:
# An empty path means a CD-ROM was empty or ejected:
if old_disk_path is not '':
- old_disk_used_by = get_disk_used_by(
- self.objstore, self.conn, old_disk_path)
+ old_disk_used_by = get_disk_used_by(self.conn, old_disk_path)
if new_disk_path is not '':
- new_disk_used_by = get_disk_used_by(
- self.objstore, self.conn, new_disk_path)
+ new_disk_used_by = get_disk_used_by(self.conn, new_disk_path)
dev_info.update(params)
dev, xml = get_disk_xml(dev_info)
@@ -241,12 +236,8 @@ class VMStorageModel(object):
if old_disk_used_by is not None and \
vm_name in old_disk_used_by:
old_disk_used_by.remove(vm_name)
- set_disk_used_by(self.objstore, old_disk_path,
- old_disk_used_by)
if new_disk_used_by is not None:
new_disk_used_by.append(vm_name)
- set_disk_used_by(self.objstore, new_disk_path,
- new_disk_used_by)
except Exception as e:
wok_log.error("Unable to update dev used_by on update due to"
" %s:" % e.message)
--
2.7.4
8 years, 3 months
[PATCH v3] [Kimchi] Feature request (#860): Support Guest Autostart
by bianca@linux.vnet.ibm.com
From: Bianca Carvalho <bianca(a)linux.vnet.ibm.com>
Include 'autostart' option in API.json and vms.py (lookup and update)
using libvirt dom.setAutostart to set as true or false. Also edit
test_model.py to include those changes and updated API.md file.
Also included API tests to test_rest.py in test_edit_vm function.
Signed-off-by: Bianca Carvalho <bianca(a)linux.vnet.ibm.com>
---
API.json | 4 ++++
docs/API.md | 2 ++
model/vms.py | 12 +++++++++---
tests/test_model.py | 6 ++++++
tests/test_rest.py | 18 ++++++++++++++++++
5 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/API.json b/API.json
index 4fdd522..4946069 100644
--- a/API.json
+++ b/API.json
@@ -322,6 +322,10 @@
"error": "KCHVM0053E",
"type": "boolean"
},
+ "autostart": {
+ "description": "Enable/Disable guest autostart",
+ "type": "boolean"
+ },
"users": {
"description": "Array of users who have permission to the VM",
"type": "array",
diff --git a/docs/API.md b/docs/API.md
index b07bf16..9f30666 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -147,6 +147,7 @@ server.
* groups: A list of system groups whose users have permission to access
the VM. Default is: empty (i.e. no groups given access).
* bootorder: list of devices in boot order
+ * autostart: show if autostart is enabled.
* **DELETE**: Remove the Virtual Machine
* **PUT**: update the parameters of existing VM
* name: New name for this VM (only applied for shutoff VM)
@@ -177,6 +178,7 @@ server.
* threads - The number of threads per core.
* bootorder: guest bootorder, types accepted: hd, cdrom, network or fd
* bootmenu: prompts guest bootmenu. Bool type.
+ * autostart: enable/disable guest autostart (true or false params).
* **POST**: *See Virtual Machine Actions*
diff --git a/model/vms.py b/model/vms.py
index 433770a..cfe4c97 100644
--- a/model/vms.py
+++ b/model/vms.py
@@ -79,11 +79,13 @@ DOM_STATE_MAP = {0: 'nostate',
7: 'pmsuspended'}
# update parameters which are updatable when the VM is online
-VM_ONLINE_UPDATE_PARAMS = ['graphics', 'groups', 'memory', 'users']
+VM_ONLINE_UPDATE_PARAMS = ['graphics', 'groups', 'memory', 'users',
+ 'autostart']
# update parameters which are updatable when the VM is offline
VM_OFFLINE_UPDATE_PARAMS = ['cpu_info', 'graphics', 'groups', 'memory',
- 'name', 'users', 'bootorder', 'bootmenu']
+ 'name', 'users', 'bootorder', 'bootmenu',
+ 'autostart']
XPATH_DOMAIN_DISK = "/domain/devices/disk[@device='disk']/source/@file"
XPATH_DOMAIN_DISK_BY_FILE = "./devices/disk[@device='disk']/source[@file='%s']"
@@ -261,6 +263,9 @@ class VMModel(object):
with lock:
dom = self.get_vm(name, self.conn)
+ if "autostart" in params:
+ dom.setAutostart(1 if params['autostart'] == True else 0)
+
# You can only change <maxMemory> offline, updating guest XML
if ("memory" in params) and ('maxmemory' in params['memory']) and\
(DOM_STATE_MAP[dom.info()[0]] != 'shutoff'):
@@ -1285,7 +1290,8 @@ class VMModel(object):
'access': 'full',
'persistent': True if dom.isPersistent() else False,
'bootorder': boot,
- 'bootmenu': bootmenu
+ 'bootmenu': bootmenu,
+ 'autostart': dom.autostart()
}
def _vm_get_disk_paths(self, dom):
diff --git a/tests/test_model.py b/tests/test_model.py
index 27225f8..7b1fbfe 100644
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -1369,6 +1369,12 @@ class ModelTests(unittest.TestCase):
inst.vm_update(u'пeω-∨м', {"bootmenu": False})
self.assertEquals("no", inst.vm_lookup(u'пeω-∨м')['bootmenu'])
+ # enable/disable autostart
+ inst.vm_update(u'пeω-∨м', {"autostart": True})
+ self.assertEquals("yes", inst.vm_lookup(u'пeω-∨м')['autostart'])
+ inst.vm_update(u'пeω-∨м', {"autostart": False})
+ self.assertEquals("no", inst.vm_lookup(u'пeω-∨м')['autostart'])
+
def test_get_interfaces(self):
inst = model.Model('test:///default',
objstore_loc=self.tmp_store)
diff --git a/tests/test_rest.py b/tests/test_rest.py
index 80596c2..0516e7c 100644
--- a/tests/test_rest.py
+++ b/tests/test_rest.py
@@ -301,6 +301,24 @@ class RestTests(unittest.TestCase):
resp = self.request('/plugins/kimchi/vms/∨м-црdαtеd', req, 'PUT')
self.assertEquals(400, resp.status)
+ # set vm autostart tests (powered)
+ resp = self.request('/plugins/kimchi/vms/vm-1/poweroff', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ req = json.dumps({"autostart": True})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/vms/vm-1', '{}', 'GET').read()
+ self.assertEquals(resp["autostart"], True)
+
+ # set vm autostart tests (running)
+ resp = self.request('/plugins/kimchi/vms/vm-1/start', '{}', 'POST')
+ self.assertEquals(200, resp.status)
+ req = json.dumps({"autostart": True})
+ resp = self.request('/plugins/kimchi/vms/vm-1', req, 'PUT')
+ self.assertEquals(200, resp.status)
+ resp = self.request('/plugins/kimchi/vms/vm-1', '{}', 'GET').read()
+ self.assertEquals(resp["autostart"], True)
+
def test_vm_lifecycle(self):
# Create a Template
req = json.dumps({'name': 'test',
--
2.7.4
8 years, 3 months
[PATCH V2] [Wok 0/2] Issue #122 - Make AsyncTask stoppable.
by pvital@linux.vnet.ibm.com
From: Paulo Vital <pvital(a)linux.vnet.ibm.com>
v2:
- Modified exception code used
- Updated i18n messages
V1:
This patch-set gives to user a way to 'stop' a Task that is still running by
setting the Task status to "killed".
Since an AsyncTask is basic a thread running in the system and this thread can
execute a pure Python method or a background command (by using run_command()
from wok.utils), the developer must pass to AsyncTask constructor a method to be
executed by the DELETE operation, called here as 'kill_cb'.
If none kill_cb is passed, the task will not be able to stopped and an error
message will be raised to user if DELETE operation is executed. Otherwise, the
kill_cb method will be executed by kill() method (responsible to execute the
DELETE operation) of AsyncTask class and its status set to 'killed'.
The unit tests present how you can use it.
Paulo Vital (2):
Issue #122 - Make AsyncTask stoppable.
Issue #122 - Add unit test to stop AsyncTask.
docs/API/tasks.md | 2 ++
src/wok/asynctask.py | 18 +++++++++++++++++-
src/wok/i18n.py | 2 ++
src/wok/model/tasks.py | 13 +++++++++++++
tests/test_api.py | 26 ++++++++++++++++++++++++--
tests/test_tasks.py | 19 ++++++++++++++++++-
6 files changed, 76 insertions(+), 4 deletions(-)
--
2.7.4
8 years, 3 months
[PATCH] [Wok 0/2] Issue #122 - Make AsyncTask stoppable.
by pvital@linux.vnet.ibm.com
From: Paulo Vital <pvital(a)linux.vnet.ibm.com>
This patch-set gives to user a way to 'stop' a Task that is still running by
setting the Task status to "killed".
Since an AsyncTask is basic a thread running in the system and this thread can
execute a pure Python method or a background command (by using run_command()
from wok.utils), the developer must pass to AsyncTask constructor a method to be
executed by the DELETE operation, called here as 'kill_cb'.
If none kill_cb is passed, the task will not be able to stopped and an error
message will be raised to user if DELETE operation is executed. Otherwise, the
kill_cb method will be executed by kill() method (responsible to execute the
DELETE operation) of AsyncTask class and its status set to 'killed'.
The unit tests present how you can use it.
Paulo Vital (2):
Issue #122 - Make AsyncTask stoppable.
Issue #122 - Add unit test to stop AsyncTask.
docs/API/tasks.md | 2 ++
src/wok/asynctask.py | 18 +++++++++++++++++-
src/wok/i18n.py | 1 +
src/wok/model/tasks.py | 13 +++++++++++++
tests/test_api.py | 26 ++++++++++++++++++++++++--
tests/test_tasks.py | 19 ++++++++++++++++++-
6 files changed, 75 insertions(+), 4 deletions(-)
--
2.7.4
8 years, 3 months
[RFC] Wok / Ginger sidebar
by Samuel Henrique De Oliveira Guimaraes
Hi team,
We currently have an issue with Ginger/Gingerbase navigation bar in small screen resolutions and we also have huge tables in System Services page. Since working on the navigation bar involves editing Wok styles, I'm sending this e-mail to Wok mailing list instead of Ginger group.
I looked for successful combinations of sidebar + horizontal navigation bars and so far I couldn't find any example that would exactly fit with Wok and its plugins. The majority of examples I'm listing below are very good with traditional pages with deep subcategories and the navigation bars can work as sitemaps and replace breadcrumbs:
* http://www.worldwildlife.org/ - https://vimeo.com/166812605
* https://www.theguardian.com/us - https://vimeo.com/166812599
* https://next.ft.com/fastft - https://vimeo.com/166812597
Wok currently has two navigation levels. Kimchi doesn't have multiple sections but Ginger and Gingerbase uses collapsible panel groups to separate sections that could be third level elements on a sidebar. This was already discussed when we moved some features from Ginger to Gingerbase but I think we could achieve a functional sidebar with up to three levels without using a "landing page" for second-level elements.
In the attached screenshots ginger_sidebar1 and ginger_sidebar2 are mockups for an off-canvas menu that would slide the main content and hide itself once an option is clicked. It would also hide the other panel accordions. Here are two off-canvas menu in action:
* http://codepen.io/SitePoint/full/uIemr/
* https://codepen.io/benske/full/cxrta/
Since this would require a change in Wok tabs and ginger/gingerbase tab-ext.xml, I think we could implement something entirely different that would with Wok and all plugins. This site menu only have first-level options on the sidebar but I think we could add collapsible links like a tree-table menu: https://www.sitepoint.com/
In addition to the sidebar, we could put a search/filter input on the top that would allow the user to type the desired option and show its position on the menu. Please take a look at the remaining attached screenshots. I did one variation with the content aligned to the center and another one aligned to the left.
Regards,
Samuel
8 years, 3 months
Re: [Kimchi-devel] [ginger-dev-list] Re: Fwd: [RFC] listing of ovs bridges
by Suresh Babu Angadi
On 08/30/2016 04:49 PM, Daniel Henrique Barboza wrote:
> Hi Suresh,
>
> Do you need only the listing of ovsbridges? Because there is a Gingerbase
> function that does that:
>
Hi Daniel,
I think we can go with this approach. Currently kimchi requires only ovs
bridge names.
So the API would remain the same, however backend implementation will
use ovs_bridges() method of netinfo.py.
> netinfo.py 183:
>
> def ovs_bridges():
> """Get the OVS Bridges of the host.
>
> In some distributions, like Fedora, the files bridge and brif are
> not created under /sys/class/net/<ovsbridge> for OVS bridges.
> These specific functions allows one to differentiate OVS bridges
> from other types of bridges.
>
> Returns:
> List[str]: a list with the OVS bridges found.
>
> """
>
>
>
> On 08/30/2016 03:18 AM, Suresh Babu Angadi wrote:
>> Hi All,
>> If there are no comments, I would go ahead and send patches.
>>
>> On 08/30/2016 11:46 AM, Suresh Babu Angadi wrote:
>>>
>>> Adding ginger mailing list, since it requires modifications in
>>> Ginger code.
>>>
>>> -------- Forwarded Message --------
>>> Subject: [Kimchi-devel] [RFC] listing of ovs bridges
>>> Date: Thu, 25 Aug 2016 16:33:39 +0530
>>> From: Suresh Babu Angadi <sureshab(a)linux.vnet.ibm.com>
>>> To: Kimchi Devel <kimchi-devel(a)ovirt.org>
>>>
>>>
>>>
>>> New API:
>>> SimpleCollection: OVSBridges
>>>
>>> URI: /plugins/kimchi/ovsbridges
>>>
>>> Methods:
>>>
>>> GET: Retrieve list of OVS bridges of the host
>>>
>>>
>>> Back end changes:
>>> Currently ginger plugin has full fledged ovs functionality. So best bet
>>> would be to have listing of ovs bridges to gingerbase which can be used
>>> by kimchi and ginger apis.
>>>
>>> --
>>> Regards,
>>> Suresh Babu Angadi
>>>
>>> _______________________________________________
>>> Kimchi-devel mailing list
>>> Kimchi-devel(a)ovirt.org
>>> http://lists.ovirt.org/mailman/listinfo/kimchi-devel
>>>
>>>
>>>
>>
>> --
>> Regards,
>> Suresh Babu Angadi
>> --
>> You received this message because you are subscribed to the Google
>> Groups "Ginger Development Mailing List" group.
>> To unsubscribe from this group and stop receiving emails from it,
>> send an email to ginger-dev-list+unsubscribe(a)googlegroups.com
>> <mailto:ginger-dev-list+unsubscribe@googlegroups.com>.
>> For more options, visit https://groups.google.com/d/optout.
>
> --
> You received this message because you are subscribed to the Google
> Groups "Ginger Development Mailing List" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to ginger-dev-list+unsubscribe(a)googlegroups.com
> <mailto:ginger-dev-list+unsubscribe@googlegroups.com>.
> For more options, visit https://groups.google.com/d/optout.
--
Regards,
Suresh Babu Angadi
8 years, 3 months
[PATCH V2] [Kimchi 0/2] Addition 'interfaces' parameter to template API.
by archus@linux.vnet.ibm.com
From: Archana Singh <archus(a)linux.vnet.ibm.com>
1) Code changes for additional param 'interfaces' to template API.
2) API.md changes for same.
Archana Singh (2):
Updated code to support 'interfaces' parameter to template API only on
s390x/s390 architecture.
Updated API.md for addition interfaces paramter in template API.
API.json | 35 +++++++++++++++++++++++++++-
control/templates.py | 1 +
docs/API.md | 12 ++++++++++
i18n.py | 6 +++++
model/templates.py | 17 ++++++++++++++
vmtemplate.py | 20 ++++++++++++++++
xmlutils/interface.py | 63 +++++++++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 153 insertions(+), 1 deletion(-)
--
2.7.4
8 years, 3 months
[PATCH] [Kimchi] mockmodel.py: fixing virtviewerfile_tmp path
by dhbarboza82@gmail.com
From: Daniel Henrique Barboza <danielhb(a)linux.vnet.ibm.com>
Instead of using relative path, use the path provided by
kimchi config. Otherwise, when running WoK tests, the
'wok/data/virtviewerfiles/' dir will be wrongly created
and used by the mockmodel.
Signed-off-by: Daniel Henrique Barboza <danielhb(a)linux.vnet.ibm.com>
---
mockmodel.py | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/mockmodel.py b/mockmodel.py
index cd06ee3..61e5ee1 100644
--- a/mockmodel.py
+++ b/mockmodel.py
@@ -33,6 +33,7 @@ from wok.objectstore import ObjectStore
from wok.utils import add_task, convert_data_size
from wok.xmlutils.utils import xml_item_update
+from wok.plugins.kimchi import config as kimchi_config
from wok.plugins.kimchi import imageinfo
from wok.plugins.kimchi import osinfo
from wok.plugins.kimchi.model import cpuinfo
@@ -141,7 +142,7 @@ class MockModel(Model):
cherrypy.engine.subscribe('exit', self.virtviewertmpfile_cleanup)
def _create_virt_viewer_tmp_file(self):
- path = '../data/virtviewerfiles/'
+ path = kimchi_config.get_virtviewerfiles_path()
if not os.path.isdir(path):
os.makedirs(path)
--
2.5.5
8 years, 3 months