First version that is cron-based
This commit is contained in:
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
venv
|
||||||
25
Dockerfile
Normal file
25
Dockerfile
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
FROM python:3.14.7-alpine3.24
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE=1 \
|
||||||
|
PYTHONUNBUFFERED=1
|
||||||
|
|
||||||
|
RUN addgroup -g 1600 pyusr \
|
||||||
|
&& adduser -D -u 1600 -G pyusr pyusr
|
||||||
|
|
||||||
|
RUN mkdir -p /app/pbsStartUpper/ && \
|
||||||
|
chown -R 1600:1600 /app/pbsStartUpper/
|
||||||
|
|
||||||
|
WORKDIR /app/pbsStartUpper/
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
|
||||||
|
RUN pip install --no-cache-dir -r requirements.txt
|
||||||
|
|
||||||
|
COPY --chown=pyusr:pyusr main.py .
|
||||||
|
|
||||||
|
USER pyusr
|
||||||
|
|
||||||
|
CMD ["python", "main.py"]
|
||||||
|
|
||||||
115
Roadmap
Normal file
115
Roadmap
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
|
||||||
|
# Connect to IDRAC
|
||||||
|
|
||||||
|
# Check if power is on
|
||||||
|
|
||||||
|
# chassis power status | grep fourth element
|
||||||
|
# "Chassis Power is off"
|
||||||
|
|
||||||
|
# if turn on power
|
||||||
|
|
||||||
|
# Send Power on (ipmitool chassis power on)
|
||||||
|
|
||||||
|
# else systemPower is on, continue.
|
||||||
|
|
||||||
|
|
||||||
|
# Store current date as PWR_DATE to later compare in while loop
|
||||||
|
|
||||||
|
# Send ping to HOST every 15 seconds for 10 minutes. It can take some time for the server to start
|
||||||
|
|
||||||
|
# while PWR_DATE is less than 15 minutes compared to CURRENT_DATE, ping
|
||||||
|
# if ping successfull 3 times in a row
|
||||||
|
# break
|
||||||
|
|
||||||
|
# else, exit with error,
|
||||||
|
# exit "Host didn't start after 20 minutes. Check the server"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# SSH to HOST
|
||||||
|
|
||||||
|
# check when verification was last ran
|
||||||
|
# if not in the last LAST_VERIF_D, run verification
|
||||||
|
# Verify datastore backups
|
||||||
|
|
||||||
|
# else, backups already verified enough, continue
|
||||||
|
# continue
|
||||||
|
|
||||||
|
# check if remote exists
|
||||||
|
# proxmox-backup-manager remote list
|
||||||
|
# ┌──────┬──────────────┬──────────┬───────────────────────────────────────────┬─────────┐
|
||||||
|
# │ name │ host │ userid │ fingerprint │ comment │
|
||||||
|
# ╞══════╪══════════════╪══════════╪═══════════════════════════════════════════╪═════════╡
|
||||||
|
# │ pbs2 │ pbs2.example │ sync@pam │64:d3:ff:3a:50:38:53:5a:9b:f7:50:...:ab:fe │ │
|
||||||
|
# └──────┴──────────────┴──────────┴───────────────────────────────────────────┴─────────┘
|
||||||
|
|
||||||
|
# for each remote host in REMOTE_PBS
|
||||||
|
|
||||||
|
# if remote host not in "host" collumn from "remote list" command
|
||||||
|
|
||||||
|
# exit with "Please first add a remote to PBS"
|
||||||
|
|
||||||
|
# else
|
||||||
|
# print All passed remotes found on PBS
|
||||||
|
|
||||||
|
|
||||||
|
# Get local and remote stores
|
||||||
|
|
||||||
|
|
||||||
|
# Create backup one-shot sync job
|
||||||
|
|
||||||
|
# for syncJob in jobList
|
||||||
|
|
||||||
|
# if AUTO_ADD_NAME in comment collumn of syncJob
|
||||||
|
# remove sync-job by id
|
||||||
|
|
||||||
|
# elif
|
||||||
|
# Add sync job
|
||||||
|
|
||||||
|
# else
|
||||||
|
# idk
|
||||||
|
|
||||||
|
# run one-shop sync jobs
|
||||||
|
|
||||||
|
# for syncJob in jobList
|
||||||
|
# if AUTO_ADD_NAME in syncJob.comment
|
||||||
|
# run sync-job
|
||||||
|
|
||||||
|
# if run succesfull
|
||||||
|
# continue
|
||||||
|
# else
|
||||||
|
# print the error message to stderr
|
||||||
|
|
||||||
|
# elif AUTO_ADD_NAME not in syncJob.comment
|
||||||
|
# skipping a manually addad syncJob
|
||||||
|
# else
|
||||||
|
# either no syncJobs or something broke
|
||||||
|
|
||||||
|
# store current date as PWR_OFF_DATE
|
||||||
|
|
||||||
|
# while ongoing syncJobs or ongoing verifyJobs
|
||||||
|
# if any remaining syncJobs and verifyJobs and garbageCollect finish
|
||||||
|
|
||||||
|
# if PWR_OFF_DATE is longer than 3 hours
|
||||||
|
# brake in order to send shutdown signal nontheless
|
||||||
|
# else
|
||||||
|
# sleep for 30 seconds
|
||||||
|
|
||||||
|
# send power off signal via SSH
|
||||||
|
# if chassis power status is on after 5 minutes
|
||||||
|
# send additional "chassis power off" via ipmitool
|
||||||
|
# else
|
||||||
|
# exit 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# proxmox-backup-manager sync-job create pbs2-local --remote pbs2 --remote-store local --store local --schedule 'Wed 02:30'
|
||||||
|
# proxmox-backup-manager sync-job update pbs2-local --comment 'offsite'
|
||||||
|
# proxmox-backup-manager sync-job list
|
||||||
|
# ┌────────────┬───────┬────────┬──────────────┬───────────┬─────────┐
|
||||||
|
# │ id │ store │ remote │ remote-store │ schedule │ comment │
|
||||||
|
# ╞════════════╪═══════╪════════╪══════════════╪═══════════╪═════════╡
|
||||||
|
# │ pbs2-local │ local │ pbs2 │ local │ Wed 02:30 │ offsite │
|
||||||
|
# └────────────┴───────┴────────┴──────────────┴───────────┴─────────┘
|
||||||
|
# proxmox-backup-manager sync-job remove pbs2-local
|
||||||
32
docker-compose.yaml
Normal file
32
docker-compose.yaml
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
# sudo crontab -e
|
||||||
|
# 0 2 * * * cd /path/to/docker-compose && /usr/bin/docker compose up -d >> /var/log/pbsupper-docker-compose.log 2>&1
|
||||||
|
|
||||||
|
services:
|
||||||
|
pbsupper-1:
|
||||||
|
container_name: pbsupper
|
||||||
|
user: 1600:1600
|
||||||
|
image: tea.shupogaki.org/yuruc3/pbsupper:v0
|
||||||
|
environment:
|
||||||
|
LOCAL_DATASTORE: somethingSomething
|
||||||
|
REMOTE_DATASTORE: somethingSomething
|
||||||
|
REMOTE_PBS: somethingSomething
|
||||||
|
|
||||||
|
HOST: somethingSomething
|
||||||
|
HOST_SSH_PORT: somethingSomething
|
||||||
|
HOST_USR: somethingSomething
|
||||||
|
HOST_USR_PWD: somethingSomething
|
||||||
|
|
||||||
|
HOST_USR_SSHKEY: |
|
||||||
|
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||||
|
123...
|
||||||
|
-----END OPENSSH PRIVATE KEY-----
|
||||||
|
HOST_USR_SSHKEY_PASS: somethingSomething
|
||||||
|
|
||||||
|
IDRAC: somethingSomething
|
||||||
|
IDRAC_USR: somethingSomething
|
||||||
|
IDRAC_PWD: somethingSomething
|
||||||
|
|
||||||
|
|
||||||
|
restart: unless-stopped
|
||||||
495
main.py
Normal file
495
main.py
Normal file
@@ -0,0 +1,495 @@
|
|||||||
|
import os, socket, subprocess, paramiko, io, sys, time
|
||||||
|
from typing import Final
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
|
||||||
|
IDRAC: Final[str] = os.getenv("IDRAC", None)
|
||||||
|
IDRAC_USR: Final[str] = os.getenv("IDRAC_USR", None)
|
||||||
|
IDRAC_PWD: Final[str] = os.getenv("IDRAC_PWD", None)
|
||||||
|
|
||||||
|
# LAST_VERIFY_DAY: Final[int] = os.getenv("LAST_VERIFY_DAY", 7)
|
||||||
|
# LAST_GARBAGE_DAY: Final[int] = os.getenv("LAST_GARBAGE_DAY", 7)
|
||||||
|
|
||||||
|
HOST: Final[str] = os.getenv("HOST", None)
|
||||||
|
HOST_SSH_PORT: Final[int] = os.getenv("HOST_SSH_PORT", None)
|
||||||
|
HOST_USR: Final[str] = os.getenv("HOST_USR", "root")
|
||||||
|
HOST_USR_PWD: Final[str] = os.getenv("HOST_USR_PWD", None)
|
||||||
|
HOST_USR_SSHKEY: Final[str] = os.getenv("HOST_USR_SSHKEY", None)
|
||||||
|
HOST_USR_SSHKEY_PASS: Final[str] = os.getenv("HOST_USR_SSHKEY_PASS", None)
|
||||||
|
|
||||||
|
LOCAL_DATASTORE: Final[str] = os.getenv("LOCAL_DATASTORE", None)
|
||||||
|
REMOTE_DATASTORE: Final[str] = os.getenv("HOST_UREMOTE_DATASTORESR_SSHKEY_PASS", None)
|
||||||
|
REMOTE_PBS: Final[str] = os.getenv("REMOTE_PBS", None)
|
||||||
|
SYNC_DIR: Final[str] = os.getenv("SYNC_DIR", "push")
|
||||||
|
PBS_RATE_OUT: Final[str] = os.getenv("PBS_RATE_OUT", "")
|
||||||
|
PBS_RATE_IN: Final[str] = os.getenv("PBS_RATE_IN", "")
|
||||||
|
PBS_TASK_LIMIT: Final[int] = os.getenv("PBS_TASK_LIMIT", 50)
|
||||||
|
PBS_MAX_RUNTIME_MIN: Final[int] = os.getenv("PBS_MAX_RUNTIME_MIN", 180)
|
||||||
|
PBS_MAX_SHUT_MIN: Final[int] = os.getenv("PBS_MAX_SHUT_MIN", 10)
|
||||||
|
AUTO_ADD_NAME: Final[str] = os.getenv("AUTO_ADD_NAME", "autoBackupScript_one-shot")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def exceptionator(exception, message):
|
||||||
|
"""Return an exception that can be custom-used"""
|
||||||
|
return exception(message)
|
||||||
|
|
||||||
|
|
||||||
|
def load_private_key(key_data: str, passphrase: str | None = None):
|
||||||
|
"""Take in SSH key, determine type and return paramiko-compatible element"""
|
||||||
|
key_classes = [
|
||||||
|
paramiko.Ed25519Key,
|
||||||
|
paramiko.ECDSAKey,
|
||||||
|
paramiko.RSAKey,
|
||||||
|
# paramiko.DSSKey,
|
||||||
|
]
|
||||||
|
|
||||||
|
for key_class in key_classes:
|
||||||
|
try:
|
||||||
|
return key_class.from_private_key(
|
||||||
|
io.StringIO(key_data),
|
||||||
|
password=passphrase or None,
|
||||||
|
)
|
||||||
|
except (paramiko.SSHException, ValueError):
|
||||||
|
pass
|
||||||
|
|
||||||
|
raise ValueError("Unsupported or invalid SSH private key")
|
||||||
|
|
||||||
|
|
||||||
|
def getCurrentTasks(allTasks: bool = False, limitOfTasks: int =50) -> dict:
|
||||||
|
"""Get what tasks are running/ran on PBS
|
||||||
|
|
||||||
|
Keyword arguments:
|
||||||
|
allTasks -- if tasks that are finished should be included. (default False)
|
||||||
|
limitOfTasks -- how many tasks to ask PBS for (default 50)
|
||||||
|
"""
|
||||||
|
|
||||||
|
(stdin, stdout, stderr) = ssh.exec_command(f'proxmox-backup-manager task list --limit {limitOfTasks} --all {allTasks}')
|
||||||
|
|
||||||
|
taskList = stdout.read().decode()
|
||||||
|
|
||||||
|
outTaskList = []
|
||||||
|
for line in taskList.splitlines():
|
||||||
|
line = line.strip()
|
||||||
|
|
||||||
|
# Only process actual table rows
|
||||||
|
if not line.startswith("│"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
columns = [col.strip() for col in line.strip("│").split("│")]
|
||||||
|
|
||||||
|
# Skip the header row
|
||||||
|
if columns[0] == "starttime":
|
||||||
|
continue
|
||||||
|
if len(columns) >= 2:
|
||||||
|
outTaskList.append(columns[2].split(":")[6])
|
||||||
|
# exit()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# print(outTaskList)
|
||||||
|
|
||||||
|
outTaskDict = {}
|
||||||
|
|
||||||
|
for task in outTaskList:
|
||||||
|
|
||||||
|
match task:
|
||||||
|
case "garbage_collection":
|
||||||
|
outTaskDict["garbage_collection"] = outTaskDict.get("garbage_collection", 0) + 1
|
||||||
|
case "verificationjob":
|
||||||
|
outTaskDict["verificationjob"] = outTaskDict.get("verificationjob", 0) + 1
|
||||||
|
case "syncjob":
|
||||||
|
outTaskDict["syncjob"] = outTaskDict.get("syncjob", 0) + 1
|
||||||
|
case "aptupdate":
|
||||||
|
outTaskDict["aptupdate"] = outTaskDict.get("aptupdate", 0) + 1
|
||||||
|
case "reader":
|
||||||
|
outTaskDict["reader"] = outTaskDict.get("reader", 0) + 1
|
||||||
|
case "logrotate":
|
||||||
|
outTaskDict["logrotate"] = outTaskDict.get("logrotate", 0) + 1
|
||||||
|
case "termproxy":
|
||||||
|
outTaskDict["termproxy"] = outTaskDict.get("termproxy", 0) + 1
|
||||||
|
case _:
|
||||||
|
outTaskDict["otherjob"] = outTaskDict.get("otherjob", 0) + 1
|
||||||
|
|
||||||
|
|
||||||
|
return outTaskDict
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if len(AUTO_ADD_NAME) > 32:
|
||||||
|
raise exceptionator(ValueError, "Maxmimum length of AUTO_ADD_NAME is 32")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# dt = datetime.now.timestamp()
|
||||||
|
|
||||||
|
# epoch_time = dt.timestamp()
|
||||||
|
# print(epoch_time)
|
||||||
|
|
||||||
|
# Check if power is on
|
||||||
|
# PWR_STATE = subprocess.run(["ipmitool", "-I", "lanplus", "-H", IDRAC, "-U", IDRAC_USR, "-P", IDRAC_PWD, "chassis", "power", "status"], capture_output=True)
|
||||||
|
|
||||||
|
try:
|
||||||
|
# power on if needed
|
||||||
|
if "off" in str(PWR_STATE.stdout.decode()[-4:]):
|
||||||
|
subprocess.run(["ipmitool", "-I", "lanplus", "-H", IDRAC, "-U", IDRAC_USR, "-P", IDRAC_PWD, "chassis", "power", "on"]) # , capture_output=True
|
||||||
|
except exception as e:
|
||||||
|
print("Most likely wrong password, username or hostname has been passed for idrac.\nExiting\n")
|
||||||
|
sys.exit(1)
|
||||||
|
# else:
|
||||||
|
# continue
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
PWR_DATE = datetime.now().timestamp()
|
||||||
|
|
||||||
|
pinging = subprocess.run(["ping", "-c", "3", "-W", "5", HOST], capture_output=True).returncode
|
||||||
|
|
||||||
|
if pinging:
|
||||||
|
print("not reachable")
|
||||||
|
|
||||||
|
while datetime.now().timestamp() - PWR_DATE <= 1200:
|
||||||
|
pinging = subprocess.run(["ping", "-c", "3", "-W", "5", HOST], capture_output=True).returncode
|
||||||
|
|
||||||
|
if not pinging:
|
||||||
|
print("reachable")
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise exceptionator(TimeoutError, "Host didn't start after 20 minutes.\nCheck the server.")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print("reachable")
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Create object of SSHClient and
|
||||||
|
# connecting to SSH
|
||||||
|
ssh = paramiko.SSHClient()
|
||||||
|
|
||||||
|
# Adding new host key to the local
|
||||||
|
# HostKeys object(in case of missing)
|
||||||
|
# AutoAddPolicy for missing host key to be set before connection setup.
|
||||||
|
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
|
|
||||||
|
|
||||||
|
if not HOST_USR_SSHKEY:
|
||||||
|
|
||||||
|
ssh.connect(hostname=HOST, port=HOST_SSH_PORT, username=HOST_USR, password=HOST_USR_PWD, timeout=3, )
|
||||||
|
|
||||||
|
else:
|
||||||
|
key = load_private_key(
|
||||||
|
HOST_USR_SSHKEY,
|
||||||
|
HOST_USR_SSHKEY_PASS
|
||||||
|
)
|
||||||
|
|
||||||
|
ssh.connect(
|
||||||
|
hostname=HOST,
|
||||||
|
port=HOST_SSH_PORT,
|
||||||
|
username=HOST_USR,
|
||||||
|
pkey=key,
|
||||||
|
timeout=3,
|
||||||
|
allow_agent=False,
|
||||||
|
look_for_keys=False,
|
||||||
|
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Execute command on SSH terminal
|
||||||
|
# using exec_command
|
||||||
|
# (stdin, stdout, stderr) = ssh.exec_command('hostname')
|
||||||
|
|
||||||
|
# # redirecting all the output in cmd_output
|
||||||
|
# # variable
|
||||||
|
# cmd_output = stdout.read().decode()
|
||||||
|
|
||||||
|
# print(cmd_output)
|
||||||
|
|
||||||
|
(stdin, stdout, stderr) = ssh.exec_command('proxmox-backup-manager remote list')
|
||||||
|
|
||||||
|
remoteList = stdout.read().decode()
|
||||||
|
|
||||||
|
remoteDict = {}
|
||||||
|
|
||||||
|
for line in remoteList.splitlines():
|
||||||
|
line = line.strip()
|
||||||
|
|
||||||
|
# Only process actual table rows
|
||||||
|
if not line.startswith("│"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
columns = [col.strip() for col in line.strip("│").split("│")]
|
||||||
|
|
||||||
|
# Skip the header row
|
||||||
|
if columns[0] == "name":
|
||||||
|
continue
|
||||||
|
|
||||||
|
if len(columns) >= 2:
|
||||||
|
name = columns[0]
|
||||||
|
host = columns[1]
|
||||||
|
|
||||||
|
remoteDict[host] = name
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if REMOTE_PBS in remoteDict:
|
||||||
|
print(f"Found {REMOTE_PBS} as {remoteDict[REMOTE_PBS]}")
|
||||||
|
else:
|
||||||
|
print(f"\n!!!\nRemote {REMOTE_PBS} not found.\nAdd remote {REMOTE_PBS} manually.\n!!!\n", file=sys.stderr)
|
||||||
|
REMOTE_PBS.remove(REMOTE_PBS)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
(stdin, stdout, stderr) = ssh.exec_command('proxmox-backup-manager sync-job list --sync-direction all')
|
||||||
|
|
||||||
|
syncJobList = stdout.read().decode()
|
||||||
|
|
||||||
|
|
||||||
|
for line in syncJobList.splitlines():
|
||||||
|
line = line.strip()
|
||||||
|
|
||||||
|
# Only process actual table rows
|
||||||
|
if not line.startswith("│"):
|
||||||
|
continue
|
||||||
|
|
||||||
|
columns = [col.strip() for col in line.strip("│").split("│")]
|
||||||
|
|
||||||
|
# Skip the header row
|
||||||
|
if columns[0] == "id":
|
||||||
|
continue
|
||||||
|
if len(columns) >= 2:
|
||||||
|
print("Sync job already on Proxmox Backup Server.\nSkipping sync job creation.")
|
||||||
|
# print(columns)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
|
||||||
|
match SYNC_DIR:
|
||||||
|
case "push":
|
||||||
|
if PBS_RATE_OUT:
|
||||||
|
(stdin, stdout, stderr) = ssh.exec_command(f"proxmox-backup-manager sync-job create {AUTO_ADD_NAME} --remote {remoteDict[REMOTE_PBS]} --remote-store {REMOTE_DATASTORE} --store {LOCAL_DATASTORE} --sync-direction push --rate-out {PBS_RATE_OUT} --comment 'automatic startupper script'")
|
||||||
|
else:
|
||||||
|
(stdin, stdout, stderr) = ssh.exec_command(f"proxmox-backup-manager sync-job create {AUTO_ADD_NAME} --remote {remoteDict[REMOTE_PBS]} --remote-store {REMOTE_DATASTORE} --store {LOCAL_DATASTORE} --sync-direction push --comment 'automatic startupper script'")
|
||||||
|
case "pull":
|
||||||
|
if PBS_RATE_IN:
|
||||||
|
(stdin, stdout, stderr) = ssh.exec_command(f"proxmox-backup-manager sync-job create {AUTO_ADD_NAME} --remote {remoteDict[REMOTE_PBS]} --remote-store {REMOTE_DATASTORE} --store {LOCAL_DATASTORE} --sync-direction pull --rate-in {PBS_RATE_IN} --comment 'automatic startupper script'")
|
||||||
|
else:
|
||||||
|
(stdin, stdout, stderr) = ssh.exec_command(f"proxmox-backup-manager sync-job create {AUTO_ADD_NAME} --remote {remoteDict[REMOTE_PBS]} --remote-store {REMOTE_DATASTORE} --store {LOCAL_DATASTORE} --sync-direction pull --comment 'automatic startupper script'")
|
||||||
|
case _:
|
||||||
|
raise exceptionator(SyncDirectionError, f"No such sync direction as {SYNC_DIR}.\n Either use 'push' or 'pull'\n")
|
||||||
|
|
||||||
|
|
||||||
|
# print(stdout.read().decode())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
(stdin, stdout, stderr) = ssh.exec_command(f"proxmox-backup-manager sync-job run {AUTO_ADD_NAME}")
|
||||||
|
# ssh.exec_command(f"proxmox-backup-manager sync-job run {AUTO_ADD_NAME}")
|
||||||
|
# print("here it runs the sync-job")
|
||||||
|
# print(stdout.read().decode())
|
||||||
|
# print(stderr.read().decode())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Maybe add some checks here if the backup was properly scheduled
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# Get tasks
|
||||||
|
# print(getCurrentTasks(limitOfTasks=100))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# check ongoing tasks
|
||||||
|
SYNC_JOB_DATE = datetime.now().timestamp()
|
||||||
|
|
||||||
|
currenttasks = getCurrentTasks(limitOfTasks=PBS_TASK_LIMIT)
|
||||||
|
|
||||||
|
while currenttasks:
|
||||||
|
|
||||||
|
currenttasks = getCurrentTasks(limitOfTasks=PBS_TASK_LIMIT)
|
||||||
|
|
||||||
|
print("Waiting 1 minute before checking tasks again")
|
||||||
|
time.sleep(60)
|
||||||
|
|
||||||
|
if SYNC_JOB_DATE - datetime.now().timestamp() >= (PBS_MAX_RUNTIME_MIN * 60):
|
||||||
|
print(SYNC_JOB_DATE - datetime.now().timestamp())
|
||||||
|
# Forcefully skip if these tasks are running. reader task is, I think, PVE backup
|
||||||
|
# Also otherjob is something else and it is better to wait if there is one otherjob
|
||||||
|
if (
|
||||||
|
currenttasks.get("aptupdate", 0)
|
||||||
|
or currenttasks.get("reader", 0)
|
||||||
|
or currenttasks.get("otherjob", 0)
|
||||||
|
):
|
||||||
|
continue
|
||||||
|
# No need to do anything here. It's only to check if these keys exist
|
||||||
|
...
|
||||||
|
break
|
||||||
|
|
||||||
|
|
||||||
|
(stdin, stdout, stderr) = ssh.exec_command(f"sudo shutdown")
|
||||||
|
print("Shuting down PBS")
|
||||||
|
# print("here it runs a shutdown now")
|
||||||
|
print(stdout.read().decode())
|
||||||
|
print(stderr.read().decode(), file=sys.stderr)
|
||||||
|
|
||||||
|
ssh.close()
|
||||||
|
# wait for PBS to safely shutdown
|
||||||
|
time.sleep(PBS_MAX_SHUT_MIN * 60)
|
||||||
|
|
||||||
|
|
||||||
|
if subprocess.run(["ping", "-c", "3", "-W", "5", HOST], capture_output=True).returncode:
|
||||||
|
print("PBS is powered off")
|
||||||
|
|
||||||
|
else:
|
||||||
|
subprocess.run(["ipmitool", "-I", "lanplus", "-H", IDRAC, "-U", IDRAC_USR, "-P", IDRAC_PWD, "chassis", "power", "off"])
|
||||||
|
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# ▒▒▒▓▓▓▒▒▒▒▓▒▒▒▒▓▓▒▒▓▓▒ ▒ ▒ ▒▒░▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒ ░░░ ████████
|
||||||
|
# ▒▒▒▒▓▓▒▓▒▒▓▒▓▓▒▓▒▒▒▓▓ ▒ ▒░ ▒▒▒▒░▒▒▒▒ ░ ░ ██████
|
||||||
|
# ▒▒▓░▒▓▓▓▓▒▒▓▓▒▒▓▓▒▓▒ ▒░ ▒░ ▒▒ ▒▒ ░░ ████
|
||||||
|
# ▓ ▒▒▒▒▒▓▓▒▓▒▓▓▒░▒ ▒ ░░ ██
|
||||||
|
# ▒▒▓▓▓▒░▒▒▓▒▒▒ ░░ █
|
||||||
|
# ░ ▓▒▓ ▒ ░░
|
||||||
|
# ░
|
||||||
|
# ▒ ▒▓ ░
|
||||||
|
# ░ ▓▒▒ ░▓▓▓▓▓ ▒▒
|
||||||
|
# ▒▓▓▓░▓▓░▓▓▓▓▓▓
|
||||||
|
# ▓▓▓▓▓▓░▓▒░░▒▒ ▒▒▓▓░░░▓▓▓▓▓░▓▓▓▓
|
||||||
|
# ▓▓▓░▒▓░▓▓▒▒▒ ▒▓▓▓▓░▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
# ░░░░░ ▓▓▓▓▓░▓▒▒▒▒▒▓▓▓▓▒ ▓▓▓▓▓▓░░░▒▓▓▓▓
|
||||||
|
# ░░░░░░░░░░░░░░ ▓▓▓▓▓░▒▒ ▒▒▓▓▓▓▓▓▓▓░░▓▒▓▓▓▓▓▓▓▓▓
|
||||||
|
# █ ░░░░░░░░░░░░░░░░ ▓▓▓▓▓▒▒ ▒▒▒░▒▓ ▓▓▓▓▓▓▓▓░▓▓▓▓▓▓▓▓▓
|
||||||
|
# ███ ░░░░░░░░░░░░░░░░░ ▒░▒▒ ▒▓▓▓▓▒▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░
|
||||||
|
# ████ ░░░░░░░░░░▓▓▓▓▓▒░░▒▓▓▓▓░▓░▓▓▓▓▓▓▓▓░▒▒░░▓▓▓▓▓
|
||||||
|
# ██████ ░▓▓▓▓▓▓▓▓▒▒░▓▓▓▓ ▓▓░▓▓▓▓▒░░▓▒▓▓▓▓▓▓▓░▒
|
||||||
|
# ████████ ▓▓▓▓▒▓▓▓▓▓▓▓▒▒░▓▒░▒ ▓▓▒░░▒▓▓▓▓▓░▓▓▓▓▓▓▒░▒ ▒ ▓░▓▓▒
|
||||||
|
# ███████████ ▓▓▓▒▓▓▓▓▓▓▓░▒▒▒ ▒▒ ▓▓▓░▓▓▓▓▓▓▓▓▒▓▓▓▓▓▒▒ ▒▓▓░▓▓ ▓▓▓▓▓▓▒▓▓▓▓▓░
|
||||||
|
# ████████████ ▓▒ ▒▒▒▒▒ ▓▓▓▓▒▓▓▓▓▓▓▓░▓▒▓▓▒░▓░▓▓▓▓▓▓▓▓▓▓░▓▓▓▓▒░░░▓▓▓▓░
|
||||||
|
# ████████████▓ ▓▒ ▒ ▒ ▓▓▓▓░▓▓▓▓▓▓▓▓░▒▓▓▓▓▓░▒▓▓▓░░▒▓ ▒░▒▓▓▓▓▓▓░▓▓▓▓▓
|
||||||
|
# ███████████ ▒▒▓▓▓░▓▓▓░▒▓▓▒▓▓▓▓░▒ ▒▒▓▓▓▓▓▒▒▒░▒▓▓▓▓▓▓▒▓▓▓▓
|
||||||
|
# ████████▓ ▓▓▓▓▓▓▓▓░ ▒▒▓▓▒▓▓░▓▓▓▓▓▓▓░▓▓▓▓
|
||||||
|
# ██████ ▓▓▓▓▓▓▓▓▓▒░░
|
||||||
|
# ████ ▓░ ░▓░░░▓▓▓░▓▓▓
|
||||||
|
# ██ ░░░░░░░░░░░░░░░░░ ░▓▓▓▓▓▓▓▒▓▓▓
|
||||||
|
# ▓ ░░░░░ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ░░░░░░░░░ ▓▓▓▓▓▓▓▓▓░▓▓
|
||||||
|
# ░░ ░ ▓▒▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ░ ▓▓░▓▓▓▒░░▒░▓▓
|
||||||
|
# ░░░ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒░ ░░ ▓▒ ▓▓▓▓▓▓▓▓▓▒▓
|
||||||
|
# ▓████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ░░░ ░░░ ▒▒▒▒▒▒▒▒ ▓▓▓▓▓▓ ▓
|
||||||
|
# ███████ ▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓░ ░░░░░ ░░░░░ ░ ▒▒▒▒▒▒▒▒▒▒▒▒▓ ▒▒▒▒▒▒▓
|
||||||
|
# ███████ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▓▒▓▒▒▒▒▒▒▒ ░
|
||||||
|
# ███████ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ ▓▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▒▒▒▒▒▒▓ ░▒▒▒▒▒▒▒
|
||||||
|
# ██████ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▓▒▒▒▓▓▓▓▓▓▓▓▓▒▒▒▓▒░░ ▒▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▓▒▒▒▓▒▒▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▓ ░▓▒▒▒▓▒▒
|
||||||
|
# ██████ ▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓ █▒░▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▒▒▒▒▒▒▓▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▓ ▒ ▒▒▓▒▒
|
||||||
|
# ██████ ▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ██▒▓▓▓▓▒▓▓██▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▒▓▓▓░▓▓▓▓▓▒░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒░▒ ░ ▒▓▓▒
|
||||||
|
# █████ ▒▒▒▒▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓████ ▓▓▓▓▓▓▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓ ▒▓▓▓▓
|
||||||
|
# █████ ▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░▓▓▓▓▓▓▓▓▓▓█████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓ ▓▓▓
|
||||||
|
# █████ ▓▓▓▓▓▓▒▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓██████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓█▓▓▓▓▓▓▓▓▓▓█▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓ ▓▓▓
|
||||||
|
# █████ ▓▓▓▓▓▓▒▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓█▓▓▓▓▓▓▓██████ ▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▒▓▓▓▓▓▓█▓▓▒▓▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓▓▓▒▓ ▓▓▓
|
||||||
|
# ████▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓███████ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓▓▓▓▓ ▒▓▓▓▓
|
||||||
|
# ████▓▓▓▓▓▓▓▓▒▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░███████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓
|
||||||
|
# █████▓▓▓▓▒▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓ ▒▓▓▓▓▓▓▓▓ ████████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▒░▓▓▓▓▓▓▒ ▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓
|
||||||
|
# █████▓▓▓▓▒▓▓▒▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓ ▒ ▓▓▓▓▓▓▓▒█████████▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▓▒ ▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓ ░ ▓
|
||||||
|
# █████▓▓▓▓▒▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▒▓▓▓▒█▓ ▓▓▓▒▓▓▓▓▓█▓▓▓█▓██ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▒██▓▓▓▓▓██▒▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓ ▒▓
|
||||||
|
# █████▓▓▓▓▒▓▓▒▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▓ ▓ ▓ ▒▓█████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓████▒▓▓▓████ ▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▒▓
|
||||||
|
# █████ ▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓░░ ▓ ▒▒▓▒███▓ ░ ███ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▒▓▓▓▓ ████░▓▓██▓█▓ ▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓ ░▓
|
||||||
|
# ██ ██ ▓▓▓▓▒▓▓▓▓▓▓▓▒▓▓▓▓▓▓ ▒▒ ░▓█▓▓▓████▒▓▓▓ ▒▓▓▓▓▓▒ █ █████▓▓▓▓▓▓▓▓▓▓▓▓▓▓███▓▓▓▓▓▓▓█▓ ▓▓▓▓█▓█▓▓ ▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▒▓
|
||||||
|
# ▓ ███▓▓▓ ░▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▓▓▓██░█████▓▓▓▓▓▓▒▒▒▒▒▓▓▓▓▓▓█████▓▓ ▓▓▓▓▓▓▓▓▓██ █▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓ ▓ ▓
|
||||||
|
# █▒ ██▓▓ ██ ▓▒▓▓▓▓▓▓░▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓████▓█▒▒▓▓ ▓▓ █▒█ ▒▓▓▒███▒▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓ ▒▓▓
|
||||||
|
# ███ ██ ▓░▓██▓▒▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓██████▓█▓█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓ ▓ ░▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓ ▓ ▒█
|
||||||
|
# ███ ███▓▓▓██▒▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ██████▓▓ ░░░▓▓▓▓▒▓▒▓▓▓▓▓▓▒▓ ▓ ▒ ▒
|
||||||
|
# ███████ ▓████▓▒▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓█▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓ ▓ ░ ▒
|
||||||
|
# ██ ████▒█▓██▓▒▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓█▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▒▓▓▓▓▓▓▒▓ ▓▓ ▒ ▒
|
||||||
|
# ██ ██████▒░▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓ ▓▓▓▓▓▓▒ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓██▓ ▒
|
||||||
|
# ██▓▓ ████████▓▓▓▓▒▓▓▓▓▒▓▓▓▓▓▓▒▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓█▒
|
||||||
|
# ██ ▒██████▒▓█░▓▓▓▓▒▒▒▒▒▓▓▓▓▓▓▓▓▒▒ ░ ░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▒
|
||||||
|
# ████░█▒▒███████ ▓▓▓ ▒▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▒▓▓██▓██▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓
|
||||||
|
# ██▒▒▒▒▒███████ ▓▒▓▓ ▓▓▓▓▓▓█▓▓▓▓▓▓▓ ░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▓▓▒▒▒ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▒▓▓▓▓▓▓▓▓▒▓▓▓▓▓ ▒
|
||||||
|
# ████░░▓█████ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓█████▓████████░▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒█▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▒▓▓▓▓▓ ▓ ▒ ▓▓
|
||||||
|
# ███████████ ▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▒ ██████████████▓▓▓▓▓▓▓▓▓▓▓▓▓▓░███▓▓▓▓▓▓▓▓▓▓▓▓▓ ░ ░▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▒ ▒▓▓
|
||||||
|
# ██████████ ▓▒▓▓▓ ▓▓▓▓▓▓▓▓▓ ▓▓▓░░░▒▒▒▒█████████████▓▓▓▓▓▓▓▓▓▓▓▓▓█████████▓▓▓▓▓▓ ░░░ ░▓▓▓▓▓▓▓▒▒▓▓▓▓ ▓█▒▓░ ▒ ▓▓▒▒░▓▓
|
||||||
|
# ███████▒▓▓█ ▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ░░▒▒▒▒▒ ███████████▓▓▓▓▓▓▓▓▓▒██████████████ ░▒ ░░░░ ▓▓▓▓▓▓▓▓▒▓▓▓ ▓ ░ ▒▒▓▓▓▓▓▒▒ ▓ █
|
||||||
|
# ███▓▒ ░▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓░░ ▒▒▒▒█▒▒ ████████████████████████████ ▒▒▒▒▒▒ ░░░░▓▓ ▓▓▓▓▓▓▓▓▓ ▒▓▓▓▓▓▒▒▓ ▓ █
|
||||||
|
# ▒ ▓░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▓▒▒▒▒▒ ████████████████████▒▒▒▒█ ▒▒▒▒▒ █ ▓▓ ▒▒▓▓▓▓▓▓▓ ▒ ▒ ▓▓▓▒▒▒▒▓ █
|
||||||
|
# ████████████▓ ██ ▓▓▓▓▓▓ ▒▒▒▒▒▒ ▒▓ ▒▒ ▒▒ ██████████ ▒▒▒ ▒▒▒▒▒▒▒▒▒▒▒▒▓▓ ▒▒▒▒▓▓▓▓▓▒░▒▓ ▓░▓█ ▒░▓▓▓▒▒▓▓▓░▓ █
|
||||||
|
# ▒ ▒▓▓▓▒ ███████████████████ ▒▓▓▓▓▓▓▓▒▒▒ ▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒░ ░░░░░░▒ ▒▓▒▒▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▓▒▒░▒░▒▓▒▓░ ▓ ▓▓▓▓▒▓▓▓▓ ▓▓█
|
||||||
|
# █▓ ▒▓█▓▓███ ██████▓█████░░▓█████ ░░ ▒▓▓▓▓▓▓▒ ▒▒▒▒▒▒▒▒ ▒ ▒▒▒▒▒▒░░░░░░░░░▒▒░▒▒▒▒▒▒▒▒▒ ▒▒▒▒▒▒▒▒▒ ▒░▒░▒ ░ ▓ ▒▒▓▒▓▒▓▓▓▓▓ █▓█
|
||||||
|
# ██▓▒██░▓██ █████▒▒░▒░██░░░▒█████ ▒▒▒▒▒ ▒▓▓▓▓▓ ▒▒░▒▒ ▒▒▒▒▒▒▒ ▒▒░░░░░░░▒ ▒ ▒▒▒▒░░░ ▒ ▒▒▒▒▒▒▓▓▓▓░░░░░▒ ▓▒▒▓▓▓▒▓▓ █▓░
|
||||||
|
# ██░▒█▓ ▒ ██████░░░░▒▒░░░▓█████ ▓▓▓▓▒ ▒ ░░░░░░▒ ▒▒▒▒▒▒░░▒▒ ░░░░░░░▒▒ ░▒▒▒▒▒░░ ▒▒▒▒▓▓▓▓▓▓░░░ ▒ ▓▓▓▓▓▓▒░▓ ▓▓
|
||||||
|
# ▓▓ ░ ███████░░░░░░░░██████ ▓▓▓▓▓▓ ░░░░░░░▒ ░░░░░░░░ ▒ ░░░▒▒▒▒░▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓▓▓▓▓▓▓▓▓ ▒ ▒▓▓▓▓▓▓▒▓▓ ▓
|
||||||
|
# ░ ████▒░▒█▒░░░░░▒█░▒▒██ ▓▓▓▓▓▓▓ ░░░░░░░ ░░░░░░░░░░ ▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ░ █ █▒▒▒▒▒▓▓▒▓▓▓▓▓▓▒▓▓ ▓
|
||||||
|
# ██░░░░▒███░░░░██▒▓██ ▓▓▓▓▓▓▓▓▓ ░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ░ █▒▒ ▓▓▓▒▓▓▓▓▓▓▓▓▓▓ ▓
|
||||||
|
# ███▒▒█████████████▓ ▓▓▓▓▓▓▓▓▓▓ ░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ░ ▓ █▒▒▓▒▓▓▒▓▓▓▓▓▓▓▓▓▓ ▓
|
||||||
|
# ████████████████ ▒▓▓▓▓▓▓▓▓▓▓▓ ░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▒ █ ▒▒▒▓▒▓▒▓▓▓▓▓▓▓▓▓▓▓ ▓
|
||||||
|
# ███████████ ▓▓▓▓▓▓▓▓▓▓▓▓▓ ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓ ▓ ▒▒ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓
|
||||||
|
# █▓ ░ ▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓ ░ ▒▒▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▓▓
|
||||||
|
# ▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ▓▓ ▓ ▓▓ ▒▒▓▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
# █▒▒▒▒▒ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ░ ▒▓ ▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
# ███████ ▓██▓▒▒▒ ▓▓▓ ▓▓▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ░░░░ ▒▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
# ███████▓ ▒███▒▒▒▒ ▓▓▓░▓▓▓▓▓ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓ ░░░░░ ▒▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
# ███████████▓ ▒▓▓▓▓▓▓▓▓▓░ ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒ ▓▓▓▓▓▓▓▓▓▓ ░░░ ░▓▓▓▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓
|
||||||
|
# ████████▒ ▓▒▓▓▓▓▓▓▓▓▓▓ ░ ▓▓▓▓▓▓▓▓▓▓▒ ▒▓▒▒ ░░ ▓▓▓▒▒▒▒▓▓▒▒▓▓▓▓▓▓▒▓
|
||||||
|
# █████▒ ▒░ ▒░▓▓▓▓▓▒▓▓▓▓ ░░ ▒▓▓▓▓▓▓ ▓▓▓▓▒▓▒▓▓▓▒▒▓▒▓▓▓▓
|
||||||
|
# ██▓ ▒▒▒▒░ ▓▓▓▓▓▓▓▓▓▓ ░ ░▓▓▓ ░ ▓ ▓ ▒▓▓▓▓▒▓▓▓▓▓▓▓
|
||||||
|
# ▒ ▒▒▒▒▒▒░ ▓▒ ▓▓▓▓▓▓▓▓▒▓▒ ░░░░░ ▓▓ ▓ ▒░ ▒▓▓▓▓▓▓▓▓
|
||||||
|
# ░▒▒▒▒▒▒░ ▓▓ ▓▓▓▓▓▓▓▓▓▒ ░░░ ░ ▒▒▒▒▒ ▒▒ ▒▒▒▒▒▒▓▓▓▓▒
|
||||||
|
# ▒▒▒▓█▒▒▒░ ▓ ▓▒▓▓▓▓▓▓▓▓▓▒▓░░ ▒ ▒▓ ▓ ▒▒▒▒▒░▒▓▓▓▓▒
|
||||||
|
# ▒▓██▒▒▒▒ ▓▓▓▓▓▓▓▓▓▒▓▓ ▒▒▒▒▒▒▒▒▒▓▓▓▓▓ ▓▓
|
||||||
|
# ██▓▒▒▒▒ ░▒▓▓▓▓▓▓ ▓▓▓▓▓▒▒▒ ▓▒
|
||||||
|
# █▓▒▒▒▒░ ▓▓▓▓▓ ▓▓▓▓▓▒▒▒ ▒▓▓▒
|
||||||
|
# ▓▒▒▒▒░ ▓▓ ▒▒▒▒▒▒▒░ ▒▒▓
|
||||||
|
# ▒▒▒▒▒ ░▓▓
|
||||||
|
# ▒▒▒▒▒ ▓▓
|
||||||
|
# ▒▒▒▒▒ ▓▓
|
||||||
|
# ▒▒▒▒▒ ▓▓
|
||||||
|
# ▒▒▒▒▒ ▒▓
|
||||||
|
# ▒▒▒▒▒▒ ▓▓
|
||||||
|
# ▒▒▒▒▒▒ ▒ ▓▓
|
||||||
|
# ▒▒▒▒▒▒ ▒▓▓
|
||||||
|
# ▒▒▒▒▒▒░ ▒ ▓▓▓
|
||||||
|
# ▒▒▒▒▒▒▒ ▒▓▓▓
|
||||||
|
# ▓▒▒▒▒▒▓▓ ░▓▓▓▒
|
||||||
|
# ▓▒▒▒▒▓▓▓▒ ▒▓▓▒▒▓
|
||||||
112
manifest.yaml
Normal file
112
manifest.yaml
Normal file
@@ -0,0 +1,112 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: Secret
|
||||||
|
metadata:
|
||||||
|
name: pbsupper-deployment-1-secretmap
|
||||||
|
namespace: CHANGE_ME
|
||||||
|
labels:
|
||||||
|
server: Server-1
|
||||||
|
idrac: v7
|
||||||
|
type: Opaque
|
||||||
|
data:
|
||||||
|
IDRAC_PWD: c29tZXRoaW5nQnV0SW5CYXNlNjQ=
|
||||||
|
HOST_USR_PWD: c29tZXRoaW5nQnV0SW5CYXNlNjQ=
|
||||||
|
HOST_USR_SSHKEY_PASS: c29tZXRoaW5nQnV0SW5CYXNlNjQ=
|
||||||
|
|
||||||
|
# Must be base64 of the ENTIRE private key, as one base64 value.
|
||||||
|
# base64 -w 0 id_ed25519
|
||||||
|
HOST_USR_SSHKEY: c29tZXRoaW5nQnV0SW5CYXNlNjQ=
|
||||||
|
|
||||||
|
|
||||||
|
# Alternatively you can also use this option instead of PRIVATE_KEY: 123...
|
||||||
|
|
||||||
|
stringData:
|
||||||
|
PRIVATE_KEY: |
|
||||||
|
-----BEGIN OPENSSH PRIVATE KEY-----
|
||||||
|
123...
|
||||||
|
-----END OPENSSH PRIVATE KEY-----
|
||||||
|
---
|
||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: pbsupper-deployment-1-configmap
|
||||||
|
namespace: CHANGE_ME
|
||||||
|
labels:
|
||||||
|
server: Server-1
|
||||||
|
idrac: v7
|
||||||
|
data:
|
||||||
|
IDRAC: somethingSomething
|
||||||
|
IDRAC_USR: somethingSomething
|
||||||
|
HOST: somethingSomething
|
||||||
|
HOST_SSH_PORT: somethingSomething
|
||||||
|
HOST_USR: somethingSomething
|
||||||
|
LOCAL_DATASTORE: somethingSomething
|
||||||
|
REMOTE_DATASTORE: somethingSomething
|
||||||
|
REMOTE_PBS: somethingSomething
|
||||||
|
SYNC_DIR: somethingSomething
|
||||||
|
PBS_RATE_OUT: somethingSomething
|
||||||
|
PBS_RATE_IN: somethingSomething
|
||||||
|
PBS_TASK_LIMIT: somethingSomething
|
||||||
|
PBS_MAX_RUNTIME_MIN: somethingSomething
|
||||||
|
PBS_MAX_SHUT_MIN: somethingSomething
|
||||||
|
AUTO_ADD_NAME : somethingSomething
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: batch/v1
|
||||||
|
kind: CronJob
|
||||||
|
metadata:
|
||||||
|
name: pbsupper
|
||||||
|
namespace: CHANGE_ME
|
||||||
|
labels:
|
||||||
|
server: Server-1
|
||||||
|
idrac: v7
|
||||||
|
|
||||||
|
spec:
|
||||||
|
schedule: "*/15 * * * *"
|
||||||
|
timeZone: "Europe/Stockholm"
|
||||||
|
concurrencyPolicy: Forbid
|
||||||
|
|
||||||
|
successfulJobsHistoryLimit: 3
|
||||||
|
failedJobsHistoryLimit: 3
|
||||||
|
|
||||||
|
jobTemplate:
|
||||||
|
spec:
|
||||||
|
backoffLimit: 2
|
||||||
|
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
restartPolicy: Never
|
||||||
|
automountServiceAccountToken: false
|
||||||
|
|
||||||
|
securityContext:
|
||||||
|
appArmorProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
|
||||||
|
containers:
|
||||||
|
- name: pbsupper
|
||||||
|
image: tea.shupogaki.org/yuruc3/pbsupper:v0
|
||||||
|
imagePullPolicy: IfNotPresent
|
||||||
|
|
||||||
|
envFrom:
|
||||||
|
- secretRef:
|
||||||
|
name: pbsupper-deployment-1-secretmap
|
||||||
|
- configMapRef:
|
||||||
|
name: pbsupper-deployment-1-configmap
|
||||||
|
|
||||||
|
securityContext:
|
||||||
|
runAsUser: 1600
|
||||||
|
runAsGroup: 1600
|
||||||
|
runAsNonRoot: true
|
||||||
|
allowPrivilegeEscalation: false
|
||||||
|
capabilities:
|
||||||
|
drop:
|
||||||
|
- ALL
|
||||||
|
seccompProfile:
|
||||||
|
type: RuntimeDefault
|
||||||
|
|
||||||
|
resources:
|
||||||
|
limits:
|
||||||
|
cpu: 200m
|
||||||
|
memory: 128Mi
|
||||||
|
requests:
|
||||||
|
cpu: 100m
|
||||||
|
memory: 64Mi
|
||||||
1
requirements.txt
Normal file
1
requirements.txt
Normal file
@@ -0,0 +1 @@
|
|||||||
|
paramiko==5.0.0
|
||||||
Reference in New Issue
Block a user