On 07/14/2016 05:31 PM, Ramon Medeiros wrote:
Signed-off-by: Ramon Medeiros <ramonn(a)linux.vnet.ibm.com>
---
API.json | 5 +++++
docs/API.md | 1 +
i18n.py | 1 +
model/vms.py | 30 +++++++++++++++++++++---------
xmlutils/bootorder.py | 4 ++++
5 files changed, 32 insertions(+), 9 deletions(-)
diff --git a/API.json b/API.json
index 1772abb..4fdd522 100644
--- a/API.json
+++ b/API.json
@@ -317,6 +317,11 @@
"additionalItems": false,
"uniqueItems": true
},
+ "bootmenu": {
+ "description": "Bootmenu on guest power on",
+ "error": "KCHVM0053E",
+ "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 4a40e70..971f28e 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -175,6 +175,7 @@ server.
* cores - The number of cores per socket.
* threads - The number of threads per core.
* bootorder: guest bootorder, types accepted: hd, cdrom, network or fd
+ * bootmenu: prompts guest bootmenu. Bool type.
* **POST**: *See Virtual Machine Actions*
diff --git a/i18n.py b/i18n.py
index e8fdf88..6ca19fd 100644
--- a/i18n.py
+++ b/i18n.py
@@ -105,6 +105,7 @@ messages = {
"KCHVM0050E": _("Cannot shutdown %(name)s. Virtual machine is shut
off."),
"KCHVM0051E": _("Cannot reset %(name)s. Virtual machine is already
shut off."),
"KCHVM0052E": _("Boot order must be a list. Devices accepted: hd,
cdrom, fd or network."),
+ "KCHVM0053E": _("Bootmenu must be boolean. Values accepted: true of
false."),
"KCHVM0055E": _("Migrate to localhost %(host)s is not
allowed."),
"KCHVM0056E": _("To migrate a virtual machine to the remote host
%(host)s the user %(user)s must have password-less login to the remote host."),
diff --git a/model/vms.py b/model/vms.py
index 17159fe..4c07297 100644
--- a/model/vms.py
+++ b/model/vms.py
@@ -63,6 +63,7 @@ from wok.plugins.kimchi.screenshot import VMScreenshot
from wok.plugins.kimchi.utils import get_next_clone_name
from wok.plugins.kimchi.utils import template_name_from_uri
from wok.plugins.kimchi.xmlutils.bootorder import get_bootorder_node
+from wok.plugins.kimchi.xmlutils.bootorder import get_bootmenu_node
Wrong import order:
+from wok.plugins.kimchi.xmlutils.bootorder import get_bootmenu_node
from wok.plugins.kimchi.xmlutils.bootorder import get_bootorder_node
from wok.plugins.kimchi.xmlutils.cpu import get_topology_xml
from wok.plugins.kimchi.xmlutils.disk import get_vm_disk_info, get_vm_disks
from utils import has_cpu_numa, set_numa_memory
@@ -82,7 +83,7 @@ VM_ONLINE_UPDATE_PARAMS = ['graphics', 'groups',
'memory', 'users']
# update parameters which are updatable when the VM is offline
VM_OFFLINE_UPDATE_PARAMS = ['cpu_info', 'graphics', 'groups',
'memory',
- 'name', 'users', 'bootorder']
+ 'name', 'users', 'bootorder',
'bootmenu']
XPATH_DOMAIN_DISK =
"/domain/devices/disk[@device='disk']/source/@file"
XPATH_DOMAIN_DISK_BY_FILE =
"./devices/disk[@device='disk']/source[@file='%s']"
@@ -95,6 +96,7 @@ XPATH_DOMAIN_UUID = '/domain/uuid'
XPATH_DOMAIN_DEV_CPU_ID = '/domain/devices/spapr-cpu-socket/@id'
XPATH_BOOT = 'os/boot/@dev'
+XPATH_BOOTMENU = 'os/bootmenu/@enable'
XPATH_CPU = './cpu'
XPATH_NAME = './name'
XPATH_NUMA_CELL = './cpu/numa/cell'
@@ -758,9 +760,16 @@ class VMModel(object):
for device in os.findall("boot"):
os.remove(device)
- # add new
- for device in get_bootorder_node(params):
- os.append(device)
+ # add new bootorder
+ if "bootorder" in params:
+ for device in get_bootorder_node(params["bootorder"]):
+ os.append(device)
+
+ # update bootmenu
+ if params.get("bootmenu") is False:
+ [os.remove(bm) for bm in os.findall("bootmenu")]
+ elif params.get("bootmenu") is True:
+ os.append(get_bootmenu_node())
# update <os>
return ET.tostring(et)
@@ -811,9 +820,9 @@ class VMModel(object):
if ('memory' in params and params['memory'] != {}):
new_xml = self._update_memory_config(new_xml, params, dom)
- # update bootorder
- if "bootorder" in params:
- new_xml = self._update_bootorder(new_xml, params["bootorder"])
+ # update bootorder or bootmenu
+ if "bootorder" or "bootmenu" in params:
+ new_xml = self._update_bootorder(new_xml, params)
snapshots_info = []
conn = self.conn.get()
@@ -1252,8 +1261,10 @@ class VMModel(object):
else:
maxmemory = memory
- # get boot order
+ # get boot order and bootmenu
boot = xpath_get_text(xml, XPATH_BOOT)
+ bootmenu = "yes" if "yes" in xpath_get_text(xml,
XPATH_BOOTMENU) \
+ else "no"
return {'name': name,
'state': state,
@@ -1273,7 +1284,8 @@ class VMModel(object):
'groups': groups,
'access': 'full',
'persistent': True if dom.isPersistent() else False,
- 'bootorder': boot
+ 'bootorder': boot,
+ 'bootmenu': bootmenu
}
def _vm_get_disk_paths(self, dom):
diff --git a/xmlutils/bootorder.py b/xmlutils/bootorder.py
index 6d92bd6..f8bc6ea 100644
--- a/xmlutils/bootorder.py
+++ b/xmlutils/bootorder.py
@@ -47,3 +47,7 @@ def get_bootorder_xml(boot_order=None):
boot_xml += ET.tostring(device, encoding='utf-8', pretty_print=True)
return boot_xml
+
+
+def get_bootmenu_node():
+ return E.bootmenu(enable="yes", timeout="5000")