forked from 3wordchant/capsul-flask
		
	delete unused virt model
This commit is contained in:
		| @ -1,193 +0,0 @@ | ||||
| import subprocess | ||||
| import re | ||||
| import sys | ||||
| import json | ||||
|  | ||||
| from flask import current_app | ||||
| from time import sleep | ||||
| from os.path import join | ||||
| from subprocess import run | ||||
|  | ||||
| from capsulflask.db import get_model | ||||
| from capsulflask.shared import my_exec_info_message, VirtualMachine | ||||
|  | ||||
| def validate_capsul_id(id): | ||||
|   if not re.match(r"^(cvm|capsul)-[a-z0-9]{10}$", id): | ||||
|     raise ValueError(f"vm id \"{id}\" must match \"^capsul-[a-z0-9]{{10}}$\"") | ||||
|  | ||||
| class VirtualizationInterface: | ||||
|   def capacity_avaliable(self, additional_ram_bytes: int) -> bool: | ||||
|     pass | ||||
|  | ||||
|   def get(self, id: str, get_ssh_host_keys: bool) -> VirtualMachine: | ||||
|     pass | ||||
|  | ||||
|   def list_ids(self) -> list: | ||||
|     pass | ||||
|  | ||||
|   def create(self, email: str, id: str, template_image_file_name: str, vcpus: int, memory: int, ssh_authorized_keys: list): | ||||
|     pass | ||||
|  | ||||
|   def destroy(self, email: str, id: str): | ||||
|     pass | ||||
|  | ||||
| class MockVirtualization(VirtualizationInterface): | ||||
|   def capacity_avaliable(self, additional_ram_bytes): | ||||
|     return True | ||||
|  | ||||
|   def get(self, id, get_ssh_host_keys): | ||||
|     validate_capsul_id(id) | ||||
|  | ||||
|     if get_ssh_host_keys: | ||||
|       ssh_host_keys = json.loads("""[ | ||||
|         {"key_type":"ED25519", "content":"ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN8cna0zeKSKl/r8whdn/KmDWhdzuWRVV0GaKIM+eshh", "sha256":"V4X2apAF6btGAfS45gmpldknoDX0ipJ5c6DLfZR2ttQ"}, | ||||
|         {"key_type":"RSA", "content":"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCvotgzgEP65JUQ8S8OoNKy1uEEPEAcFetSp7QpONe6hj4wPgyFNgVtdoWdNcU19dX3hpdse0G8OlaMUTnNVuRlbIZXuifXQ2jTtCFUA2mmJ5bF+XjGm3TXKMNGh9PN+wEPUeWd14vZL+QPUMev5LmA8cawPiU5+vVMLid93HRBj118aCJFQxLgrdP48VPfKHFRfCR6TIjg1ii3dH4acdJAvlmJ3GFB6ICT42EmBqskz2MPe0rIFxH8YohCBbAbrbWYcptHt4e48h4UdpZdYOhEdv89GrT8BF2C5cbQ5i9qVpI57bXKrj8hPZU5of48UHLSpXG8mbH0YDiOQOfKX/Mt", "sha256":"ghee6KzRnBJhND2kEUZSaouk7CD6o6z2aAc8GPkV+GQ"}, | ||||
|         {"key_type":"ECDSA", "content":"ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLLgOoATz9R4aS2kk7vWoxX+lshK63t9+5BIHdzZeFE1o+shlcf0Wji8cN/L1+m3bi0uSETZDOAWMP3rHLJj9Hk=", "sha256":"aCYG1aD8cv/TjzJL0bi9jdabMGksdkfa7R8dCGm1yYs"} | ||||
|       ]""") | ||||
|       return VirtualMachine(id, ipv4="1.1.1.1", ssh_host_keys=ssh_host_keys) | ||||
|  | ||||
|     return VirtualMachine(id, ipv4="1.1.1.1") | ||||
|  | ||||
|   def list_ids(self) -> list: | ||||
|     return get_model().all_non_deleted_vm_ids() | ||||
|  | ||||
|   def create(self, email: str, id: str, template_image_file_name: str, vcpus: int, memory_mb: int, ssh_authorized_keys: list): | ||||
|     validate_capsul_id(id) | ||||
|     current_app.logger.info(f"mock create: {id} for {email}") | ||||
|     sleep(1) | ||||
|  | ||||
|   def destroy(self, email: str, id: str): | ||||
|     current_app.logger.info(f"mock destroy: {id} for {email}") | ||||
|  | ||||
|  | ||||
| class ShellScriptVirtualization(VirtualizationInterface): | ||||
|  | ||||
|   def validate_completed_process(self, completedProcess, email=None): | ||||
|     emailPart = "" | ||||
|     if email != None: | ||||
|       emailPart = f"for {email}" | ||||
|  | ||||
|     if completedProcess.returncode != 0: | ||||
|       raise RuntimeError(f"""{" ".join(completedProcess.args)} failed {emailPart} with exit code {completedProcess.returncode} | ||||
|         stdout: | ||||
|         {completedProcess.stdout} | ||||
|         stderr: | ||||
|         {completedProcess.stderr} | ||||
|       """) | ||||
|  | ||||
|   def capacity_avaliable(self, additional_ram_bytes): | ||||
|     my_args=[join(current_app.root_path, 'shell_scripts/capacity-avaliable.sh'), str(additional_ram_bytes)] | ||||
|     completedProcess = run(my_args, capture_output=True) | ||||
|  | ||||
|     if completedProcess.returncode != 0: | ||||
|       current_app.logger.error(f""" | ||||
|       capacity-avaliable.sh exited {completedProcess.returncode} with | ||||
|         stdout: | ||||
|         {completedProcess.stdout} | ||||
|         stderr: | ||||
|         {completedProcess.stderr} | ||||
|       """) | ||||
|       return False | ||||
|  | ||||
|     lines = completedProcess.stdout.splitlines() | ||||
|     output = lines[len(lines)-1] | ||||
|     if not output == b"yes": | ||||
|       current_app.logger.error(f"capacity-avaliable.sh exited 0 and returned {output} but did not return \"yes\" ") | ||||
|       return False | ||||
|  | ||||
|     return True | ||||
|  | ||||
|   def get(self, id, get_ssh_host_keys): | ||||
|     validate_capsul_id(id) | ||||
|     completedProcess = run([join(current_app.root_path, 'shell_scripts/get.sh'), id], capture_output=True) | ||||
|     self.validate_completed_process(completedProcess) | ||||
|     ipaddr_lines = completedProcess.stdout.splitlines() | ||||
|     if len(ipaddr_lines) == 0: | ||||
|       return None | ||||
|  | ||||
|     ipaddr = ipaddr_lines[0].decode("utf-8") | ||||
|  | ||||
|     if not re.match(r"^([0-9]{1,3}\.){3}[0-9]{1,3}$", ipaddr): | ||||
|       return None | ||||
|  | ||||
|     if get_ssh_host_keys: | ||||
|       try: | ||||
|         completedProcess2 = run([join(current_app.root_path, 'shell_scripts/ssh-keyscan.sh'), ipaddr], capture_output=True) | ||||
|         self.validate_completed_process(completedProcess2) | ||||
|         ssh_host_keys = json.loads(completedProcess2.stdout.decode("utf-8")) | ||||
|         return VirtualMachine(id, ipv4=ipaddr, ssh_host_keys=ssh_host_keys) | ||||
|       except: | ||||
|         current_app.logger.warning(f""" | ||||
|           failed to ssh-keyscan {id} at {ipaddr}: | ||||
|           {my_exec_info_message(sys.exc_info())}""" | ||||
|         ) | ||||
|  | ||||
|     return VirtualMachine(id, ipv4=ipaddr) | ||||
|  | ||||
|   def list_ids(self) -> list: | ||||
|     completedProcess = run([join(current_app.root_path, 'shell_scripts/list-ids.sh')], capture_output=True) | ||||
|     self.validate_completed_process(completedProcess) | ||||
|     return list(map(lambda x: x.decode("utf-8"), completedProcess.stdout.splitlines() )) | ||||
|  | ||||
|   def create(self, email: str, id: str, template_image_file_name: str, vcpus: int, memory_mb: int, ssh_authorized_keys: list): | ||||
|     validate_capsul_id(id) | ||||
|  | ||||
|     if not re.match(r"^[a-zA-Z0-9/_.-]+$", template_image_file_name): | ||||
|       raise ValueError(f"template_image_file_name \"{template_image_file_name}\" must match \"^[a-zA-Z0-9/_.-]+$\"") | ||||
|  | ||||
|     for ssh_public_key in ssh_authorized_keys: | ||||
|       if not re.match(r"^(ssh|ecdsa)-[0-9A-Za-z+/_=@. -]+$", ssh_public_key): | ||||
|         raise ValueError(f"ssh_public_key \"{ssh_public_key}\" must match \"^(ssh|ecdsa)-[0-9A-Za-z+/_=@. -]+$\"") | ||||
|  | ||||
|     if vcpus < 1 or vcpus > 8: | ||||
|       raise ValueError(f"vcpus \"{vcpus}\" must match 1 <= vcpus <= 8") | ||||
|  | ||||
|     if memory_mb < 512 or memory_mb > 16384: | ||||
|       raise ValueError(f"memory_mb \"{memory_mb}\" must match 512 <= memory_mb <= 16384") | ||||
|  | ||||
|     ssh_keys_string = "\n".join(ssh_authorized_keys) | ||||
|  | ||||
|     completedProcess = run([ | ||||
|       join(current_app.root_path, 'shell_scripts/create.sh'), | ||||
|       id, | ||||
|       template_image_file_name, | ||||
|       str(vcpus), | ||||
|       str(memory_mb), | ||||
|       ssh_keys_string | ||||
|     ], capture_output=True) | ||||
|  | ||||
|     self.validate_completed_process(completedProcess, email) | ||||
|     lines = completedProcess.stdout.splitlines() | ||||
|     status = lines[len(lines)-1].decode("utf-8") | ||||
|  | ||||
|     vmSettings = f""" | ||||
|       id={id} | ||||
|       template_image_file_name={template_image_file_name} | ||||
|       vcpus={str(vcpus)} | ||||
|       memory={str(memory_mb)} | ||||
|       ssh_authorized_keys={ssh_keys_string} | ||||
|     """ | ||||
|  | ||||
|     if not status == "success": | ||||
|       raise ValueError(f"""failed to create vm for {email} with: | ||||
|         {vmSettings} | ||||
|         stdout: | ||||
|         {completedProcess.stdout} | ||||
|         stderr: | ||||
|         {completedProcess.stderr} | ||||
|       """) | ||||
|  | ||||
|   def destroy(self, email: str, id: str): | ||||
|     validate_capsul_id(id) | ||||
|     completedProcess = run([join(current_app.root_path, 'shell_scripts/destroy.sh'), id], capture_output=True) | ||||
|     self.validate_completed_process(completedProcess, email) | ||||
|     lines = completedProcess.stdout.splitlines() | ||||
|     status = lines[len(lines)-1].decode("utf-8") | ||||
|  | ||||
|     if not status == "success": | ||||
|       raise ValueError(f"""failed to destroy vm "{id}" for {email}: | ||||
|         stdout: | ||||
|         {completedProcess.stdout} | ||||
|         stderr: | ||||
|         {completedProcess.stderr} | ||||
|       """) | ||||
		Reference in New Issue
	
	Block a user