Compare commits

...

2 Commits

Author SHA1 Message Date
e6dd3d81ce
sped up the soft by about 3x using basic caching and threads
All checks were successful
continuous-integration/drone/push Build is passing
2023-06-20 10:01:13 +02:00
7ed109f70b
revert caching system 2023-06-20 08:56:02 +02:00
3 changed files with 49 additions and 85 deletions

View File

@ -176,19 +176,7 @@ class LXC(LinuxMachine):
Get IPv4 Get IPv4
:return: ipv4 :return: ipv4
""" """
if self.is_running(): if self.ipv4 == "dhcp" or self.ipv4 == "auto":
if netmask:
return self.get_in_cache('network', 'ipv4_netmask',
default_value=self.retrieve_ipv4(netmask=netmask, use_ssh=use_ssh))
else:
return self.get_in_cache('network', 'ipv4',
default_value=self.retrieve_ipv4(netmask=netmask, use_ssh=use_ssh))
return self.ipv4
def retrieve_ipv4(self, netmask: bool = False, use_ssh: bool = False):
if self.ipv4 == "dhcp":
if self.is_running(): if self.is_running():
if self.has_program("ip", use_ssh=use_ssh): if self.has_program("ip", use_ssh=use_ssh):
if netmask: if netmask:
@ -315,6 +303,7 @@ class LXC(LinuxMachine):
Start LXC Start LXC
""" """
self.pve.start_lxc(self.lxc_id) self.pve.start_lxc(self.lxc_id)
self.ipv4 = self.get_ipv4()
def stop(self): def stop(self):
""" """

View File

@ -6,7 +6,8 @@ from src.utils import utils
class LinuxMachine(): class LinuxMachine():
def __init__(self): def __init__(self):
self.cache = {} self.known_programs = []
pass
def update(self): def update(self):
pass pass
@ -29,38 +30,21 @@ class LinuxMachine():
def get_memory(self): def get_memory(self):
"""Get memory""" """Get memory"""
return self.run_command("free -m | grep Mem | awk '{print $2}'")
memory = self.get_in_cache('system', 'memory')
if memory is None:
self.set_in_cache('system', 'memory', self.run_command("free -m | grep Mem | awk '{print $2}'"))
return self.get_in_cache('system', 'memory')
def get_ipv4(self): def get_ipv4(self):
"""Get IPv4 address""" """Get IPv4 address"""
ipv4 = self.get_in_cache('system', 'ipv4') if self.has_program("ip"):
if ipv4 is None: return self.run_command("""ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print $2}' | cut -f1 -d'/'""")
if self.has_program("ip"): elif self.has_program("ifconfig"):
self.set_in_cache('system', 'ipv4', self.run_command(command= return self.run_command(command="ifconfig eth0 | awk '/inet addr/{print substr($2,6)}'")
"""ip addr | grep 'state UP' -A2 | tail -n1 |
awk '{print $2}' | cut -f1 -d'/'"""))
elif self.has_program("ifconfig"):
self.set_in_cache('system', 'ipv4',
self.run_command(command="ifconfig eth0 | awk '/inet addr/{print substr($2,6)}'"))
return self.get_in_cache('system', 'ipv4')
def get_ipv6(self): def get_ipv6(self):
pass pass
def get_mac(self): def get_mac(self):
"""Get MAC address""" """Get MAC address"""
mac = self.get_in_cache('system', 'mac') return self.run_command("""cat /sys/class/net/$(ip route show default | awk '/default/ {print $5}')/address""")
if mac is None:
self.set_in_cache('system', 'mac', self.run_command(
"""cat /sys/class/net/$(ip route show default | awk '/default/ {print $5}')/address"""))
return self.get_in_cache('system', 'mac')
def start(self): def start(self):
pass pass
@ -77,18 +61,16 @@ class LinuxMachine():
:return: boolean :return: boolean
""" """
if program in self.known_programs:
return True
if type(program) == str: if type(program) == str:
program_cache = self.get_in_cache('known_programs', program) result = self.run_command("which " + program, return_status_code=True, use_ssh=use_ssh) == 0
if program_cache is None: if result:
self.set_in_cache('known_programs', program, str(self.run_command("which " + program, self.known_programs.append(program)
return_status_code=True, return result
use_ssh=use_ssh) == 0))
return bool(self.get_in_cache('known_programs', program))
elif type(program) == list: elif type(program) == list:
programs = [] return all(self.has_program(program=p, use_ssh=use_ssh) for p in program)
for p in program:
programs.append(self.has_program(p))
return all(programs)
def has_file(self, file: str or Path): def has_file(self, file: str or Path):
"""Check if file exists on LXC """Check if file exists on LXC
@ -326,25 +308,3 @@ class LinuxMachine():
else: else:
self.run_command(f"sed {'-i' if case_sensitive else ''} 's/{search}/{replace}/g' {path}", self.run_command(f"sed {'-i' if case_sensitive else ''} 's/{search}/{replace}/g' {path}",
return_status_code=True) return_status_code=True)
def get_in_cache(self, category: str, property: str, default_value: any = None):
if default_value is not None and property not in self.cache[category]:
self.set_in_cache(category, property, default_value)
if category in self.cache:
if property in self.cache[category]:
return self.cache[category][property]
else:
return None
def set_in_cache(self, category: str, property: str = None, value: str = None):
if category not in self.cache:
self.cache[category] = {}
if property is not None and value is not None:
if property not in self.cache[category]:
self.cache[category] = {}
self.cache[category] = {property: value}
else:
raise ValueError("Key and value must be specified to save in the cache")

