[RFC]Listing storage devices to add to kimchi
by Pooja Kulkarni
New API:
SimpleCollection: Storage Devices
URI: /plugins/gingerbase/stgdevs
Methods:
GET: Retrieve list of block devices of the host
Ginger provides the listing of all available block devices
(plugins/ginger/stgdevs) on the host.
The idea is to move the base functions of REST API
plugins/ginger/stgdevs from ginger to gingerbase , so that kimchi APIs
can also use them to list available block devices ( to be added to a
template or a guest).
Let me know what you think.
Regards
Pooja Kulkarni
8 years, 3 months
Re: [Kimchi-devel] Fwd: [RFC] listing of ovs bridges
by Suresh Babu Angadi
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
8 years, 3 months
[RFC] changes to /plugins/kimchi/interfaces
by Suresh Babu Angadi
*Current Implementation:*
URI: /plugins/kimchi/interfaces
Methods:
* GET: Retrieve a summarized list of current Interfaces
Retrieves list of host interfaces, which are not in use by libvirt
networks.
*Proposal:*
URI: /plugins/kimchi/interfaces
*Methods:*
* GET: Retrieve summarized list of *all host* Interfaces
* Parameters: _inuse: true | false
if no filter mentioned then API lists all host interfaces
if inuse =“true" then API lists all host interfaces which are in use by
libvirt networks
if inuse=“false” then API lists available host interfaces, which are
not in use by libvirt networks.
*From UI point of view, current API call should be changed to
/plugins/kimchi/interfaces?_inuse='false' to keep the current
functionality unaffected.*
--
Regards,
Suresh Babu Angadi
8 years, 3 months
[PATCH] [Kimchi] Github #991: unsubscribing from exit bus on cleanup
by dhbarboza82@gmail.com
From: Daniel Henrique Barboza <danielhb(a)linux.vnet.ibm.com>
WoK tests are running the Cherrypy Exit bus multiple times
without executing the __init__ from Mockmodel. causing
the 'virtviewertmpfile_cleanup' callback to fail because
there is no temp file created (it was cleaned in a previous
callback).
Unsubscribing from the 'exit' bus in the cleanup solves the
issue, given that the subscription only happens in Mockmodel
__init__ .
Signed-off-by: Daniel Henrique Barboza <danielhb(a)linux.vnet.ibm.com>
---
mockmodel.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/mockmodel.py b/mockmodel.py
index cd06ee3..89f1187 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)
@@ -155,6 +156,7 @@ class MockModel(Model):
def virtviewertmpfile_cleanup(self):
os.unlink(self.virtviewerfile_tmp.name)
+ cherrypy.engine.unsubscribe('exit', self.virtviewertmpfile_cleanup)
def reset(self):
MockModel._mock_vms = defaultdict(list)
--
2.5.5
8 years, 3 months
[PATCH V6] [Wok 0/3] Issue #158: Move AsyncTask information to memory
by pvital@linux.vnet.ibm.com
From: Paulo Vital <pvital(a)linux.vnet.ibm.com>
V6:
- Fixed import order
- Improved AsyncTask.remove()
- Baked banana and cinnamon cupcakes
V5:
- Moved remove_tasks() to AsyncTask class.
V4:
- Fix usage of UUID to prevent "UUID Is not JSON Serializable" error
V3:
- Changes in how create AsyncTask
V2:
- moved all tasks_queue infrastructure to wok.asynctask
- modified some user messages.
V1:
this patch-set moves AsyncTask information from objectstore to memory and it
is dependency to solve Issue #122.
Paulo Vital (3):
Issue #158: Move AsyncTask information to memory
Issue #158: Update model/tasks.py with AsyncTasks in memory.
Issue #158: Add AsyncTasks testcases
src/wok/asynctask.py | 48 +++++++++++--------
src/wok/i18n.py | 3 +-
src/wok/model/tasks.py | 22 +++++----
src/wok/objectstore.py | 6 ---
src/wok/utils.py | 19 --------
tests/test_tasks.py | 124 +++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 166 insertions(+), 56 deletions(-)
create mode 100644 tests/test_tasks.py
--
2.7.4
8 years, 3 months
[PATCH V2] [Kimchi] Update usage of add_task() method.
by pvital@linux.vnet.ibm.com
From: Paulo Vital <pvital(a)linux.vnet.ibm.com>
After move AsyncTask to memory, the call to add a new task has changed.
This patch updates all add_task() calls to address the new way.
Signed-off-by: Paulo Vital <pvital(a)linux.vnet.ibm.com>
---
mockmodel.py | 9 +++++----
model/storagepools.py | 7 ++++---
model/storagevolumes.py | 9 +++++----
model/vmhostdevs.py | 26 +++++++++++++-------------
model/vms.py | 18 +++++++++---------
model/vmsnapshots.py | 6 +++---
tests/test_model.py | 21 ++++++++++-----------
tests/test_rest.py | 15 ++++++---------
8 files changed, 55 insertions(+), 56 deletions(-)
diff --git a/mockmodel.py b/mockmodel.py
index cd06ee3..d0ba8bd 100644
--- a/mockmodel.py
+++ b/mockmodel.py
@@ -28,9 +28,10 @@ from collections import defaultdict
from lxml import objectify
from lxml.builder import E
+from wok.asynctask import AsyncTask
from wok.exception import NotFoundError, OperationFailed
from wok.objectstore import ObjectStore
-from wok.utils import add_task, convert_data_size
+from wok.utils import convert_data_size
from wok.xmlutils.utils import xml_item_update
from wok.plugins.kimchi import imageinfo
@@ -416,9 +417,9 @@ class MockModel(Model):
def _mock_vmsnapshots_create(self, vm_name, params):
name = params.get('name', unicode(int(time.time())))
params = {'vm_name': vm_name, 'name': name}
- taskid = add_task(u'/plugins/kimchi/vms/%s/snapshots/%s' %
- (vm_name, name), self._vmsnapshots_create_task,
- self.objstore, params)
+ taskid = AsyncTask(u'/plugins/kimchi/vms/%s/snapshots/%s' %
+ (vm_name, name), self._vmsnapshots_create_task,
+ params).id
return self.task_lookup(taskid)
def _vmsnapshots_create_task(self, cb, params):
diff --git a/model/storagepools.py b/model/storagepools.py
index a2dbaec..92d6436 100644
--- a/model/storagepools.py
+++ b/model/storagepools.py
@@ -21,9 +21,10 @@ import libvirt
import lxml.etree as ET
from lxml.builder import E
+from wok.asynctask import AsyncTask
from wok.exception import InvalidOperation, MissingParameter
from wok.exception import NotFoundError, OperationFailed
-from wok.utils import add_task, run_command, wok_log
+from wok.utils import run_command, wok_log
from wok.xmlutils.utils import xpath_get_text
from wok.plugins.kimchi.config import config, get_kimchi_version, kimchiPaths
@@ -252,8 +253,8 @@ class StoragePoolsModel(object):
params['path'] = self.scanner.scan_dir_prepare(params['name'])
scan_params['pool_path'] = params['path']
- task_id = add_task('/plugins/kimchi/storagepools/%s' % ISO_POOL_NAME,
- self.scanner.start_scan, self.objstore, scan_params)
+ task_id = AsyncTask('/plugins/kimchi/storagepools/%s' % ISO_POOL_NAME,
+ self.scanner.start_scan, scan_params).id
# Record scanning-task/storagepool mapping for future querying
try:
with self.objstore as session:
diff --git a/model/storagevolumes.py b/model/storagevolumes.py
index 7b2272b..4708674 100644
--- a/model/storagevolumes.py
+++ b/model/storagevolumes.py
@@ -28,9 +28,10 @@ import time
import urllib2
from lxml.builder import E
+from wok.asynctask import AsyncTask
from wok.exception import InvalidOperation, InvalidParameter, IsoFormatError
from wok.exception import MissingParameter, NotFoundError, OperationFailed
-from wok.utils import add_task, get_unique_file_name
+from wok.utils import get_unique_file_name
from wok.utils import probe_file_permission_as_user, wok_log
from wok.xmlutils.utils import xpath_get_text
from wok.model.tasks import TaskModel
@@ -124,7 +125,7 @@ class StorageVolumesModel(object):
params['pool'] = pool_name
targeturi = '/plugins/kimchi/storagepools/%s/storagevolumes/%s' \
% (pool_name, name)
- taskid = add_task(targeturi, create_func, self.objstore, params)
+ taskid = AsyncTask(targeturi, create_func, params).id
return self.task.lookup(taskid)
def _create_volume_with_capacity(self, cb, params):
@@ -441,8 +442,8 @@ class StorageVolumeModel(object):
'new_pool': new_pool,
'new_name': new_name}
target_uri = u'/plugins/kimchi/storagepools/%s/storagevolumes/%s/clone'
- taskid = add_task(target_uri % (pool, new_name), self._clone_task,
- self.objstore, params)
+ taskid = AsyncTask(target_uri % (pool, new_name), self._clone_task,
+ params).id
return self.task.lookup(taskid)
def _clone_task(self, cb, params):
diff --git a/model/vmhostdevs.py b/model/vmhostdevs.py
index e2299e2..0c89959 100644
--- a/model/vmhostdevs.py
+++ b/model/vmhostdevs.py
@@ -26,12 +26,13 @@ from lxml import etree, objectify
from lxml.builder import E, ElementMaker
from operator import itemgetter
+from wok.asynctask import AsyncTask
from wok.exception import InvalidOperation, InvalidParameter, NotFoundError
from wok.exception import OperationFailed
from wok.message import WokMessage
from wok.model.tasks import TaskModel
from wok.rollbackcontext import RollbackContext
-from wok.utils import add_task, run_command, wok_log
+from wok.utils import run_command, wok_log
from wok.plugins.kimchi.model.config import CapabilitiesModel
from wok.plugins.kimchi.model.host import DeviceModel, DevicesModel
@@ -92,11 +93,11 @@ class VMHostDevsModel(object):
dev_info = self.dev_model.lookup(dev_name)
if dev_info['device_type'] == 'pci':
- taskid = add_task(u'/plugins/kimchi/vms/%s/hostdevs/' %
- VMModel.get_vm(vmid, self.conn).name(),
- self._attach_pci_device, self.objstore,
- {'vmid': vmid, 'dev_info': dev_info,
- 'lock': threading.RLock()})
+ taskid = AsyncTask(u'/plugins/kimchi/vms/%s/hostdevs/' %
+ VMModel.get_vm(vmid, self.conn).name(),
+ self._attach_pci_device,
+ {'vmid': vmid, 'dev_info': dev_info,
+ 'lock': threading.RLock()}).id
return self.task.lookup(taskid)
with RollbackContext() as rollback:
@@ -110,11 +111,11 @@ class VMHostDevsModel(object):
rollback.commitAll()
- taskid = add_task(u'/plugins/kimchi/vms/%s/hostdevs/' %
- VMModel.get_vm(vmid, self.conn).name(),
- '_attach_%s_device' % dev_info['device_type'],
- self.objstore, {'vmid': vmid, 'dev_info': dev_info,
- 'lock': threading.RLock()})
+ taskid = AsyncTask(u'/plugins/kimchi/vms/%s/hostdevs/' %
+ VMModel.get_vm(vmid, self.conn).name(),
+ '_attach_%s_device' % dev_info['device_type'],
+ {'vmid': vmid, 'dev_info': dev_info,
+ 'lock': threading.RLock()}).id
return self.task.lookup(taskid)
@@ -604,8 +605,7 @@ class VMHostDevModel(object):
'lock': threading.RLock()}
task_uri = u'/plugins/kimchi/vms/%s/hostdevs/%s' % \
(VMModel.get_vm(vmid, self.conn).name(), dev_name)
- taskid = add_task(task_uri, self._detach_device, self.objstore,
- task_params)
+ taskid = AsyncTask(task_uri, self._detach_device, task_params).id
return self.task.lookup(taskid)
def _event_devices(self, conn, dom, alias, opaque):
diff --git a/model/vms.py b/model/vms.py
index 3380278..7f607f5 100644
--- a/model/vms.py
+++ b/model/vms.py
@@ -34,12 +34,13 @@ from lxml import etree, objectify
from lxml.builder import E
from xml.etree import ElementTree
+from wok.asynctask import AsyncTask
from wok.config import config
from wok.exception import InvalidOperation, InvalidParameter
from wok.exception import NotFoundError, OperationFailed
from wok.model.tasks import TaskModel
from wok.rollbackcontext import RollbackContext
-from wok.utils import add_task, convert_data_size
+from wok.utils import convert_data_size
from wok.utils import import_class, run_setfacl_set_attr, run_command, wok_log
from wok.xmlutils.utils import dictize, xpath_get_text, xml_item_insert
from wok.xmlutils.utils import xml_item_remove, xml_item_update
@@ -144,8 +145,8 @@ class VMsModel(object):
'graphics': params.get('graphics', {}),
"title": params.get("title", ""),
"description": params.get("description", "")}
- taskid = add_task(u'/plugins/kimchi/vms/%s' % name, self._create_task,
- self.objstore, data)
+ taskid = AsyncTask(u'/plugins/kimchi/vms/%s' % name, self._create_task,
+ data).id
return self.task.lookup(taskid)
@@ -349,9 +350,9 @@ class VMModel(object):
new_name = get_next_clone_name(current_vm_names, name, ts=True)
# create a task with the actual clone function
- taskid = add_task(u'/plugins/kimchi/vms/%s/clone' % new_name,
- self._clone_task, self.objstore,
- {'name': name, 'new_name': new_name})
+ taskid = AsyncTask(u'/plugins/kimchi/vms/%s/clone' % new_name,
+ self._clone_task, {'name': name,
+ 'new_name': new_name}).id
return self.task.lookup(taskid)
@@ -1898,9 +1899,8 @@ class VMModel(object):
'non_shared': non_shared,
'remote_host': remote_host,
'user': user}
- task_id = add_task('/plugins/kimchi/vms/%s/migrate' % name,
- self._migrate_task,
- self.objstore, params)
+ task_id = AsyncTask('/plugins/kimchi/vms/%s/migrate' % name,
+ self._migrate_task, params).id
return self.task.lookup(task_id)
diff --git a/model/vmsnapshots.py b/model/vmsnapshots.py
index 6f2483c..6589306 100644
--- a/model/vmsnapshots.py
+++ b/model/vmsnapshots.py
@@ -23,8 +23,8 @@ import time
from lxml import objectify
from lxml.builder import E
+from wok.asynctask import AsyncTask
from wok.exception import InvalidOperation, NotFoundError, OperationFailed
-from wok.utils import add_task
from wok.xmlutils.utils import xpath_get_text
from wok.model.tasks import TaskModel
@@ -74,8 +74,8 @@ class VMSnapshotsModel(object):
name = params.get('name', unicode(int(time.time())))
task_params = {'vm_name': vm_name, 'name': name}
- taskid = add_task(u'/plugins/kimchi/vms/%s/snapshots/%s' % (vm_name,
- name), self._create_task, self.objstore, task_params)
+ taskid = AsyncTask(u'/plugins/kimchi/vms/%s/snapshots/%s' % (vm_name,
+ name), self._create_task, task_params).id
return self.task.lookup(taskid)
def _create_task(self, cb, params):
diff --git a/tests/test_model.py b/tests/test_model.py
index e77d4fd..d9ffd5e 100644
--- a/tests/test_model.py
+++ b/tests/test_model.py
@@ -36,12 +36,13 @@ from mock import call, mock_open, patch
import tests.utils as utils
import wok.objectstore
+from wok.asynctask import AsyncTask
from wok.basemodel import Singleton
from wok.config import config
from wok.exception import InvalidOperation
from wok.exception import InvalidParameter, NotFoundError, OperationFailed
from wok.rollbackcontext import RollbackContext
-from wok.utils import add_task, convert_data_size, get_task_id
+from wok.utils import convert_data_size
from wok.xmlutils.utils import xpath_get_text
from wok.plugins.gingerbase import netinfo
@@ -1401,30 +1402,28 @@ class ModelTests(unittest.TestCase):
inst = model.Model('test:///default',
objstore_loc=self.tmp_store)
- taskid = add_task('', quick_op, inst.objstore, 'Hello')
+ taskid = AsyncTask('', quick_op, 'Hello').id
inst.task_wait(taskid)
- self.assertEquals(get_task_id(), taskid)
self.assertEquals('finished', inst.task_lookup(taskid)['status'])
self.assertEquals('Hello', inst.task_lookup(taskid)['message'])
- taskid = add_task('', long_op, inst.objstore,
- {'delay': 3, 'result': False,
- 'message': 'It was not meant to be'})
- self.assertEquals(get_task_id(), taskid)
+ params = {'delay': 3, 'result': False,
+ 'message': 'It was not meant to be'}
+ taskid = AsyncTask('', long_op, params).id
self.assertEquals('running', inst.task_lookup(taskid)['status'])
- self.assertEquals('OK', inst.task_lookup(taskid)['message'])
+ self.assertEquals('The request is being processing.',
+ inst.task_lookup(taskid)['message'])
inst.task_wait(taskid)
self.assertEquals('failed', inst.task_lookup(taskid)['status'])
self.assertEquals('It was not meant to be',
inst.task_lookup(taskid)['message'])
- taskid = add_task('', abnormal_op, inst.objstore, {})
+ taskid = AsyncTask('', abnormal_op, {}).id
inst.task_wait(taskid)
self.assertEquals('Exception raised',
inst.task_lookup(taskid)['message'])
self.assertEquals('failed', inst.task_lookup(taskid)['status'])
- taskid = add_task('', continuous_ops, inst.objstore,
- {'result': True})
+ taskid = AsyncTask('', continuous_ops, {'result': True}).id
self.assertEquals('running', inst.task_lookup(taskid)['status'])
inst.task_wait(taskid, timeout=10)
self.assertEquals('finished', inst.task_lookup(taskid)['status'])
diff --git a/tests/test_rest.py b/tests/test_rest.py
index 80596c2..90a808a 100644
--- a/tests/test_rest.py
+++ b/tests/test_rest.py
@@ -30,8 +30,8 @@ from functools import partial
from tests.utils import get_free_port, patch_auth, request
from tests.utils import run_server, wait_task
+from wok.asynctask import AsyncTask
from wok.rollbackcontext import RollbackContext
-from wok.utils import add_task
from wok.plugins.kimchi import mockmodel
from wok.plugins.kimchi.osinfo import get_template_default
@@ -1305,22 +1305,19 @@ class RestTests(unittest.TestCase):
)
def test_tasks(self):
- id1 = add_task('/plugins/kimchi/tasks/1', self._async_op,
- model.objstore)
- id2 = add_task('/plugins/kimchi/tasks/2', self._except_op,
- model.objstore)
- id3 = add_task('/plugins/kimchi/tasks/3', self._intermid_op,
- model.objstore)
+ id1 = AsyncTask('/plugins/kimchi/tasks/1', self._async_op).id
+ id2 = AsyncTask('/plugins/kimchi/tasks/2', self._except_op).id
+ id3 = AsyncTask('/plugins/kimchi/tasks/3', self._intermid_op).id
target_uri = urllib2.quote('^/plugins/kimchi/tasks/*', safe="")
filter_data = 'status=running&target_uri=%s' % target_uri
tasks = json.loads(
self.request('/plugins/kimchi/tasks?%s' % filter_data).read()
)
- self.assertEquals(3, len(tasks))
+ self.assertLessEqual(3, len(tasks))
tasks = json.loads(self.request('/plugins/kimchi/tasks').read())
- tasks_ids = [int(t['id']) for t in tasks]
+ tasks_ids = [t['id'] for t in tasks]
self.assertEquals(set([id1, id2, id3]) - set(tasks_ids), set([]))
wait_task(self._task_lookup, id2)
foo2 = json.loads(
--
2.7.4
8 years, 3 months
[PATCH V5] [Wok 0/3] Issue #158: Move AsyncTask information to memory
by pvital@linux.vnet.ibm.com
From: Paulo Vital <pvital(a)linux.vnet.ibm.com>
V5:
- Moved remove_tasks() to AsyncTask class.
V4:
- Fix usage of UUID to prevent "UUID Is not JSON Serializable" error
V3:
- Changes in how create AsyncTask
V2:
- moved all tasks_queue infrastructure to wok.asynctask
- modified some user messages.
V1:
this patch-set moves AsyncTask information from objectstore to memory and it
is dependency to solve Issue #122.
Paulo Vital (3):
Issue #158: Move AsyncTask information to memory
Issue #158: Update model/tasks.py with AsyncTasks in memory.
Issue #158: Add AsyncTasks testcases
src/wok/asynctask.py | 48 +++++++++++--------
src/wok/i18n.py | 3 +-
src/wok/model/tasks.py | 22 +++++----
src/wok/objectstore.py | 6 ---
src/wok/utils.py | 19 --------
tests/test_tasks.py | 124 +++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 166 insertions(+), 56 deletions(-)
create mode 100644 tests/test_tasks.py
--
2.7.4
8 years, 3 months
[PATCH v2] [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.
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 ++++++
4 files changed, 21 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)
--
2.7.4
8 years, 3 months
[PATCH V2] [Kimchi] Only on s390x add default networks to template if template.conf has default network configuration uncommented.
by archus@linux.vnet.ibm.com
From: Archana Singh <archus(a)linux.vnet.ibm.com>
Below are the changes done for s390x architecture to only add default networks
to template if template.conf has network configuration uncommented
otherwise do not add any network by default.
1) Only on s390x, osinfo._get_tmpl_defaults() does not add
default network in case template.conf has commented out network configuration.
2) Only on s390x, NetworksModel._check_default_networks() does
not throw key error if networks not found in tmpl_defaults.
3) Only on s390x, VMTemplate.validate_integrity() does not throw
key error if networks not found in the template.
4) Only on s390x, LibvirtVMTemplate._network_validate() does not
throw key error on s390x if networks not found in tmpl_default, as on s390x networks is optional.
5) Only on s390x, VMTemplate._get_network_xml() does
return empty string and does not throw key error if networks not found in template object.
6) Only on s390x, control/templates.py gets networks as [] if not found
self.info.
7) Added method is_running_on_s390x in kimchi's utils.
Signed-off-by: Archana Singh <archus(a)linux.vnet.ibm.com>
---
control/templates.py | 2 +-
model/networks.py | 7 ++++++-
model/templates.py | 6 +++++-
osinfo.py | 14 +++++++++++++-
utils.py | 11 +++++++++++
vmtemplate.py | 17 ++++++++++++++---
6 files changed, 50 insertions(+), 7 deletions(-)
diff --git a/control/templates.py b/control/templates.py
index bb2e068..2dd8601 100644
--- a/control/templates.py
+++ b/control/templates.py
@@ -67,7 +67,7 @@ class Template(Resource):
'memory': self.info['memory'],
'cdrom': self.info.get('cdrom', None),
'disks': self.info['disks'],
- 'networks': self.info['networks'],
+ 'networks': self.info.get('networks', []),
'folder': self.info.get('folder', []),
'graphics': self.info['graphics'],
'cpu_info': self.info.get('cpu_info')
diff --git a/model/networks.py b/model/networks.py
index 35431d4..603a31c 100644
--- a/model/networks.py
+++ b/model/networks.py
@@ -35,6 +35,7 @@ from wok.plugins.kimchi import network as knetwork
from wok.plugins.kimchi.config import kimchiPaths
from wok.plugins.kimchi.model.config import CapabilitiesModel
from wok.plugins.kimchi.osinfo import defaults as tmpl_defaults
+from wok.plugins.kimchi.utils import is_running_on_s390x
from wok.plugins.kimchi.xmlutils.interface import get_iface_xml
from wok.plugins.kimchi.xmlutils.network import create_linux_bridge_xml
from wok.plugins.kimchi.xmlutils.network import create_vlan_tagged_bridge_xml
@@ -55,7 +56,11 @@ class NetworksModel(object):
self.caps = CapabilitiesModel(**kargs)
def _check_default_networks(self):
- networks = list(set(tmpl_defaults['networks']))
+ if is_running_on_s390x():
+ networks = list(set(tmpl_defaults.get('networks', [])))
+ else:
+ networks = list(set(tmpl_defaults['networks']))
+
conn = self.conn.get()
for net_name in networks:
diff --git a/model/templates.py b/model/templates.py
index a299c85..387e4f1 100644
--- a/model/templates.py
+++ b/model/templates.py
@@ -35,6 +35,7 @@ from wok.plugins.kimchi.config import get_kimchi_version
from wok.plugins.kimchi.kvmusertests import UserTests
from wok.plugins.kimchi.model.cpuinfo import CPUInfoModel
from wok.plugins.kimchi.utils import is_libvirtd_up, pool_name_from_uri
+from wok.plugins.kimchi.utils import is_running_on_s390x
from wok.plugins.kimchi.vmtemplate import VMTemplate
ISO_TYPE = "ISO 9660 CD-ROM"
@@ -358,7 +359,10 @@ class LibvirtVMTemplate(VMTemplate):
return sorted(map(lambda x: x.decode('utf-8'), names))
def _network_validate(self):
- names = self.info['networks']
+ if is_running_on_s390x():
+ names = self.info.get('networks', [])
+ else:
+ names = self.info['networks']
for name in names:
try:
conn = self.conn.get()
diff --git a/osinfo.py b/osinfo.py
index 2c59312..af37c72 100644
--- a/osinfo.py
+++ b/osinfo.py
@@ -138,10 +138,22 @@ def _get_tmpl_defaults():
'pool': '/plugins/kimchi/storagepools/default'}},
'processor': {'vcpus': '1', 'maxvcpus': 1},
'graphics': {'type': 'spice', 'listen': '127.0.0.1'}}
+
+ The default values on s390x architecture:
+
+ {'memory': {'current': 1024, 'maxmemory': 1024},
+ 'storage': { 'disk.0': {'format': 'qcow2', 'size': '10',
+ 'pool': '/plugins/kimchi/storagepools/default'}},
+ 'processor': {'vcpus': '1', 'maxvcpus': 1},
+ 'graphics': {'type': 'spice', 'listen': '127.0.0.1'}}
"""
# Create dict with default values
tmpl_defaults = defaultdict(dict)
- tmpl_defaults['main']['networks'] = ['default']
+
+ host_arch = _get_arch()
+ if host_arch not in ['s390x']:
+ tmpl_defaults['main']['networks'] = ['default']
+
tmpl_defaults['memory'] = {'current': _get_default_template_mem(),
'maxmemory': _get_default_template_mem()}
tmpl_defaults['storage']['disk.0'] = {'size': 10, 'format': 'qcow2',
diff --git a/utils.py b/utils.py
index 26d3cf6..b88740a 100644
--- a/utils.py
+++ b/utils.py
@@ -20,6 +20,7 @@
import contextlib
import json
+import os
import platform
import re
import sqlite3
@@ -272,3 +273,13 @@ def is_libvirtd_up():
output, error, rc = run_command(cmd, silent=True)
return True if output == 'active\n' else False
+
+
+def is_running_on_s390x():
+ """
+ Checks if running on s390x.
+ """
+ if os.uname()[4] == 's390x':
+ return True
+ else:
+ return False
diff --git a/vmtemplate.py b/vmtemplate.py
index 7ac0541..f5405fa 100644
--- a/vmtemplate.py
+++ b/vmtemplate.py
@@ -288,7 +288,13 @@ class VMTemplate(object):
networks = ""
params = {'type': 'network',
'model': self.info['nic_model']}
- for nw in self.info['networks']:
+
+ if self.info.get('arch') == 's390x':
+ info_networks = self.info.get('networks', [])
+ else:
+ info_networks = self.info['networks']
+
+ for nw in info_networks:
params['network'] = nw
networks += get_iface_xml(params, self.info['arch'],
self.info['os_distro'],
@@ -353,7 +359,7 @@ class VMTemplate(object):
graphics.update(kwargs.get('graphics', {}))
# Graphics is not supported on s390x, this check will
# not add graphics tag in domain xml.
- if params['arch'] not in ['s390x']:
+ if params.get('arch') != 's390x':
params['graphics'] = get_graphics_xml(graphics)
libvirt_stream_protocols = kwargs.get('libvirt_stream_protocols', [])
@@ -487,7 +493,12 @@ class VMTemplate(object):
def validate_integrity(self):
invalid = {}
# validate networks integrity
- invalid_networks = list(set(self.info['networks']) -
+ if self.info.get('arch') == 's390x':
+ networks = self.info.get('networks', [])
+ else:
+ networks = self.info['networks']
+
+ invalid_networks = list(set(networks) -
set(self._get_all_networks_name()))
if invalid_networks:
invalid['networks'] = invalid_networks
--
2.7.4
8 years, 3 months
[PATCH V4] [Wok 0/3] Issue #158: Move AsyncTask information to memory
by pvital@linux.vnet.ibm.com
From: Paulo Vital <pvital(a)linux.vnet.ibm.com>
V4:
- Fix usage of UUID to prevent "UUID Is not JSON Serializable" error
V3:
- Changes in how create AsyncTask
V2:
- moved all tasks_queue infrastructure to wok.asynctask
- modified some user messages.
V1:
this patch-set moves AsyncTask information from objectstore to memory and it
is dependency to solve Issue #122.
Paulo Vital (3):
Issue #158: Move AsyncTask information to memory
Issue #158: Update model/tasks.py with AsyncTasks in memory.
Issue #158: Add AsyncTasks testcases
src/wok/asynctask.py | 49 +++++++++++--------
src/wok/i18n.py | 3 +-
src/wok/model/tasks.py | 22 +++++----
src/wok/objectstore.py | 6 ---
src/wok/utils.py | 19 --------
tests/test_tasks.py | 124 +++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 167 insertions(+), 56 deletions(-)
create mode 100644 tests/test_tasks.py
--
2.7.4
8 years, 3 months