implemented most creations steps and global improvements
All checks were successful
continuous-integration/drone/push Build is passing
All checks were successful
continuous-integration/drone/push Build is passing
This commit is contained in:
parent
e4188e8432
commit
fb4154c7e5
44
README.md
44
README.md
@ -167,28 +167,50 @@ The script step will execute a script.
|
|||||||
```
|
```
|
||||||
|
|
||||||
### File
|
### File
|
||||||
The file step will copy a file to the VM/LXC.
|
The file step will create / copy a file to the VM/LXC.
|
||||||
```json
|
```json
|
||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"type": "file",
|
"type": "file_create",
|
||||||
"path": "traefik.toml", // local path (here: resources/lxc/<id>/traefik.toml)
|
"path": "/var/data/traefikv2/traefik.toml", // lxc/vm path
|
||||||
"destination": "/var/data/traefikv2/traefik.toml" // lxc/vm path
|
"permissions": "644" // (optional) permissions of the file
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
```json
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"type": "file_copy",
|
||||||
|
"path": "traefik.toml", // local path (here: resources/lxc/<id>/traefik.toml)
|
||||||
|
"destination": "/var/data/traefikv2/traefik.toml", // lxc/vm path
|
||||||
|
"permissions": "644" // (optional) permissions of the file
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
*Note: `file_copy` creates the folder if it doesn't exist*
|
||||||
|
|
||||||
### Folder
|
### Folder
|
||||||
The folder step will copy a folder to the VM/LXC.
|
The folder step will copy a folder to the VM/LXC.
|
||||||
```json
|
```json
|
||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"type": "folder",
|
"type": "folder_create",
|
||||||
"path": "/data/", // local path (here: resources/lxc/<id>/data/)
|
"path": "/var/data/traefikv2", // lxc/vm path
|
||||||
"destination": "/var/data/traefikv2" // lxc/vm path
|
"permissions": "755" // (optional) permissions of the folder
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
```json
|
||||||
|
"steps": [
|
||||||
|
{
|
||||||
|
"type": "folder_copy",
|
||||||
|
"path": "/data/", // local path (here: resources/lxc/<id>/data/)
|
||||||
|
"destination": "/var/data/traefikv2", // lxc/vm path
|
||||||
|
"permissions": "755" // (optional) permissions of the folder
|
||||||
|
}
|
||||||
|
]
|
||||||
|
```
|
||||||
|
*Note: `folder_copy` creates the folder if it doesn't exist*
|
||||||
|
|
||||||
### Command
|
### Command
|
||||||
The command step will execute a command on the VM/LXC.
|
The command step will execute a command on the VM/LXC.
|
||||||
@ -197,19 +219,19 @@ The command step will execute a command on the VM/LXC.
|
|||||||
{
|
{
|
||||||
"type": "command",
|
"type": "command",
|
||||||
"command": "whoami", // command to execute
|
"command": "whoami", // command to execute
|
||||||
"working_directory": "/var/data/config/traefikv2" // lxc/vm path
|
"working_directory": "/var/data/config/traefikv2" // (optional) lxc/vm path
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Docker
|
### Docker
|
||||||
The docker step will execute a docker command on the VM/LXC.
|
The docker step will execute a command inside a docker container running on the VM/LXC.
|
||||||
```json
|
```json
|
||||||
"steps": [
|
"steps": [
|
||||||
{
|
{
|
||||||
"type": "docker",
|
"type": "docker",
|
||||||
"command": "run -d --name=traefikv2 --restart=always -p 80:80 -p 443:443 -p 8080:8080 -v /var/data/traefikv2:/etc/traefik -v /var/data/config/traefikv2:/config -v /var/run/docker.sock:/var/run/docker.sock traefik:latest", // docker command to execute
|
"container": "<container-name>", // docker container name
|
||||||
"working_directory": "/var/data/config/traefikv2" // lxc/vm path
|
"command": "<command-to-run-inside>" // docker command to execute
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
@ -4,5 +4,8 @@
|
|||||||
"user": "root",
|
"user": "root",
|
||||||
"port": 22,
|
"port": 22,
|
||||||
"local": false
|
"local": false
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"setAuthorizedHostsSSH": true
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -25,7 +25,6 @@
|
|||||||
"start_on_boot": "false",
|
"start_on_boot": "false",
|
||||||
"startup_order": 2,
|
"startup_order": 2,
|
||||||
"password": "qwertz1234",
|
"password": "qwertz1234",
|
||||||
"ssh": false,
|
|
||||||
"tags": "2-proxy+auth"
|
"tags": "2-proxy+auth"
|
||||||
},
|
},
|
||||||
"creation": {
|
"creation": {
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import logging
|
import logging
|
||||||
import os
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
|
from src.utils import lxc_commands_utils
|
||||||
|
|
||||||
|
|
||||||
def are_all_conditions_met(lxc):
|
def are_all_conditions_met(lxc):
|
||||||
"""
|
"""
|
||||||
@ -10,7 +11,7 @@ def are_all_conditions_met(lxc):
|
|||||||
If all conditions are met, the deploy/updates steps are run
|
If all conditions are met, the deploy/updates steps are run
|
||||||
Otherwise, we run the creation steps
|
Otherwise, we run the creation steps
|
||||||
|
|
||||||
:param lxc_id: lxc id
|
:param lxc:
|
||||||
:return: are conditions met
|
:return: are conditions met
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@ -34,6 +35,13 @@ def are_all_conditions_met(lxc):
|
|||||||
return all(result)
|
return all(result)
|
||||||
|
|
||||||
|
|
||||||
|
def optional(var, placeholder):
|
||||||
|
if var is None:
|
||||||
|
return placeholder
|
||||||
|
else:
|
||||||
|
return var
|
||||||
|
|
||||||
|
|
||||||
def run_steps(lxc):
|
def run_steps(lxc):
|
||||||
"""
|
"""
|
||||||
Run creation steps for an LXC
|
Run creation steps for an LXC
|
||||||
@ -49,48 +57,23 @@ def run_steps(lxc):
|
|||||||
|
|
||||||
# Support for scripts
|
# Support for scripts
|
||||||
case "script":
|
case "script":
|
||||||
run_script(step, lxc)
|
lxc_commands_utils.run_script(step, lxc)
|
||||||
|
case "file_create":
|
||||||
|
lxc_commands_utils.create_file_in_lxc(lxc, step["path"], optional(step["permission"], 644))
|
||||||
def run_script(step, lxc):
|
case "file_copy":
|
||||||
# Run local script
|
lxc_commands_utils.copy_local_file_to_lxc(lxc, step["path"], step["destination"])
|
||||||
if "path" in step:
|
case "folder":
|
||||||
path = step["path"]
|
lxc_commands_utils.create_folder_in_lxc(lxc, step["path"], optional(step["permission"], 755))
|
||||||
|
case "folder_copy":
|
||||||
with open(path, "r") as file:
|
lxc_commands_utils.copy_local_folder_to_lxc(lxc, step["path"], step["destination"])
|
||||||
script = file.read()
|
case "command":
|
||||||
lxc.run_command("'bash -s' <<'ENDSSH'\n" + script)
|
lxc.run_command(step["command"], optional(step["working_directory"], None))
|
||||||
|
case "docker":
|
||||||
# Run remote script
|
lxc_commands_utils.run_docker_command(lxc, step["container"], step["command"])
|
||||||
elif "url" in step:
|
case "docker_compose":
|
||||||
url = step["url"]
|
lxc_commands_utils.run_docker_compose_command(lxc, step["command"],
|
||||||
lxc.has
|
optional(step["working_directory"], None))
|
||||||
pass
|
case "git":
|
||||||
|
lxc.run_command(f"git clone {step['url']} {step['destination']}")
|
||||||
# Run script in LXC
|
case "download":
|
||||||
elif "lxc_path" in step:
|
lxc_commands_utils.download_file(lxc, step["url"], step["destination"])
|
||||||
lxc_path = step["lxc_path"]
|
|
||||||
pass
|
|
||||||
|
|
||||||
path = step["path"]
|
|
||||||
if path.startswith("/global/"):
|
|
||||||
# Use global folder
|
|
||||||
full_path = "resources/scripts" + path[len("/global/"):]
|
|
||||||
else:
|
|
||||||
# Use VM/LXC folder
|
|
||||||
lxc_id = lxc.get_id()
|
|
||||||
full_path = f"resources/lxc/{lxc_id}/{path}"
|
|
||||||
|
|
||||||
if os.path.isfile(full_path):
|
|
||||||
lxc.run_command(f"bash {full_path}")
|
|
||||||
|
|
||||||
|
|
||||||
def has_program(lxc, program):
|
|
||||||
"""
|
|
||||||
Check if program is installed in LXC
|
|
||||||
|
|
||||||
:param lxc: lxc
|
|
||||||
:param program: program
|
|
||||||
:return: is program installed
|
|
||||||
"""
|
|
||||||
return lxc.run_command("which " + program, only_code=True) == 0
|
|
||||||
|
76
src/utils/lxc_commands_utils.py
Normal file
76
src/utils/lxc_commands_utils.py
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
from src.utils import proxmox_utils
|
||||||
|
from src.utils.resources_utils import get_path
|
||||||
|
|
||||||
|
|
||||||
|
def run_script(lxc, step):
|
||||||
|
# Run local script
|
||||||
|
if "path" in step:
|
||||||
|
_run_local_script_on_lxc(lxc, step["path"])
|
||||||
|
|
||||||
|
# Run remote script
|
||||||
|
elif "url" in step:
|
||||||
|
_run_remote_script_on_lxc(lxc, step["url"])
|
||||||
|
|
||||||
|
# Run script in LXC
|
||||||
|
elif "lxc_path" in step:
|
||||||
|
_run_script_on_lxc(lxc, step["lxc_path"])
|
||||||
|
|
||||||
|
|
||||||
|
def _run_script_on_lxc(lxc, path):
|
||||||
|
lxc.run_command(f"bash {path}")
|
||||||
|
|
||||||
|
|
||||||
|
def _run_local_script_on_lxc(lxc, path):
|
||||||
|
path = get_path(lxc, path)
|
||||||
|
with open(path, "r") as file:
|
||||||
|
script = file.read()
|
||||||
|
lxc.run_command("'bash -s' <<'ENDSSH'\n" + script)
|
||||||
|
|
||||||
|
|
||||||
|
def _run_remote_script_on_lxc(lxc, url):
|
||||||
|
if lxc.has_program("curl"):
|
||||||
|
lxc.run_command(f"curl -sSL {url} | bash")
|
||||||
|
|
||||||
|
|
||||||
|
def create_folder_in_lxc(lxc, path, permission=755):
|
||||||
|
lxc.run_command(f"mkdir -p {path}")
|
||||||
|
|
||||||
|
if permission != 755:
|
||||||
|
lxc.run_command(f"chmod -R {permission} {path}")
|
||||||
|
|
||||||
|
|
||||||
|
def create_file_in_lxc(lxc, path, permission=644):
|
||||||
|
lxc.run_command(f"touch {path}")
|
||||||
|
if permission != 644:
|
||||||
|
lxc.run_command(f"chmod {permission} {path}")
|
||||||
|
|
||||||
|
|
||||||
|
def copy_local_file_to_lxc(lxc, path, destination):
|
||||||
|
proxmox_utils.run_command_locally(f"scp {path} {lxc.get_ssh_string()}:{destination}")
|
||||||
|
|
||||||
|
|
||||||
|
def copy_local_folder_to_lxc(lxc, path, destination):
|
||||||
|
proxmox_utils.run_command_locally(f"scp -r {path} {lxc.get_ssh_string()}:{destination}")
|
||||||
|
|
||||||
|
|
||||||
|
def run_docker_command(lxc, container, command):
|
||||||
|
lxc.run_command(f"docker exec -it {container} {command}")
|
||||||
|
|
||||||
|
|
||||||
|
def run_docker_compose_command(lxc, command, working_directory=None):
|
||||||
|
docker_compose_exec = "docker-compose"
|
||||||
|
if not lxc.has_program(docker_compose_exec):
|
||||||
|
docker_compose_exec = "docker compose"
|
||||||
|
|
||||||
|
if working_directory is not None:
|
||||||
|
lxc.run_command(f"cd {working_directory} && {docker_compose_exec} {command}")
|
||||||
|
else:
|
||||||
|
lxc.run_command(f"{docker_compose_exec} {command}")
|
||||||
|
|
||||||
|
|
||||||
|
def download_file(lxc, url, destination):
|
||||||
|
if type(url) is list:
|
||||||
|
for u in url:
|
||||||
|
lxc.run_command(f"wget {u} -O {destination}")
|
||||||
|
else:
|
||||||
|
lxc.run_command(f"wget {url} -O {destination}")
|
@ -1,7 +1,7 @@
|
|||||||
import json
|
import json
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from src.utils import proxmox_utils, creation_utils
|
from src.utils import proxmox_utils, creation_utils, lxc_commands_utils
|
||||||
|
|
||||||
lxcs = []
|
lxcs = []
|
||||||
|
|
||||||
@ -86,7 +86,6 @@ class LXC:
|
|||||||
self.privileged = options["privileged"]
|
self.privileged = options["privileged"]
|
||||||
self.start_on_boot = options["start_on_boot"]
|
self.start_on_boot = options["start_on_boot"]
|
||||||
self.password = options["password"]
|
self.password = options["password"]
|
||||||
self.ssh = options["ssh"]
|
|
||||||
|
|
||||||
self.creation = creation
|
self.creation = creation
|
||||||
self.deploy = deploy
|
self.deploy = deploy
|
||||||
@ -283,12 +282,9 @@ class LXC:
|
|||||||
"""
|
"""
|
||||||
return self.password
|
return self.password
|
||||||
|
|
||||||
def is_ssh_enabled(self):
|
def get_ssh_string(self):
|
||||||
"""
|
# TODO: implement hostname and maybe ipv6?
|
||||||
Is SSH enabled
|
return "root@" + self.get_ipv4()
|
||||||
:return: ssh
|
|
||||||
"""
|
|
||||||
return self.ssh
|
|
||||||
|
|
||||||
def get_deploy(self):
|
def get_deploy(self):
|
||||||
"""
|
"""
|
||||||
@ -311,6 +307,13 @@ class LXC:
|
|||||||
"""
|
"""
|
||||||
return proxmox_utils.run_command_on_pve(f"pct list | awk '/running/ && /{self.lxc_id}/'") != ""
|
return proxmox_utils.run_command_on_pve(f"pct list | awk '/running/ && /{self.lxc_id}/'") != ""
|
||||||
|
|
||||||
|
def does_exist(self):
|
||||||
|
"""
|
||||||
|
Does exist
|
||||||
|
:return: does lxc exist? (boolean)
|
||||||
|
"""
|
||||||
|
return proxmox_utils.does_lxc_exist(self.lxc_id)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
"""
|
"""
|
||||||
Start LXC
|
Start LXC
|
||||||
@ -326,13 +329,17 @@ class LXC:
|
|||||||
"""
|
"""
|
||||||
Create LXC
|
Create LXC
|
||||||
"""
|
"""
|
||||||
if proxmox_utils.does_lxc_exist(self.lxc_id):
|
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(self.get_pct_command(create=False), 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(self.get_pct_command(create=True), True)
|
||||||
|
|
||||||
|
if proxmox_utils.get_config()['settings']['setAuthorizedHostsSSH']:
|
||||||
|
pve_public_key = proxmox_utils.get_ssh_public_key()
|
||||||
|
self.run_command(f"echo '{pve_public_key}' >> /root/.ssh/authorized_keys")
|
||||||
|
|
||||||
def creation(self):
|
def creation(self):
|
||||||
"""
|
"""
|
||||||
Run the creations checks and steps
|
Run the creations checks and steps
|
||||||
@ -343,21 +350,37 @@ class LXC:
|
|||||||
self.start()
|
self.start()
|
||||||
|
|
||||||
# Check if all creation conditions are met
|
# Check if all creation conditions are met
|
||||||
if not creation_utils.creation_conditions_met(self):
|
if not creation_utils.are_all_conditions_met(self):
|
||||||
logging.info(f"Not all creation conditions met for LXC {self.lxc_id}, running creation steps...")
|
logging.info(f"Not all creation conditions met for LXC {self.lxc_id}, running creation steps...")
|
||||||
|
|
||||||
# Run creation steps
|
# Run creation steps
|
||||||
creation_utils.run_creation_steps(self)
|
creation_utils.run_steps(self)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def deploy(self):
|
def deploy(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def has_program(self, program):
|
def has_program(self, program):
|
||||||
return creation_utils.has_program(self, program)
|
"""
|
||||||
|
Check if program is installed on LXC
|
||||||
|
:param program: program executable name
|
||||||
|
|
||||||
def run_command(self, command, warn_exit_status=False, only_code=False):
|
:return: boolean
|
||||||
|
"""
|
||||||
|
if type(program) == str:
|
||||||
|
return self.run_command("which " + program, only_code=True) == 0
|
||||||
|
elif type(program) == list:
|
||||||
|
return all((self.run_command("which " + p, only_code=True) == 0) for p in program)
|
||||||
|
|
||||||
|
def run_script(self, script_path):
|
||||||
|
"""
|
||||||
|
Run script on LXC filesystem using bash
|
||||||
|
|
||||||
|
:param script_path:
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
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):
|
||||||
"""
|
"""
|
||||||
Run command on LXC
|
Run command on LXC
|
||||||
:param command: command to run
|
:param command: command to run
|
||||||
@ -365,6 +388,10 @@ class LXC:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
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:
|
||||||
|
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(f"pct exec {self.lxc_id} -- {command}", warn_exit_status, only_code)
|
||||||
|
|
||||||
|
@ -58,55 +58,72 @@ def execute_tteck_script(script_url, env_variables):
|
|||||||
run_command_on_pve(f"{env_variables} && bash -c \"$(wget -qLO - {script_url}\"", True)
|
run_command_on_pve(f"{env_variables} && bash -c \"$(wget -qLO - {script_url}\"", True)
|
||||||
|
|
||||||
|
|
||||||
def run_command_on_pve(command, warn_exit_status=False, only_code=False):
|
def get_config():
|
||||||
|
config_file = os.path.join(project_path / "resources" / "config.json")
|
||||||
|
with open(config_file, "r") as file:
|
||||||
|
return json.loads(file.read())
|
||||||
|
|
||||||
|
|
||||||
|
def run_command_on_pve(command, warn_exit_status=False, only_code=False, local=False):
|
||||||
"""
|
"""
|
||||||
Run command on PVE
|
Run command on PVE
|
||||||
|
|
||||||
|
:param local: should be run locally not via ssh even with local mode off
|
||||||
:param only_code: should we only return the exit code and not the stdout
|
:param only_code: should we only return the exit code and not the stdout
|
||||||
:param warn_exit_status: should an exception be thrown if the exit status is not 0
|
:param warn_exit_status: should an exception be thrown if the exit status is not 0
|
||||||
:param command: command
|
:param command: command
|
||||||
:return: command
|
:return: command
|
||||||
"""
|
"""
|
||||||
|
|
||||||
config_file = os.path.join(project_path / "resources" / "config.json")
|
# Get config
|
||||||
with open(config_file, "r") as file:
|
config = get_config()
|
||||||
|
|
||||||
data = json.loads(file.read())
|
# Check if PVE is local or remote
|
||||||
|
if config['pve']['local'] or local:
|
||||||
|
# Run command and return output (not as bytes)
|
||||||
|
logging.debug(f"Running command on PVE (locally): \n{command}")
|
||||||
|
|
||||||
# Check if PVE is local or remote
|
command = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||||
if data['pve']['local']:
|
encoding="utf-8")
|
||||||
# Run command and return output (not as bytes)
|
|
||||||
logging.debug(f"Running command on PVE (locally): \n{command}")
|
|
||||||
|
|
||||||
command = subprocess.run(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
if command.returncode != 0 and warn_exit_status:
|
||||||
encoding="utf-8")
|
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 command.returncode != 0 and warn_exit_status:
|
if only_code:
|
||||||
logging.error(f"Error while running command on PVE: \n{command.stderr}")
|
return command.returncode
|
||||||
raise Exception(f"Error while running command on PVE: \n{command.stderr}")
|
|
||||||
|
|
||||||
if only_code:
|
return command.stdout.decode().rstrip()
|
||||||
return command.returncode
|
|
||||||
|
|
||||||
return command.stdout.decode().rstrip()
|
else:
|
||||||
|
host = config['pve']['host']
|
||||||
|
username = config['pve']['user']
|
||||||
|
port = config['pve']['port']
|
||||||
|
|
||||||
else:
|
# Run command on PVE via SSH and return output
|
||||||
host = data['pve']['host']
|
logging.debug(f"Running command on PVE (ssh): \n{command}")
|
||||||
username = data['pve']['user']
|
|
||||||
port = data['pve']['port']
|
|
||||||
|
|
||||||
# Run command on PVE via SSH and return output
|
# catch errors code
|
||||||
logging.debug(f"Running command on PVE (ssh): \n{command}")
|
command = subprocess.run(f"ssh {username}@{host} -p {port} \"{command}\"", shell=True,
|
||||||
|
stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8")
|
||||||
|
|
||||||
# catch errors code
|
if command.returncode != 0 and warn_exit_status:
|
||||||
command = subprocess.run(f"ssh {username}@{host} -p {port} \"{command}\"", shell=True,
|
logging.error(f"Error while running command on PVE: \n{command.stderr}")
|
||||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="utf-8")
|
raise Exception(f"Error while running command on PVE: \n{command.stderr}")
|
||||||
|
|
||||||
if command.returncode != 0 and warn_exit_status:
|
if only_code:
|
||||||
logging.error(f"Error while running command on PVE: \n{command.stderr}")
|
return command.returncode
|
||||||
raise Exception(f"Error while running command on PVE: \n{command.stderr}")
|
|
||||||
|
|
||||||
if only_code:
|
return command.stdout.rstrip()
|
||||||
return command.returncode
|
|
||||||
|
|
||||||
return command.stdout.rstrip()
|
|
||||||
|
def run_command_locally(command, warn_exit_status=False, only_code=False):
|
||||||
|
run_command_on_pve(command, warn_exit_status, only_code, local=True)
|
||||||
|
|
||||||
|
|
||||||
|
def get_ssh_public_key():
|
||||||
|
"""
|
||||||
|
Get SSH public key
|
||||||
|
:return: ssh public key
|
||||||
|
"""
|
||||||
|
return run_command_on_pve("cat ~/.ssh/id_rsa.pub", True)
|
||||||
|
8
src/utils/resources_utils.py
Normal file
8
src/utils/resources_utils.py
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
def get_path(lxc, path):
|
||||||
|
if path.startswith("/global/"):
|
||||||
|
# Use global folder
|
||||||
|
return "resources/scripts" + path[len("/global/"):]
|
||||||
|
else:
|
||||||
|
# Use VM/LXC folder
|
||||||
|
lxc_id = lxc.get_id()
|
||||||
|
return f"resources/lxc/{lxc_id}/{path}"
|
Loading…
Reference in New Issue
Block a user