From faa3ef8cb4b3fe7a428defeff08cb8fadeabc2f6 Mon Sep 17 00:00:00 2001 From: Jerry Seutter Date: Fri, 7 Nov 2014 20:42:08 -0700 Subject: [PATCH] Add support for Qemu devices on cloud instances --- gns3server/modules/qemu/qemu_vm.py | 62 +++++++++++++++++++++++++++++- gns3server/modules/qemu/schemas.py | 4 ++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/gns3server/modules/qemu/qemu_vm.py b/gns3server/modules/qemu/qemu_vm.py index ce341780..ffdd299d 100644 --- a/gns3server/modules/qemu/qemu_vm.py +++ b/gns3server/modules/qemu/qemu_vm.py @@ -24,6 +24,10 @@ import shutil import random import subprocess import shlex +import ntpath + +from gns3server.config import Config +from gns3dms.cloud.rackspace_ctrl import get_provider from .qemu_error import QemuError from .adapters.ethernet_adapter import EthernetAdapter @@ -86,6 +90,7 @@ class QemuVM(object): self._stdout_file = "" self._console_start_port_range = console_start_port_range self._console_end_port_range = console_end_port_range + self._cloud_path = None # QEMU settings self._qemu_path = qemu_path @@ -288,6 +293,27 @@ class QemuVM(object): log.info("QEMU VM {name} [id={id}] has been deleted (including associated files)".format(name=self._name, id=self._id)) + @property + def cloud_path(self): + """ + Returns the cloud path where images can be downloaded from. + + :returns: cloud path + """ + + return self._cloud_path + + @cloud_path.setter + def cloud_path(self, cloud_path): + """ + Sets the cloud path where images can be downloaded from. + + :param cloud_path: + :return: + """ + + self._cloud_path = cloud_path + @property def qemu_path(self): """ @@ -531,7 +557,41 @@ class QemuVM(object): if not self.is_running(): if not os.path.isfile(self._qemu_path) or not os.path.exists(self._qemu_path): - raise QemuError("QEMU binary '{}' is not accessible".format(self._qemu_path)) + found = False + paths = [os.getcwd()] + os.environ["PATH"].split(os.pathsep) + # look for the qemu binary in the current working directory and $PATH + for path in paths: + try: + if self._qemu_path in os.listdir(path) and os.access(os.path.join(path, self._qemu_path), os.X_OK): + self._qemu_path = os.path.join(path, self._qemu_path) + found = True + break + except OSError: + continue + + if not found: + raise QemuError("QEMU binary '{}' is not accessible".format(self._qemu_path)) + + if self.cloud_path is not None: + # Download from Cloud Files + if self.hda_disk_image != "": + _, filename = ntpath.split(self.hda_disk_image) + src = '{}/{}'.format(self.cloud_path, filename) + dest = os.path.join(self.working_dir, filename) + if not os.path.isfile(dest): + cloud_settings = Config.instance().cloud_settings() + provider = get_provider(cloud_settings) + provider.download_file(src, dest) + self.hda_disk_image = dest + if self.hdb_disk_image != "": + _, filename = ntpath.split(self.hdb_disk_image) + src = '{}/{}'.format(self.cloud_path, filename) + dest = os.path.join(self.working_dir, filename) + if not os.path.isfile(dest): + cloud_settings = Config.instance().cloud_settings() + provider = get_provider(cloud_settings) + provider.download_file(src, dest) + self.hdb_disk_image = dest self._command = self._build_command() try: diff --git a/gns3server/modules/qemu/schemas.py b/gns3server/modules/qemu/schemas.py index a4f340c3..885941fd 100644 --- a/gns3server/modules/qemu/schemas.py +++ b/gns3server/modules/qemu/schemas.py @@ -120,6 +120,10 @@ QEMU_UPDATE_SCHEMA = { "description": "QEMU kernel command line", "type": "string", }, + "cloud_path": { + "description": "Path to the image in the cloud object store", + "type": "string", + }, "options": { "description": "additional QEMU options", "type": "string",