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)
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()
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)