implemented power steps, unzip, packages, and replace in files
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
Mathieu Broillet 2023-06-12 16:18:09 +02:00
parent fb4154c7e5
commit 6a6cddbc5f
No known key found for this signature in database
GPG Key ID: 7D4F25BC50A0AA32
5 changed files with 172 additions and 18 deletions

View File

@ -322,7 +322,7 @@ The remove-package step will remove a package on the VM/LXC.
*Note : At the the moment, only apt, apk, dnf, yum are supported.* *Note : At the the moment, only apt, apk, dnf, yum are supported.*
*Warning : Packages can have different names depending on the Linux distribution.* *Warning : Packages can have different names depending on the Linux distribution.*
### Reboot ### Power
The reboot step will reboot the VM/LXC. The reboot step will reboot the VM/LXC.
```json ```json
"steps": [ "steps": [
@ -331,6 +331,23 @@ The reboot step will reboot the VM/LXC.
} }
] ]
``` ```
The start step will start the VM/LXC.
```json
"steps": [
{
"type": "start"
}
]
```
The stop step will stop the VM/LXC.
```json
"steps": [
{
"type": "stop"
}
]
```
### Replace in file ### Replace in file
The replace-in-file step will replace a string in a file. The replace-in-file step will replace a string in a file.

View File

@ -67,13 +67,27 @@ def run_steps(lxc):
case "folder_copy": case "folder_copy":
lxc_commands_utils.copy_local_folder_to_lxc(lxc, step["path"], step["destination"]) lxc_commands_utils.copy_local_folder_to_lxc(lxc, step["path"], step["destination"])
case "command": case "command":
lxc.run_command(step["command"], optional(step["working_directory"], None)) lxc.run_command(command=step["command"], working_directory=optional(step["working_directory"], None))
case "docker": case "docker":
lxc_commands_utils.run_docker_command(lxc, step["container"], step["command"]) lxc_commands_utils.run_docker_command(lxc, step["container"], step["command"])
case "docker_compose": case "docker_compose":
lxc_commands_utils.run_docker_compose_command(lxc, step["command"], lxc_commands_utils.run_docker_compose_command(lxc, step["command"],
optional(step["working_directory"], None)) optional(step["working_directory"], None))
case "git": case "git":
lxc.run_command(f"git clone {step['url']} {step['destination']}") lxc.run_command(command=f"git clone {step['url']} {step['destination']}")
case "download": case "download":
lxc_commands_utils.download_file(lxc, step["url"], step["destination"]) lxc_commands_utils.download_file(lxc, step["url"], step["destination"])
case "unzip":
lxc_commands_utils.unzip_file(lxc, step["path"], optional(step["destination"], None))
case "install-package":
lxc_commands_utils.install_package(lxc, step["package"])
case "remove-package":
lxc_commands_utils.remove_package(lxc, step["package"])
case "start":
lxc.start()
case "stop":
lxc.stop()
case "reboot":
lxc.reboot()
case "replace-in-files":
lxc_commands_utils.replace_in_files(lxc, step["files"], step["search"], step["replace"])

View File

@ -1,3 +1,5 @@
from pathlib import Path
from src.utils import proxmox_utils from src.utils import proxmox_utils
from src.utils.resources_utils import get_path from src.utils.resources_utils import get_path
@ -74,3 +76,40 @@ def download_file(lxc, url, destination):
lxc.run_command(f"wget {u} -O {destination}") lxc.run_command(f"wget {u} -O {destination}")
else: else:
lxc.run_command(f"wget {url} -O {destination}") lxc.run_command(f"wget {url} -O {destination}")
def unzip_file(lxc, path, destination=None):
if destination is None:
destination = Path(path).parent
if ".zip" in path:
lxc.run_command(f"unzip {path} -d {destination}")
elif ".tar.gz" in path:
lxc.run_command(f"tar -xzf {path} -C {destination}")
def install_package(lxc, package):
if type(package) is list:
for p in package:
lxc.run_command(f"{proxmox_utils.get_install_package_command(lxc.get_os_name())} {p} -y")
else:
lxc.run_command(f"{proxmox_utils.get_install_package_command(lxc.get_os_name())} {package} -y")
def remove_package(lxc, package):
if type(package) is list:
packages = []
for p in package:
packages.append(p)
lxc.run_command(f"{proxmox_utils.get_remove_package_command(lxc.get_os_name())} {' '.join(packages)}")
else:
lxc.run_command(f"{proxmox_utils.get_remove_package_command(lxc.get_os_name())} {package}")
def replace_in_files(lxc, path, search, replace, case_sensitive=False):
if type(path) is list:
for p in path:
lxc.run_command(f"sed -i {'-i' if case_sensitive else ''} 's/{search}/{replace}/g' {p}")
else:
lxc.run_command(f"sed -i {'-i' if case_sensitive else ''} 's/{search}/{replace}/g' {path}")

