Change in vdsm[master]: vdsm: hook for booting from an ISO image gathered via http

stirabos at redhat.com stirabos at redhat.com
Mon May 18 17:31:05 UTC 2015


Simone Tiraboschi has uploaded a new change for review.

Change subject: vdsm: hook for booting from an ISO image gathered via http
......................................................................

vdsm: hook for booting from an ISO image gathered via http

Let the VM boot from an ISO image made available via an HTTP URL without
the need to import the ISO into an ISO storage domain.
syntax: httpisoboot=http://server/path/to/disk.iso

Change-Id: I22b190b5d3d43cab7bdbfa81bdf0904b2988b2bc
Bug-Url: https://bugzilla.redhat.com/917026
Signed-off-by: Simone Tiraboschi <stirabos at redhat.com>
---
M vdsm_hooks/Makefile.am
A vdsm_hooks/httpisoboot/Makefile.am
A vdsm_hooks/httpisoboot/README
A vdsm_hooks/httpisoboot/before_vm_start.py
4 files changed, 210 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/76/41076/1

diff --git a/vdsm_hooks/Makefile.am b/vdsm_hooks/Makefile.am
index 5196072..5b893de 100644
--- a/vdsm_hooks/Makefile.am
+++ b/vdsm_hooks/Makefile.am
@@ -41,6 +41,7 @@
 	fakevmstats \
 	floppy \
 	hostusb \
+	httpisoboot \
 	hugepages \
 	isolatedprivatevlan \
 	macbind \
