Compare commits

...

4 Commits

8 changed files with 59 additions and 29 deletions

View File

@ -6,6 +6,5 @@
"local": false "local": false
}, },
"settings": { "settings": {
"setAuthorizedHostsSSH": true
} }
} }

View File

@ -37,9 +37,6 @@
{ {
"type": "script", "type": "script",
"path": "/global/install-docker.sh" "path": "/global/install-docker.sh"
},
{
"type": ""
} }
] ]
}, },

View File

@ -25,4 +25,4 @@ def run():
logging.info(f"Loading LXC {lxc.lxc_id}") logging.info(f"Loading LXC {lxc.lxc_id}")
lxc.create() lxc.create()
lxc.start() lxc.start()
lxc.check_creation_conditions() lxc.run_creation()

View File

@ -74,14 +74,14 @@ def run_steps(lxc):
""" """
creation = lxc.get_creation() creation = lxc.get_creation()
creation_steps = creation["creation_steps"] creation_steps = creation["steps"]
for step in creation_steps: for step in creation_steps:
match step["type"]: match step["type"]:
# Support for scripts # Support for scripts
case "script": case "script":
lxc_commands_utils.run_script(step, lxc) lxc_commands_utils.run_script(lxc, step)
case "file_create": case "file_create":
lxc_commands_utils.create_file_in_lxc(lxc, step["path"], optional(step["permission"], 644)) lxc_commands_utils.create_file_in_lxc(lxc, step["path"], optional(step["permission"], 644))
case "file_copy": case "file_copy":

View File

@ -17,6 +17,11 @@ def run_script(lxc, step):
Typically read from the "creation/steps/<step>" in JSON file Typically read from the "creation/steps/<step>" in JSON file
""" """
# Install bash if not installed
# Sometimes only ash or sh are installed, which doesn't work for some scripts
if not lxc.has_program("bash"):
install_package(lxc, "bash")
# Run local script # Run local script
if "path" in step: if "path" in step:
_run_local_script_on_lxc(lxc, step["path"]) _run_local_script_on_lxc(lxc, step["path"])
@ -42,7 +47,7 @@ def _run_local_script_on_lxc(lxc, path: "Path to the script on the machine runni
path = get_path(lxc, path) path = get_path(lxc, path)
with open(path, "r") as file: with open(path, "r") as file:
script = file.read() script = file.read()
lxc.run_command("'bash -s' <<'ENDSSH'\n" + script) lxc.run_command("bash <<EOF\n" + script + "\nEOF")
def _run_remote_script_on_lxc(lxc, url: "URL to the script"): def _run_remote_script_on_lxc(lxc, url: "URL to the script"):
@ -196,9 +201,9 @@ def install_package(lxc, package):
if type(package) is list: if type(package) is list:
for p in package: for p in package:
lxc.run_command(f"{proxmox_utils.get_install_package_command(lxc.get_os_name())} {p} -y") lxc.run_command(f"{proxmox_utils.get_install_package_command(lxc.get_os_name())} {p}")
else: else:
lxc.run_command(f"{proxmox_utils.get_install_package_command(lxc.get_os_name())} {package} -y") lxc.run_command(f"{proxmox_utils.get_install_package_command(lxc.get_os_name())} {package}")
def remove_package(lxc, package): def remove_package(lxc, package):

View File

@ -234,6 +234,14 @@ class LXC:
Get IPv4 Get IPv4
:return: ipv4 :return: ipv4
""" """
if self.ipv4 == "dhcp":
if self.is_running():
if self.has_program("ip"):
return self.run_command(
command="ip addr | grep 'state UP' -A2 | tail -n1 | awk '{print \$2}' | cut -f1 -d'/'")
elif self.has_program("ifconfig"):
return self.run_command(command="ifconfig eth0 | awk '/inet addr/{print substr($2,6)}'")
return self.ipv4 return self.ipv4
def get_ipv6(self): def get_ipv6(self):
@ -367,11 +375,7 @@ class LXC:
logging.info(f"Creating LXC {self.lxc_id}") logging.info(f"Creating LXC {self.lxc_id}")
proxmox_utils.run_command_on_pve(command=self.get_pct_command(create=True), warn_exit_status=True) proxmox_utils.run_command_on_pve(command=self.get_pct_command(create=True), warn_exit_status=True)
if proxmox_utils.get_config()['settings']['setAuthorizedHostsSSH']: def run_creation(self):
pve_public_key = proxmox_utils.get_ssh_public_key()
self.run_command(f"echo '{pve_public_key}' >> /root/.ssh/authorized_keys")
def creation(self):
""" """
Run the creations checks and steps Run the creations checks and steps
""" """
@ -411,25 +415,25 @@ class LXC:
""" """
return lxc_commands_utils.run_script(self, {"lxc_path": script_path}) return lxc_commands_utils.run_script(self, {"lxc_path": script_path})
def run_command(self, command, warn_exit_status=False, only_code=False, working_directory=None): def run_command(self, command, ssh=False, warn_exit_status=False, only_code=False, working_directory=None):
""" """
Run command on LXC Run command on LXC
:param command: command to run :param command: command to run
:return: command output :return: command output
""" """
logging.debug(f"Running command {command} on LXC {self.lxc_id}") # logging.debug(f"Running command {command} on LXC {self.lxc_id}")
if working_directory: if working_directory:
command = f"cd {working_directory} && {command}" command = f"cd {working_directory} && {command}"
if only_code: if ssh:
return proxmox_utils.run_command_ssh(command=command, host=self.get_ipv4(), username="root", port=22,
warn_exit_status=warn_exit_status, only_code=only_code)
else:
return proxmox_utils.run_command_on_pve(command=f"pct exec {self.lxc_id} -- {command}", return proxmox_utils.run_command_on_pve(command=f"pct exec {self.lxc_id} -- {command}",
warn_exit_status=warn_exit_status, only_code=only_code) warn_exit_status=warn_exit_status, only_code=only_code)
return proxmox_utils.run_command_on_pve(command=f"pct exec {self.lxc_id} -- {command}",
warn_exit_status=warn_exit_status)
def get_pct_command(self, create=True): def get_pct_command(self, create=True):
""" """
Get pct command to create/edit LXC Get pct command to create/edit LXC
@ -450,6 +454,7 @@ class LXC:
f"--storage {self.storage} " \ f"--storage {self.storage} " \
f"--unprivileged {not self.privileged} " \ f"--unprivileged {not self.privileged} " \
f"--rootfs volume={self.storage}:{self.disk},size={self.disk} " \ f"--rootfs volume={self.storage}:{self.disk},size={self.disk} " \
f"--ssh-public-keys /root/.ssh/id_rsa.pub " \
f"--unprivileged {not self.privileged}" f"--unprivileged {not self.privileged}"
else: else:
# Update command # Update command
@ -464,7 +469,6 @@ class LXC:
# TODO: add gateway4 # TODO: add gateway4
# f"ip6={self.ipv6},gw6={self.gateway6},trunks={self.vlan} " \ # TODO # f"ip6={self.ipv6},gw6={self.gateway6},trunks={self.vlan} " \ # TODO
# f"-ssh-public-keys {self.ssh}" # TODO
return pct_command return pct_command
def get_tteck_env_variables(self): def get_tteck_env_variables(self):
@ -492,7 +496,7 @@ class LXC:
"NS": "", "NS": "",
"MAC": self.mac, "MAC": self.mac,
"VLAN": self.vlan, "VLAN": self.vlan,
"SSH": self.ssh, # "SSH": self.ssh,
"VERB": "no" "VERB": "no"
} }