View File

@ -148,11 +148,11 @@ class LXC:
template_name = proxmox_utils.run_command_on_pve( template_name = proxmox_utils.run_command_on_pve(
f"pveam available --section system | awk /'{self.os_name}-{self.os_release}/' | awk '{{print \\$2}}'") f"pveam available --section system | awk /'{self.os_name}-{self.os_release}/' | awk '{{print \\$2}}'")
is_template_downloaded = proxmox_utils.run_command_on_pve(f"pveam list local | awk /'{template_name}/'") is_template_downloaded = proxmox_utils.run_command_on_pve(command=f"pveam list local | awk /'{template_name}/'")
if is_template_downloaded == "": if is_template_downloaded == "":
logging.info(f"Template {template_name} not found, downloading it...") logging.info(f"Template {template_name} not found, downloading it...")
proxmox_utils.run_command_on_pve(f"pveam download local {template_name}", True) proxmox_utils.run_command_on_pve(command=f"pveam download local {template_name}", warn_exit_status=True)
return f"local:vztmpl/{template_name}" return f"local:vztmpl/{template_name}"
@ -305,7 +305,7 @@ class LXC:
Is running Is running
:return: is lxc running? (boolean) :return: is lxc running? (boolean)
""" """
return proxmox_utils.run_command_on_pve(f"pct list | awk '/running/ && /{self.lxc_id}/'") != "" return proxmox_utils.run_command_on_pve(command=f"pct list | awk '/running/ && /{self.lxc_id}/'") != ""
def does_exist(self): def does_exist(self):
""" """
@ -323,7 +323,21 @@ class LXC:
return return
else: else:
logging.info(f"Starting LXC {self.lxc_id}") logging.info(f"Starting LXC {self.lxc_id}")
proxmox_utils.run_command_on_pve(f"pct start {self.lxc_id}", True) proxmox_utils.run_command_on_pve(command=f"pct start {self.lxc_id}", warn_exit_status=True)
def stop(self):
"""
Stop LXC
"""
logging.info(f"Stopping LXC {self.lxc_id}")
proxmox_utils.run_command_on_pve(command=f"pct stop {self.lxc_id}", warn_exit_status=True)
def reboot(self):
"""
Reboot LXC
"""
logging.info(f"Rebooting LXC {self.lxc_id}")
proxmox_utils.run_command_on_pve(command=f"pct reboot {self.lxc_id}", warn_exit_status=True)
def create(self): def create(self):
""" """
@ -331,10 +345,10 @@ class LXC:
""" """
if self.does_exist(): if self.does_exist():
logging.info(f"LXC {self.lxc_id} already exists, skipping creation") logging.info(f"LXC {self.lxc_id} already exists, skipping creation")
proxmox_utils.run_command_on_pve(self.get_pct_command(create=False), True) proxmox_utils.run_command_on_pve(command=self.get_pct_command(create=False), warn_exit_status=True)
else: else:
logging.info(f"Creating LXC {self.lxc_id}") logging.info(f"Creating LXC {self.lxc_id}")
proxmox_utils.run_command_on_pve(self.get_pct_command(create=True), 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']: if proxmox_utils.get_config()['settings']['setAuthorizedHostsSSH']:
pve_public_key = proxmox_utils.get_ssh_public_key() pve_public_key = proxmox_utils.get_ssh_public_key()
@ -393,9 +407,11 @@ class LXC:
command = f"cd {working_directory} && {command}" command = f"cd {working_directory} && {command}"
if only_code: if only_code:
return proxmox_utils.run_command_on_pve(f"pct exec {self.lxc_id} -- {command}", warn_exit_status, only_code) 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)
return proxmox_utils.run_command_on_pve(f"pct exec {self.lxc_id} -- {command}", warn_exit_status) 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):
""" """

View File