diff --git a/vdsm_hooks/httpisoboot/Makefile.am b/vdsm_hooks/httpisoboot/Makefile.am
new file mode 100644
index 0000000..e89d0e3
--- /dev/null
+++ b/vdsm_hooks/httpisoboot/Makefile.am
@@ -0,0 +1,30 @@
+#
+# Copyright 2015 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+#
+# Refer to the README and COPYING files for full details of the license
+#
+
+EXTRA_DIST = \
+	before_vm_start.py
+
+install-data-local:
+	$(MKDIR_P) $(DESTDIR)$(vdsmhooksdir)/before_vm_start
+	$(INSTALL_SCRIPT) $(srcdir)/before_vm_start.py \
+		$(DESTDIR)$(vdsmhooksdir)/before_vm_start/50_httpisoboot
+
+uninstall-local:
+	$(RM) $(DESTDIR)$(vdsmhooksdir)/before_vm_start/50_httpisoboot
diff --git a/vdsm_hooks/httpisoboot/README b/vdsm_hooks/httpisoboot/README
new file mode 100644
index 0000000..6ac5a3b
--- /dev/null
+++ b/vdsm_hooks/httpisoboot/README
@@ -0,0 +1,7 @@
+httpisoboot hook:
+============
+Let the VM boot from an ISO image made available via an HTTP URL without
+the need to import the ISO into an ISO storage domain.
+
+syntax:
+    httpisoboot=http://server/path/to/disk.iso
diff --git a/vdsm_hooks/httpisoboot/before_vm_start.py b/vdsm_hooks/httpisoboot/before_vm_start.py
new file mode 100755
index 0000000..eac3cb7
--- /dev/null
+++ b/vdsm_hooks/httpisoboot/before_vm_start.py
@@ -0,0 +1,172 @@
+#!/usr/bin/python
+
+import os
+import sys
+import hooking
+import traceback
+from urlparse import urlparse
+
+'''
+httpisoboot hook:
+    Let the VM boot from an ISO image made available via an HTTP URL without
+    the need to import the ISO into an ISO storage domain.
+syntax:
+    httpisoboot=http://server/path/to/disk.iso
+'''
+
+
+def indexToDiskName(i):
+    if i < 0 or i >= 4:
+        return None
+    return 'hd' + chr(ord('a') + i % 4)
+
+
+def increaseDevicesBootOrder(domxml):
+    xmldisks = domxml.getElementsByTagName('disk')
+    for d in xmldisks:
+        boots = d.getElementsByTagName('boot')
+        for boot in boots:
+            if boot.hasAttribute('order'):
+                try:
+                    boot.setAttribute(
+                        'order',
+                        str(
+                            int(
+                                boot.getAttribute('order')
+                            )+1
+                        )
+                    )
+                except ValueError:
+                    sys.stderr.write(
+                        'httpisoboot: unable to manipulate the boot order\n'
+                    )
+                    sys.exit(2)
+
+
+def createHttpIsoElement(domxml, protocol, hostname, port, url_path):
+    '''
+    <disk type='network' device='cdrom'>
+      <driver name='qemu' type='raw'/>
+      <source protocol="http" name="url_path">
+        <host name="hostname" port="80"/>
+      </source>
+      <target dev='hdc' bus='ide' tray='closed'/>
+      <backingStore/>
+      <readonly/>
+      <boot order='1'/>
+    </disk>
+    '''
+
+    disk = domxml.createElement('disk')
+    disk.setAttribute('type', 'network')
+    disk.setAttribute('device', 'cdrom')
+
+    driver = domxml.createElement('driver')
+    driver.setAttribute('name', 'qemu')
+    driver.setAttribute('type', 'raw')
+    disk.appendChild(driver)
+
+    source = domxml.createElement('source')
+    source.setAttribute('protocol', protocol)
+    source.setAttribute('name', url_path)
+
+    host = domxml.createElement('host')
+    host.setAttribute('name', hostname)
+    host.setAttribute('port', port)
+    source.appendChild(host)
+    disk.appendChild(source)
+
+    readonly = domxml.createElement('readonly')
+    disk.appendChild(readonly)
+    backingStore = domxml.createElement('backingStore')
+    disk.appendChild(backingStore)
+
+    # find a name for hdX
+    target = domxml.createElement('target')
+    target.setAttribute('bus', 'ide')
+    target.setAttribute('tray', 'closed')
+    xmldisks = domxml.getElementsByTagName('disk')
+    disks = []
+    for d in xmldisks:
+        disks.append(d.getElementsByTagName('target')[0].getAttribute('dev'))
+    found = False
+    for i in range(0, 4):
+        dname = indexToDiskName(i)
+        if dname and dname not in disks:
+            target.setAttribute('dev', indexToDiskName(i))
+            found = True
+            break
+    if not found:
+        sys.stderr.write('httpisoboot: unable to attach another ide cdrom\n')
+        sys.exit(2)
+    disk.appendChild(target)
+
+    boot = domxml.createElement('boot')
+    boot.setAttribute('order', '1')
+    disk.appendChild(boot)
+
+    return disk
+
+
+if 'httpisoboot' in os.environ:
+    try:
+        httpisoboot = os.environ['httpisoboot']
+        domxml = hooking.read_domxml()
+        devices = domxml.getElementsByTagName('devices')[0]
+
+        parsed = urlparse.urlsplit(httpisoboot)
+        protocol = parsed.scheme
+        if protocol not in ['http', 'https']:
+            sys.stderr.write(
+                (
+                    "httpisoboot: '{protocol}' is not supported, "
+                    "please try http or https\n"
+                ).format(protocol=protocol)
+            )
+            sys.exit(2)
+
+        hostname = parsed.netloc.split(':')[0]
+        if not hostname:
+            sys.stderr.write(
+                (
+                    "httpisoboot: invalid hostname in the URL '{url}'\n"
+                ).format(url=httpisoboot)
+            )
+            sys.exit(2)
+
+        port = None
+        if parsed.port is not None:
+            port = parsed.port
+        elif protocol == 'http':
+            port = 80
+        elif protocol == 'https':
+            port = 443
+        if not port >= 1 and port <= 65535:
+            sys.stderr.write(
+                (
+                    "httpisoboot: invalid port in the URL '{url}'\n"
+                ).format(url=httpisoboot)
+            )
+            sys.exit(2)
+        port_s = str(port)
+
+        url_path = parsed.path
+        if parsed.query:
+            url_path += '?' + parsed.query
+
+        increaseDevicesBootOrder(domxml)
+
+        diskdev = createHttpIsoElement(
+            domxml,
+            protocol,
+            hostname,
+            port_s,
+            url_path
+        )
+        devices.appendChild(diskdev)
+
+        hooking.write_domxml(domxml)
+    except:
+        sys.stderr.write('httpisoboot: [unexpected error]: %s\n' %
+                         traceback.format_exc())
+        sys.exit(2)


-- 
To view, visit https://gerrit.ovirt.org/41076
To unsubscribe, visit https://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I22b190b5d3d43cab7bdbfa81bdf0904b2988b2bc
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Simone Tiraboschi <stirabos at redhat.com>


More information about the vdsm-patches mailing list