View File

@ -81,7 +81,7 @@ def run_command_on_pve(command, warn_exit_status=False, only_code=False, local=F
# Check if PVE is local or remote # Check if PVE is local or remote
if config['pve']['local'] or local: if config['pve']['local'] or local:
# Run command and return output (not as bytes) # Run command and return output (not as bytes)
logging.debug(f"Running command on PVE (locally): \n{command}") logging.debug(f"Running command on PVE (locally): {command}")
command = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, command = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
encoding="utf-8") encoding="utf-8")
@ -101,10 +101,10 @@ def run_command_on_pve(command, warn_exit_status=False, only_code=False, local=F
port = config['pve']['port'] port = config['pve']['port']
# Run command on PVE via SSH and return output # Run command on PVE via SSH and return output
logging.debug(f"Running command on PVE (ssh): \n{command}") logging.debug(f"Running command on PVE (ssh): {command}")
# catch errors code # catch errors code
command = subprocess.run(f"ssh {username}@{host} -p {port} \"{command}\"", shell=True, command = subprocess.run(f'ssh {username}@{host} -p {port} "{command}"', shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8") stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8")
if command.returncode != 0 and warn_exit_status: if command.returncode != 0 and warn_exit_status:
@ -121,6 +121,24 @@ def run_command_locally(command, warn_exit_status=False, only_code=False):
run_command_on_pve(command=command, warn_exit_status=warn_exit_status, only_code=only_code, local=True) run_command_on_pve(command=command, warn_exit_status=warn_exit_status, only_code=only_code, local=True)
def run_command_ssh(command, host, username, port=22, warn_exit_status=False, only_code=False):
# Run command on PVE via SSH and return output
logging.debug(f"Running command on host {host} (ssh): {command}")
# catch errors code
command = subprocess.run(f'ssh {username}@{host} -p {port} "{command}"', shell=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8")
if command.returncode != 0 and warn_exit_status:
logging.error(f"Error while running command on PVE: \n{command.stderr}")
raise Exception(f"Error while running command on PVE: \n{command.stderr}")
if only_code:
return command.returncode
return command.stdout.rstrip()
def get_install_package_command(distribution): def get_install_package_command(distribution):
""" """
Get the install package without interaction command based on the distribution. Get the install package without interaction command based on the distribution.
@ -142,7 +160,7 @@ def get_install_package_command(distribution):
elif distribution == "gentoo": elif distribution == "gentoo":
return "emerge -a" return "emerge -a"
elif distribution == "alpine": elif distribution == "alpine":
return "apk add --no-cache" return "apk add"
elif distribution == "archlinux": elif distribution == "archlinux":
return "pacman -S --noconfirm" return "pacman -S --noconfirm"
elif distribution == "devuan": elif distribution == "devuan":

View File

@ -1,8 +1,15 @@
import os
from src.get_path_file import project_path
def get_path(lxc, path): def get_path(lxc, path):
parent = os.path.join(project_path / "resources")
if path.startswith("/global/"): if path.startswith("/global/"):
# Use global folder # Use global folder
return "resources/scripts" + path[len("/global/"):] return parent + "/scripts/" + path[len("/global/"):]
else: else:
# Use VM/LXC folder # Use VM/LXC folder
lxc_id = lxc.get_id() lxc_id = lxc.get_id()
return f"resources/lxc/{lxc_id}/{path}" return parent + f"/resources/lxc/{lxc_id}/{path}"