@ -11,7 +11,7 @@ def get_pve_version():
Get PVE version Get PVE version
:return: pve version :return: pve version
""" """
return run_command_on_pve("pveversion", True) return run_command_on_pve(command="pveversion", warn_exit_status=True)
def get_pve_hostname(): def get_pve_hostname():
@ -19,7 +19,7 @@ def get_pve_hostname():
Get PVE hostname Get PVE hostname
:return: pve hostname :return: pve hostname
""" """
return run_command_on_pve("hostname", True) return run_command_on_pve(command="hostname", warn_exit_status=True)
def does_lxc_exist(lxc_id): def does_lxc_exist(lxc_id):
@ -30,7 +30,7 @@ def does_lxc_exist(lxc_id):
:return: does lxc exists :return: does lxc exists
""" """
# TODO: only check in VMID column # TODO: only check in VMID column
return lxc_id in run_command_on_pve(f"pct list | awk '/{lxc_id}/'") return lxc_id in run_command_on_pve(command=f"pct list | awk '/{lxc_id}/'")
def does_qemu_vm_exist(vm_id): def does_qemu_vm_exist(vm_id):
@ -41,7 +41,7 @@ def does_qemu_vm_exist(vm_id):
:return: does qemu vm exists :return: does qemu vm exists
""" """
# TODO: only check in VMID column # TODO: only check in VMID column
return vm_id in run_command_on_pve(f"qm list {vm_id}") return vm_id in run_command_on_pve(command=f"qm list {vm_id}")
def execute_tteck_script(script_url, env_variables): def execute_tteck_script(script_url, env_variables):
@ -55,7 +55,7 @@ def execute_tteck_script(script_url, env_variables):
env_variables = " ".join(env_variables) env_variables = " ".join(env_variables)
run_command_on_pve(f"{env_variables} && bash -c \"$(wget -qLO - {script_url}\"", True) run_command_on_pve(command=f"{env_variables} && bash -c \"$(wget -qLO - {script_url}\"", warn_exit_status=True)
def get_config(): def get_config():
@ -118,7 +118,75 @@ def run_command_on_pve(command, warn_exit_status=False, only_code=False, local=F
def run_command_locally(command, warn_exit_status=False, only_code=False): def run_command_locally(command, warn_exit_status=False, only_code=False):
run_command_on_pve(command, warn_exit_status, only_code, local=True) run_command_on_pve(command=command, warn_exit_status=warn_exit_status, only_code=only_code, local=True)
def get_install_package_command(distribution):
"""
Get the install package without interaction command based on the distribution.
:param distribution: Distribution name
:return: Install package command
"""
distribution = distribution.lower()
if distribution == "debian":
return "apt-get install -y"
elif distribution == "ubuntu":
return "apt-get install -y"
elif distribution == "centos":
return "yum install -y"
elif distribution == "fedora":
return "yum install -y"
elif distribution == "gentoo":
return "emerge -a"
elif distribution == "alpine":
return "apk add --no-cache"
elif distribution == "archlinux":
return "pacman -S --noconfirm"
elif distribution == "devuan":
return "apt-get install -y"
elif distribution == "nixos":
return "nix-env -i"
elif distribution == "opensuse":
return "zypper install -y"
else:
raise Exception(f"Unsupported distribution: {distribution}")
def get_remove_package_command(distribution):
"""
Get the remove package without interaction command based on the distribution.
:param distribution: Distribution name
:return: Remove package command
"""
distribution = distribution.lower()
if distribution == "debian":
return "apt-get remove -y"
elif distribution == "ubuntu":
return "apt-get remove -y"
elif distribution == "centos":
return "yum remove -y"
elif distribution == "fedora":
return "yum remove -y"
elif distribution == "gentoo":
return "emerge -C"
elif distribution == "alpine":
return "apk del"
elif distribution == "archlinux":
return "pacman -R --noconfirm"
elif distribution == "devuan":
return "apt-get remove -y"
elif distribution == "nixos":
return "nix-env -e"
elif distribution == "opensuse":
return "zypper remove -y"
else:
raise Exception(f"Unsupported distribution: {distribution}")
def get_ssh_public_key(): def get_ssh_public_key():
@ -126,4 +194,4 @@ def get_ssh_public_key():
Get SSH public key Get SSH public key
:return: ssh public key :return: ssh public key
""" """
return run_command_on_pve("cat ~/.ssh/id_rsa.pub", True) return run_command_on_pve(command="cat ~/.ssh/id_rsa.pub", warn_exit_status=True)