View File

@ -41,13 +41,9 @@ class ProxmoxHost(LinuxMachine):
self.connection = None self.connection = None
self.repo_path = path.as_posix() self.repo_path = path.as_posix()
threading.Thread(target=self.update).start() self.running_lxcs = []
def __str__(self): threading.Thread(target=self.update, daemon=True).start()
return f"ProxmoxHost({self.host}, {self.user}, {self.port})"
def __repr__(self):
return f"ProxmoxHost({self.host}, {self.user}, {self.port})"
def update(self): def update(self):
update_connection = Connection(host=self.host, user=self.user, port=self.port) update_connection = Connection(host=self.host, user=self.user, port=self.port)
@ -56,10 +52,25 @@ class ProxmoxHost(LinuxMachine):
1:] 1:]
for line in pct_output: for line in pct_output:
if line.strip(): if line.strip():
vmid, status, name = line.split() if len(line.split()) == 3:
self.set_in_cache('lxc', vmid.strip(), str("running" in status.strip())) vm_id, status, name = line.split()
else:
vm_id, status, lock, name = line.split()
time.sleep(1) if "running" in status:
if vm_id not in self.running_lxcs:
self.running_lxcs.append(int(vm_id))
else:
if vm_id in self.running_lxcs:
self.running_lxcs.remove(int(vm_id))
time.sleep(0.5)
def __str__(self):
return f"ProxmoxHost({self.host}, {self.user}, {self.port})"
def __repr__(self):
return f"ProxmoxHost({self.host}, {self.user}, {self.port})"
def connect(self): def connect(self):
"""Connect to the Proxmox host.""" """Connect to the Proxmox host."""
@ -114,16 +125,18 @@ class ProxmoxHost(LinuxMachine):
if the stdout is empty and exception_on_empty_stdout is True if the stdout is empty and exception_on_empty_stdout is True
""" """
# Check if host is None, if it is, run the command locally, else run it on the host via SSH
start_time = time.time() start_time = time.time()
# Check if host is None, if it is, run the command locally, else run it on the host via SSH
if self.host is None: if self.host is None:
command_result = subprocess.run(command, shell=True, capture_output=True, encoding="utf-8") command_result = subprocess.run(command, shell=True, capture_output=True, encoding="utf-8")
elif self.connection is not None: elif self.connection is not None:
command_result = self.connection.run(command, hide=True, warn=True, encoding="utf-8") command_result = self.connection.run(command, hide=True, warn=True, encoding="utf-8")
else: else:
raise Exception("No host or connection provided") raise Exception("No host or connection provided")
print(f"Time taken for {command}: {time.time() - start_time}")
end_time = time.time()
print(f"Command {command} took {end_time - start_time} seconds to run")
# If return code is not 0 and that exception_on_exit is True and return_status_code is False, throw an exception # If return code is not 0 and that exception_on_exit is True and return_status_code is False, throw an exception
if command_result.return_code != 0 and exception_on_exit and not return_status_code: if command_result.return_code != 0 and exception_on_exit and not return_status_code:
@ -167,12 +180,14 @@ class ProxmoxHost(LinuxMachine):
def is_lxc_running(self, lxc_id): def is_lxc_running(self, lxc_id):
"""Check if the given LXC is running on the Proxmox host.""" """Check if the given LXC is running on the Proxmox host."""
lxc = self.get_in_cache('lxc', lxc_id) if lxc_id in self.running_lxcs:
if lxc is None: return True
self.set_in_cache('lxc', lxc_id, else:
str('running' in self.run_command(f"pct status {lxc_id}", exception_on_exit=False))) return False
return self.get_in_cache('lxc', lxc_id) # Not used anymore because it's too slow, now using an update thread to keep track of running LXCs
# pct_status_output = self.run_command(f"pct status {lxc_id}", exception_on_exit=False)
# return "running" in pct_status_output
def start_lxc(self, lxc_id): def start_lxc(self, lxc_id):
"""Start the given LXC on the Proxmox host.""" """Start the given LXC on the Proxmox host."""