Ejemplo n.º 1
0
    def vm_create(self, request):
        """
        Creates a new VM (router).

        Mandatory request parameters:
        - name (vm name)
        - platform (platform name e.g. c7200)
        - image (path to IOS image)
        - ram (amount of RAM in MB)

        Optional request parameters:
        - console (console port number)
        - aux (auxiliary console port number)
        - mac_addr (MAC address)
        - chassis (router chassis model)

        Response parameters:
        - id (vm identifier)
        - name (vm name)

        :param request: JSON request
        """

        # validate the request
        if not self.validate_request(request, VM_CREATE_SCHEMA):
            return

        name = request["name"]
        platform = request["platform"]
        image = request["image"]
        ram = request["ram"]
        hypervisor = None
        chassis = request.get("chassis")
        router_id = request.get("router_id")

        # Locate the image
        updated_image_path = os.path.join(self.images_directory, image)
        if os.path.isfile(updated_image_path):
            image = updated_image_path
        else:
            if not os.path.exists(self.images_directory):
                os.mkdir(self.images_directory)
            cloud_path = request.get("cloud_path", None)
            if cloud_path is not None:
                # Download the image from cloud files
                _, filename = ntpath.split(image)
                src = '{}/{}'.format(cloud_path, filename)
                provider = get_provider(self._cloud_settings)
                log.debug("Downloading file from {} to {}...".format(src, updated_image_path))
                provider.download_file(src, updated_image_path)
                log.debug("Download of {} complete.".format(src))
                image = updated_image_path

        try:
            if platform not in PLATFORMS:
                raise DynamipsError("Unknown router platform: {}".format(platform))

            if not self._hypervisor_manager:
                self.start_hypervisor_manager()

            hypervisor = self._hypervisor_manager.allocate_hypervisor_for_router(image, ram)

            if chassis:
                router = PLATFORMS[platform](hypervisor, name, router_id, chassis=chassis)
            else:
                router = PLATFORMS[platform](hypervisor, name, router_id)
            router.ram = ram
            router.image = image
            if platform not in ("c1700", "c2600"):
                router.sparsemem = self._hypervisor_manager.sparse_memory_support
            router.mmap = self._hypervisor_manager.mmap_support
            if "console" in request:
                router.console = request["console"]
            if "aux" in request:
                router.aux = request["aux"]
            if "mac_addr" in request:
                router.mac_addr = request["mac_addr"]

            # JIT sharing support
            if self._hypervisor_manager.jit_sharing_support:
                jitsharing_groups = hypervisor.jitsharing_groups
                ios_image = os.path.basename(image)
                if ios_image in jitsharing_groups:
                    router.jit_sharing_group = jitsharing_groups[ios_image]
                else:
                    new_jit_group = -1
                    for jit_group in range(0, 127):
                        if jit_group not in jitsharing_groups.values():
                            new_jit_group = jit_group
                            break
                    if new_jit_group == -1:
                        raise DynamipsError("All JIT groups are allocated!")
                    router.jit_sharing_group = new_jit_group

            # Ghost IOS support
            if self._hypervisor_manager.ghost_ios_support:
                self.set_ghost_ios(router)

        except DynamipsError as e:
            dynamips_stdout = ""
            if hypervisor:
                hypervisor.decrease_memory_load(ram)
                if hypervisor.memory_load == 0 and not hypervisor.devices:
                    hypervisor.stop()
                    self._hypervisor_manager.hypervisors.remove(hypervisor)
                dynamips_stdout = hypervisor.read_stdout()
            self.send_custom_error(str(e) + dynamips_stdout)
            return

        response = {"name": router.name,
                    "id": router.id}
        defaults = router.defaults()
        response.update(defaults)
        self._routers[router.id] = router
        self.send_response(response)
