[Kimchi-devel] [PATCH][Kimchi 1/2] Allow guest to enable bootmenu on startup

Ramon Medeiros ramonn at linux.vnet.ibm.com
Thu Jul 14 01:25:57 UTC 2016


Signed-off-by: Ramon Medeiros <ramonn at linux.vnet.ibm.com>
---
 API.json              |  5 +++++
 docs/API.md           |  1 +
 i18n.py               |  1 +
 model/vms.py          | 30 +++++++++++++++++++++---------
 xmlutils/bootorder.py |  3 +++
 5 files changed, 31 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
 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..21939b3 100644
--- a/xmlutils/bootorder.py
+++ b/xmlutils/bootorder.py
@@ -47,3 +47,6 @@ 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")
-- 
2.5.5




More information about the Kimchi-devel mailing list