def copy_lab_source(self, vm_id, lab_repo_name, git_clone_loc): directories = git_clone_loc.split("/") labs_dir = directories[-2] src_dir = None if base_config.ADS_ON_CONTAINER: src_dir = "%s%s%s%s%s%s" % (base_config.VM_ROOT_DIR, base_config.ADS_SERVER_VM_ID, base_config.VM_DEST_DIR, labs_dir, "/", lab_repo_name) else: src_dir = "%s%s%s%s" % (base_config.VM_DEST_DIR, labs_dir, "/", lab_repo_name) dest_dir = "%s%s%s" % (base_config.VM_ROOT_DIR, vm_id, base_config.VM_DEST_DIR + "labs") logger.debug("vm_id = %s, src_dir=%s, dest_dir=%s" % (vm_id, src_dir, dest_dir)) try: return self.copy_files(src_dir, dest_dir) except Exception, e: logger.error("ERROR = %s" % str(e)) return False
def destroy_vm(self, vm_id): vm_id = self.validate_vm_id(vm_id) try: command = (r'ssh -o "%s" %s "%s stop %s"' % (base_config.NO_STRICT_CHECKING, base_config.BASE_IP_ADDRESS, VZCTL, vm_id)) logger.debug("BridgeVZAdapter: destroy_vm(): stop command = %s" % command) (ret_code, output) = execute_command(command) if ret_code == 0: command = (r'ssh -o "%s" %s "%s destroy %s"' % (base_config.NO_STRICT_CHECKING, base_config.BASE_IP_ADDRESS, VZCTL, vm_id)) logger.debug("BridgeVZAdapter: destroy_vm(): destroy command = \ %s" % command) (ret_code, output) = execute_command(command) if ret_code == 0: return "Success" except Exception, e: logger.error("Error destroying VM: " + str(e)) return "Failed to destroy VM: " + str(e)
def copy_public_key(self, vm_id): try: public_key_file = ("%s%s%s%s" % (base_config.VM_ROOT_DIR, base_config.ADS_SERVER_VM_ID, base_config.VM_DEST_DIR, ".ssh/id_rsa.pub")) authorized_key_file = ("%s%s%s%s" % (base_config.VM_ROOT_DIR, vm_id, base_config.VM_DEST_DIR, ".ssh/authorized_keys")) logger.debug("public key location = %s, authorized key location = %s" % (public_key_file, authorized_key_file)) command = (r'ssh -o "%s" %s "%s %s > %s"' % (base_config.NO_STRICT_CHECKING, base_config.BASE_IP_ADDRESS, "/bin/cat", public_key_file, authorized_key_file)) logger.debug("command to cpy the public key = %s" % command) (ret_code, output) = execute_command(command) return True except Exception, e: logger.error("ERROR = %s" % str(e)) return False
def get_instance(self, vm_id): logger.debug("AWSAdapter: get_instance(): vm_id: %s" % (vm_id)) reservations = self.connection.get_all_instances(instance_ids=[vm_id]) instance = reservations[0].instances[0] return instance
def construct_repo_name(self, lab_src_url): # sample lab_src_url: [email protected]:vlead/ovpl.git logger.debug("lab_src_url: %s" % lab_src_url) repo = lab_src_url.split('/')[-1] repo_name = (repo[:-4] if repo[-4:] == ".git" else repo) logger.debug("repo_name: %s" % repo_name) return str(repo_name)
def create_record(lab_src_url=None, c=None): logger.debug("Test case insert_record") if c is None: c = Controller() if lab_src_url is None: lab_src_url = \ "https://github.com/Virtual-Labs/computer-programming-iiith.git" revision_tag = None lab_id = "cse04" current_user = "******" vmpool_id = 1 vm_description = "LINUXAdapter" adapter_ip = "http://localhost" adapter_port = "8000" create_path = "/api/1.0/vm/create" destroy_path = "/api/1.0/vm/destroy" vm_id = "123" vm_ip = "10.12.13.114" vm_port = "8089" try: vm_pool = VMPool(vmpool_id, vm_description, adapter_ip, adapter_port, create_path, destroy_path) c.lab_spec = c.labmgr.get_lab_reqs(lab_src_url, revision_tag) logger.debug("returned from lab_manager and the controller's lab_spec = %s" % c.lab_spec) c.update_lab_spec(lab_id, lab_src_url, revision_tag) record = vm_pool.construct_state(c.lab_spec, vm_id, vm_ip, vm_port) c.deploy_record.record = record c.update_deploy_record(current_user) logger.debug("deploy_record = %s" % c.deploy_record.record) logger.debug("ID = %s" % c.deploy_record.record['id']) return c.deploy_record except Exception, e: logger.debug("Error inserting record, error is %s" % str(e))
def add_vm_pool(self, vm_pool_id, vm_description, adapter_ip, adapter_port, create_path, destroy_path): logger.debug("VMPoolManager: add_vm_pool(); %s, %s, %s, %s, %s, %s" % (vm_pool_id, vm_description, adapter_ip, adapter_port, create_path, destroy_path)) self.vmpools.append(VMPool(vm_pool_id, vm_description, adapter_ip, adapter_port, create_path, destroy_path))
def test_find_os_template(): os = "ubuntu" os_version = "12" try: template = find_os_template(os, os_version) logger.debug("Returned template = %s" % template) except Exception, e: logger.debug("Exception = %s" % str(e))
def test_get_lab_reqs(): lab_src_url = "https://github.com/Virtual-Labs/computer-programming-iiith.git" labmgr = LabManager() try: lab_spec = labmgr.get_lab_reqs(lab_src_url, version=None) logger.debug("Lab spec: %s" % str(lab_spec)) except Exception, e: logger.error("Test failed with error: " + str(e))
def create_vm(self, lab_spec, vm_id=""): logger.debug("centos_openvz_adapter: create_vm()") """If no vm_id is specified, it is computed using the last two segments""" """of an available IP address; vm_spec is an object """ if vm_id == "": ip_address = base_adapter.find_available_ip() m = re.match(r'[0-9]+.[0-9]+.([0-9]+).([0-9]+)', ip_address) if m is not None: vm_id = str((int(m.group(1) + m.group(2)))) # vm_id = m.group(1) + m.group(2) else: ip_address = None vm_id = self.validate_vm_id(vm_id) (vm_create_args, vm_set_args) = self.construct_vzctl_args(lab_spec) logger.debug("centos_openvz_adapter: create_vm(): ip = %s, vm_id = %s, \ vm_create_args = %s, vm_set_args = %s" % (ip_address, vm_id, vm_create_args, vm_set_args)) try: command = (r'ssh -o "%s" %s "%s create %s %s"' % (base_config.NO_STRICT_CHECKING, base_config.BASE_IP_ADDRESS, VZCTL, vm_id, vm_create_args)) logger.debug("centos_openvz_adapter: create_vm(): create command = %s" % command) (ret_code, output) = execute_command(command) if ret_code == 0: command = (r'ssh -o "%s" %s "%s start %s"' % (base_config.NO_STRICT_CHECKING, base_config.BASE_IP_ADDRESS, VZCTL, vm_id)) logger.debug("centos_openvz_adapter: create_vm():start command = %s" % command) (ret_code, output) = execute_command(command) if ret_code == 0: command = (r'ssh -o "%s" %s "%s set %s %s"' % (base_config.NO_STRICT_CHECKING, base_config.BASE_IP_ADDRESS, VZCTL, vm_id, vm_set_args)) logger.debug("centos_openvz_adapter:create_vm():set command=%s" % command) (ret_code, output) = execute_command(command) if ret_code == 0: return (True, vm_id) except Exception, e: logger.error("Error creating VM: " + str(e)) # raise e return (False, -1)
def get_vm_ip(self, vm_id): logger.debug("AWSAdapter: get_vm_ip(): vm_id: %s" % (vm_id)) instance = self.get_instance(vm_id) logger.debug("AWSAdapter: IP address of the instance is: %s" % instance.private_ip_address) return instance.private_ip_address
def update_lab_spec(self, lab_id, lab_src_url, revision_tag): self.lab_spec['lab']['description']['id'] = \ self.lab_spec['lab_id'] = lab_id self.lab_spec['lab']['lab_src_url'] = lab_src_url self.lab_spec['lab']['lab_repo_name'] = \ self.git.construct_repo_name(lab_src_url) self.lab_spec['lab']['revision_tag'] = revision_tag self.lab_spec['lab']['runtime_requirements']['hosting'] = 'dedicated' logger.debug("lab_repo_name: %s" % (self.lab_spec['lab']['lab_repo_name']))
def reset_repo(self, repo_name): repo = self.git_clone_loc + repo_name reset_cmd = "git --git-dir=%s/.git --work-tree=%s reset --hard" % (repo, repo) logger.debug("reset cmd: %s" % reset_cmd) try: (ret_code, output) = execute_command(reset_cmd) logger.debug("reset repo successful") except Exception, e: logger.error("Error Resetting the repository: " + str(e)) raise e
def clone_repo(self, lab_src_url, repo_name): clone_cmd = "git clone %s %s%s" % (lab_src_url, self.git_clone_loc, repo_name) logger.debug(clone_cmd) try: (ret_code, output) = execute_command(clone_cmd) logger.debug("Clone repo successful") except Exception, e: logger.error("Error Cloning the repository: " + str(e)) raise e
def get_lab_spec(self, repo_name): spec_file_path = self.get_spec_path(repo_name) + self.lab_spec_file logger.debug("spec_file_path: %s" % spec_file_path) if not os.path.exists(spec_file_path): logger.error("Lab spec file not found") raise LabSpecInvalid("Lab spec file not found") try: return json.loads(open(spec_file_path).read()) except Exception, e: logger.error("Lab spec JSON invalid: " + str(e))
def pull_repo(self, repo_name): repo = self.git_clone_loc + repo_name pull_cmd = "git --git-dir=%s/.git --work-tree=%s pull" % (repo, repo) logger.debug("pull cmd: %s" % pull_cmd) try: (ret_code, output) = execute_command(pull_cmd) logger.debug("Pull repo successful") except Exception, e: logger.error("Error Pulling the repository: " + str(e)) raise e
def find_os_template(os, os_version, supported_images): """ Find a suitable os image from the list of supported images from the given OS and OS version. If a suitable OS is not found, raise appropriate Exception """ logger.debug("OS = %s and OS_VERSION = %s" % (os, os_version)) logger.debug("Supported images = %s" % supported_images) if os == "" or os_version == "": msg = "No OS or Version specified" logger.error(msg) raise OSNotFound(msg) # sanitize input os = os.strip().upper() os_version = os_version.strip() if os == 'UBUNTU' and os_version == '12': os_version = '12.04' if os == 'UBUNTU' and os_version == '13': os_version = '13.04' if os == 'UBUNTU' and os_version == '14': os_version = '14.04' if os == 'CENTOS' and os_version == '6': os_version = '6.9' # filter the supported image list by the os and the by the version all_versions_of_os = filter(lambda x: x['os'] == os, supported_images) logger.debug("List of all the supported versions of OS = %s is %s" % (os, all_versions_of_os)) if all_versions_of_os: chosen_template = filter(lambda x: x['version'] == os_version, all_versions_of_os) logger.debug("The image supported for OS = %s, Version = %s is %s" % (os, os_version, chosen_template)) else: msg = "OS = %s is not supported" % os logger.error(msg) raise OSNotFound(msg) if not chosen_template or not len(chosen_template): msg = "Version = %s is not supported" % os_version logger.error(msg) raise OSNotFound(msg) # chose the item; there should be only one. chosen_template = chosen_template[0] logger.debug("Choosen image: %s; based on input OS: %s, version: %s" % (chosen_template, os, os_version)) return chosen_template['id']
def checkout_version(self, repo_name, version=None): repo = self.git_clone_loc + repo_name if version is None: version = "master" checkout_cmd = "git --git-dir=%s/.git --work-tree=%s checkout %s" % (repo, repo, version) try: (ret_code, output) = execute_command(checkout_cmd) logger.debug("Checkout repo successful") except Exception, e: logger.error("Error checking out the repository: " + str(e)) raise e
def update_deploy_record(self, current_user): logger.debug("current user is %s" % current_user) self.deploy_record.record['lab_history']['deployed_by'] = current_user self.deploy_record.record['lab_history']['released_by'] = 'dummy' self.deploy_record.record['lab_history']['released_on'] = \ datetime.utcnow() # This is a hack, just to avoid duplicate records. self.deploy_record.record['id'] = \ self.lab_spec['lab']['lab_src_url'] + str(datetime.utcnow()) logger.debug("Lab deployed by %s" % self.deploy_record.record['lab_history']['deployed_by'])
def restart_vm(self, vm_id): vm_id = self.validate_vm_id(vm_id) try: command = (r'ssh -o "%s" %s "%s restart %s"' % (base_config.NO_STRICT_CHECKING, base_config.BASE_IP_ADDRESS, VZCTL, vm_id)) logger.debug("BridgeVZAdapter: restart_vm(): restart command = %s" % command) (ret_code, output) = execute_command(command) except Exception, e: raise e
def get_used_pools(self, lab_id): used_pools = [] logger.debug("VMPoolManager: get_used_pools()") deployment_record = self.state.get_record(lab_id) logger.debug("Deployment Record = %s" % deployment_record) if deployment_record is not None: # Currently there is only pool where the lab is deployed used_pools.append(deployment_record['vmpool_info']['vmpool_id']) return used_pools else: logger.error("No record found with the lab id = %s" % lab_id) raise RecordNotFoundError(lab_id)
def construct_state(self, lab_spec, vm_id, vm_ip, vm_port): deploy_record = Record().record logger.debug("before setting record = %s" % deploy_record) deploy_record["lab_spec"] = lab_spec deploy_record["vm_info"]["vm_id"] = vm_id deploy_record["vm_info"]["vm_ip"] = vm_ip deploy_record["vm_info"]["vm_port"] = vm_port deploy_record["vmpool_info"]["vmpool_id"] = self.vmpool_id deploy_record["vmpool_info"]["vm_description"] = self.vm_description deploy_record["vmpool_info"]["adapter_ip"] = self.adapter_ip deploy_record["vmpool_info"]["adapter_port"] = self.adapter_port logger.debug("after setting record = %s" % deploy_record) return deploy_record
def init_vm(self, vm_id, lab_repo_name): logger.debug("BridgeVZAdapter: init_vm(): vm_id = %s" % vm_id) success = True success = success and self.copy_public_key(vm_id) success = success and self.copy_ovpl_source(vm_id) success = success and self.copy_lab_source(vm_id, lab_repo_name, self.git.get_git_clone_loc()) success = success and self.start_vm_manager(vm_id) response = {"vm_id": vm_id, "vm_ip": IP_ADDRESS, "vm_port": base_config.VM_MANAGER_PORT} # check if the VMManager service came up and running.. logger.debug("Ensuring VMManager service is running on VM %s" % response['vm_ip']) vmmgr_port = int(base_config.VM_MANAGER_PORT) success = base_adapter.wait_for_service(response['vm_ip'], vmmgr_port, self.time_before_next_retry, config.TIMEOUT) if not success: logger.debug("Could not reach VMManager after %s secs!! Aborting." % config.TIMEOUT) return (success, response) logger.debug("centos_openvz_adapter: init_vm(): success = %s, response = %s" % (success, response)) return (success, response)
def create_vm_id(self, vm_id): """If no vm_id is specified, it is computed using the last two segments""" """of an available IP address; vm_spec is an object """ logger.debug("create_vm_id(): vm_id = %s" % vm_id) if vm_id == "": global IP_ADDRESS IP_ADDRESS = base_adapter.find_available_ip() m = re.match(r'[0-9]+.[0-9]+.([0-9]+).([0-9]+)', IP_ADDRESS) if m is not None: vm_id = str((int(m.group(1) + m.group(2)))) else: vm_id = self.validate_vm_id(vm_id) logger.debug("create_vm_id(): vm_id = %s" % vm_id) return vm_id
def register_lab(self, lab_id, ip_address): service_host = base_config.SERVICE_HOST service_name = "hosting_service" service_action = "register" command = 'ssh %s %s %s %s %s' % \ (service_host, service_name, service_action, lab_id, ip_address) logger.debug("Hook's service command = %s" % command) (ret_code, output) = execute_command(command) if ret_code == 0: domain_name = lab_id + "." + get_adapter_hostname() logger.debug("FQDN of lab is = %s" % domain_name) return domain_name
def stop_vm(self, vm_id): vm_id = self.validate_vm_id(vm_id) try: command = (r'ssh -o "%s" %s "%s stop %s"' % (base_config.NO_STRICT_CHECKING, base_config.BASE_IP_ADDRESS, VZCTL, vm_id)) logger.debug("centos_openvz_adapter: stop_vm(): command = %s" % command) (ret_code, output) = execute_command(command) return "Success" except Exception, e: logger.error("Error stopping VM: " + str(e)) return "Failed to stop VM: " + str(e)
def is_service_up(vm_ip, port): logger.debug("base_adapter: is_service_up(): VM IP: %s" % vm_ip) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) try: logger.debug("base_adapter: trying to connect to port: %s of: %s" % (port, vm_ip)) s.connect((vm_ip, port)) logger.debug("base_adapter: VM %s: port: %s is up.." % (vm_ip, port)) return True except socket.error as e: logger.debug("base_adapter: VM %s: Error connecting to port: %s: %s" % (vm_ip, port, e)) logger.debug("base_adapter: retrying to reach port %s.." % port) s.close() return False
def _copy_lab_source(self, ip_addr, lab_repo_name): src_dir = str(self.git.git_clone_loc) + "/" + lab_repo_name dest_dir = "{0}@{1}:{2}labs/".format(self.VM_USER, ip_addr, base_config.VM_DEST_DIR) logger.debug("ip_address = %s, src_dir=%s, dest_dir=%s" % (ip_addr, src_dir, dest_dir)) try: return self._copy_files(src_dir, dest_dir) except Exception, e: logger.error("ERROR = %s" % str(e)) print 'ERROR= %s' % (str(e)) return False
def execute_command(cmd): logger.debug("command: %s" % cmd) return_code = -1 output = None try: output = subprocess.check_output(cmd, shell=True) return_code = 0 except subprocess.CalledProcessError as cpe: logger.error("Called Process Error Message: %s" % cpe.output) raise cpe except OSError as ose: logger.error("OSError: %s" % ose.output) raise ose return (return_code, output)
def copy_ovpl_source(self, vm_id): src_dir = "%s%s%s" % (base_config.VM_ROOT_DIR, base_config.ADS_SERVER_VM_ID, base_adapter.OVPL_DIR_PATH) dest_dir = "%s%s%s" % (base_config.VM_ROOT_DIR, vm_id, base_config.VM_DEST_DIR) logger.debug("vm_id = %s, src_dir=%s, dest_dir=%s" % (vm_id, src_dir, dest_dir)) try: return self.copy_files(str(src_dir), str(dest_dir)) except Exception, e: logger.error("ERROR = %s" % str(e)) return False
c = Controller() # log the user who is deploying the lab.. logger.debug("Lab Deployment: deployed by: %s, lab id: %s, URL: %s" % (post_data['current_user'], post_data['lab_id'], post_data['lab_src_url'])) self.write(c.test_lab(post_data['current_user'], post_data['lab_id'], post_data['lab_src_url'], post_data.get('version', None))) if __name__ == "__main__": env = EnvSetUp.Instance() config_spec = env.get_config_spec() tornado.options.parse_command_line() app = tornado.web.Application( handlers=[ (r"/", MainHandler) ], template_path=os.path.join(os.path.dirname(__file__), "templates"), static_path=os.path.join(os.path.dirname(__file__), "static"), cookie_secret=config_spec["CONTROLLER_CONFIG"]["COOKIE_SECRET"], debug=True) http_server = tornado.httpserver.HTTPServer(app) options.port = config_spec["CONTROLLER_CONFIG"]["SERVER_PORT"] logger.debug("ControllerServer: It will run on port : " + str(options.port)) http_server.listen(options.port) tornado.ioloop.IOLoop.instance().start()