Ejemplo n.º 2
0
    def start(self):
        """
        Starts this QEMU VM.
        """

        if self.is_running():

            # resume the VM if it is paused
            self.resume()
            return

        else:

            if not os.path.isfile(self._qemu_path) or not os.path.exists(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)
                    dst = os.path.join(self.working_dir, filename)
                    if not os.path.isfile(dst):
                        cloud_settings = Config.instance().cloud_settings()
                        provider = get_provider(cloud_settings)
                        log.debug("Downloading file from {} to {}...".format(src, dst))
                        provider.download_file(src, dst)
                        log.debug("Download of {} complete.".format(src))
                    self.hda_disk_image = dst
                if self.hdb_disk_image != "":
                    _, filename = ntpath.split(self.hdb_disk_image)
                    src = '{}/{}'.format(self.cloud_path, filename)
                    dst = os.path.join(self.working_dir, filename)
                    if not os.path.isfile(dst):
                        cloud_settings = Config.instance().cloud_settings()
                        provider = get_provider(cloud_settings)
                        log.debug("Downloading file from {} to {}...".format(src, dst))
                        provider.download_file(src, dst)
                        log.debug("Download of {} complete.".format(src))
                    self.hdb_disk_image = dst

                if self.initrd != "":
                    _, filename = ntpath.split(self.initrd)
                    src = '{}/{}'.format(self.cloud_path, filename)
                    dst = os.path.join(self.working_dir, filename)
                    if not os.path.isfile(dst):
                        cloud_settings = Config.instance().cloud_settings()
                        provider = get_provider(cloud_settings)
                        log.debug("Downloading file from {} to {}...".format(src, dst))
                        provider.download_file(src, dst)
                        log.debug("Download of {} complete.".format(src))
                    self.initrd = dst
                if self.kernel_image != "":
                    _, filename = ntpath.split(self.kernel_image)
                    src = '{}/{}'.format(self.cloud_path, filename)
                    dst = os.path.join(self.working_dir, filename)
                    if not os.path.isfile(dst):
                        cloud_settings = Config.instance().cloud_settings()
                        provider = get_provider(cloud_settings)
                        log.debug("Downloading file from {} to {}...".format(src, dst))
                        provider.download_file(src, dst)
                        log.debug("Download of {} complete.".format(src))
                    self.kernel_image = dst

            self._command = self._build_command()
            try:
                log.info("starting QEMU: {}".format(self._command))
                self._stdout_file = os.path.join(self._working_dir, "qemu.log")
                log.info("logging to {}".format(self._stdout_file))
                with open(self._stdout_file, "w") as fd:
                    self._process = subprocess.Popen(self._command,
                                                     stdout=fd,
                                                     stderr=subprocess.STDOUT,
                                                     cwd=self._working_dir)
                log.info("QEMU VM instance {} started PID={}".format(self._id, self._process.pid))
                self._started = True
            except (OSError, subprocess.SubprocessError) as e:
                stdout = self.read_stdout()
                log.error("could not start QEMU {}: {}\n{}".format(self._qemu_path, e, stdout))
                raise QemuError("could not start QEMU {}: {}\n{}".format(self._qemu_path, e, stdout))

            self._set_process_priority()
            if self._cpu_throttling:
                self._set_cpu_throttling()
Ejemplo n.º 3
0
    def iou_create(self, request):
        """
        Creates a new IOU instance.

        Mandatory request parameters:
        - path (path to the IOU executable)

        Optional request parameters:
        - name (IOU name)
        - console (IOU console port)

        Response parameters:
        - id (IOU instance identifier)
        - name (IOU name)
        - default settings

        :param request: JSON request
        """

        # validate the request
        if not self.validate_request(request, IOU_CREATE_SCHEMA):
            return

        name = request["name"]
        iou_path = request["path"]
        console = request.get("console")
        iou_id = request.get("iou_id")

        updated_iou_path = os.path.join(self.images_directory, iou_path)
        if os.path.isfile(updated_iou_path):
            iou_path = updated_iou_path
        else:
            if not os.path.exists(self.images_directory):
                os.mkdir(self.images_directory)
            cloud_path = request.get("cloud_path", None)
            if cloud_path is not None:
                # Download the image from cloud files
                _, filename = ntpath.split(iou_path)
                src = '{}/{}'.format(cloud_path, filename)
                provider = get_provider(self._cloud_settings)
                log.debug("Downloading file from {} to {}...".format(src, updated_iou_path))
                provider.download_file(src, updated_iou_path)
                log.debug("Download of {} complete.".format(src))
                # Make file executable
                st = os.stat(updated_iou_path)
                os.chmod(updated_iou_path, st.st_mode | stat.S_IEXEC)
                iou_path = updated_iou_path

        try:
            iou_instance = IOUDevice(name,
                                     iou_path,
                                     self._working_dir,
                                     iou_id,
                                     console,
                                     self._console_host,
                                     self._console_start_port_range,
                                     self._console_end_port_range)

        except IOUError as e:
            self.send_custom_error(str(e))
            return

        response = {"name": iou_instance.name,
                    "id": iou_instance.id}

        defaults = iou_instance.defaults()
        response.update(defaults)
        self._iou_instances[iou_instance.id] = iou_instance
        self.send_response(response)