forked from 3wordchant/capsul-flask
delete unused virt model
This commit is contained in:
parent
b1129a8355
commit
44ee42764c
@ -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}
|
|
||||||
""")
|
|
Loading…
Reference in New Issue
Block a user