mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-10-08 06:26:39 +00:00
OCI catalog verification, console start marks and log cleanup
This commit is contained in:
@@ -25,6 +25,17 @@ import sys
|
||||
|
||||
NO_LOGIN = ('nologin', 'false')
|
||||
LOG_DIR = Path('/var/log/proxmenux/oci')
|
||||
# Each start is marked in the console log by a pre-start hook. The hook runs
|
||||
# the script only when it exists and always succeeds: a hook that fails would
|
||||
# stop the container from starting.
|
||||
START_MARK_SCRIPT = Path(__file__).resolve().with_name('oci_console_mark.sh')
|
||||
START_MARK = '=== ProxMenux: container started '
|
||||
|
||||
|
||||
def start_mark_hook(vmid: int) -> str:
|
||||
script = START_MARK_SCRIPT
|
||||
# `test`, not `[`: a bracket in the configuration reads as a snapshot section.
|
||||
return f"lxc.hook.pre-start: /bin/sh -c 'test -x {script} && {script} {int(vmid)}; exit 0'"
|
||||
LOGROTATE = Path('/etc/logrotate.d/proxmenux-oci')
|
||||
# copytruncate, because liblxc keeps the file open for as long as the
|
||||
# container runs; moving it away would leave the application writing into the
|
||||
@@ -165,8 +176,9 @@ def enable_log(vmid: int) -> Path:
|
||||
text = conf.read_text()
|
||||
current, _, snapshots = text.partition('\n[')
|
||||
wanted = f'lxc.console.logfile: {path}'
|
||||
kept = [line for line in current.splitlines() if not line.startswith('lxc.console.logfile:')]
|
||||
kept.append(wanted)
|
||||
kept = [line for line in current.splitlines()
|
||||
if not line.startswith('lxc.console.logfile:') and START_MARK_SCRIPT.name not in line]
|
||||
kept += [wanted, start_mark_hook(vmid)]
|
||||
rebuilt = '\n'.join(kept) + '\n'
|
||||
if snapshots:
|
||||
rebuilt += '\n[' + snapshots
|
||||
@@ -176,6 +188,14 @@ def enable_log(vmid: int) -> Path:
|
||||
return path
|
||||
|
||||
|
||||
def remove_log(vmid: int) -> None:
|
||||
"""Delete the console log of a removed container and its rotated copies."""
|
||||
base = log_path(vmid)
|
||||
for path in [base, *LOG_DIR.glob(f'{base.name}.*')]:
|
||||
if path.is_file() and not path.is_symlink():
|
||||
path.unlink()
|
||||
|
||||
|
||||
def configure(vmid: int) -> dict:
|
||||
"""Console log and Proxmox terminal of a container being created."""
|
||||
path = enable_log(vmid)
|
||||
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
# Marks each start of an OCI container in its console log, so the log can be
|
||||
# read from the last start. Run by the container's lxc.hook.pre-start.
|
||||
case "$1" in
|
||||
''|*[!0-9]*) exit 0 ;;
|
||||
esac
|
||||
printf '\n=== ProxMenux: container started %s ===\n' "$(date '+%Y-%m-%d %H:%M:%S')" \
|
||||
>> "/var/log/proxmenux/oci/$1.console.log" 2>/dev/null
|
||||
exit 0
|
||||
@@ -44,7 +44,9 @@ BASIC = {'arch', 'cmode', 'console', 'tty', 'cores', 'cpulimit', 'cpuunits', 'de
|
||||
'lxc.signal.halt', 'lxc.environment.runtime',
|
||||
# The container's console log, set by the installer on every
|
||||
# creation; the rebuilt container gets it again the same way.
|
||||
'lxc.console.logfile'}
|
||||
'lxc.console.logfile',
|
||||
# The hook that marks each start in that log, set the same way.
|
||||
'lxc.hook.pre-start'}
|
||||
# Their output is data (and may hold saved secrets); it is never logged.
|
||||
DATA_COMMANDS = {('pct', 'config'), ('pvesh', 'get')}
|
||||
LOG_DIR = Path(os.environ.get('OCI_LOG_DIR', '/var/log/proxmenux/oci'))
|
||||
|
||||
@@ -18,6 +18,7 @@ import sys
|
||||
import oci_image_cache as image_cache
|
||||
import oci_instances as instances
|
||||
from oci_installation_state import parse_config
|
||||
import oci_console
|
||||
from oci_ui import translate, msg_info, msg_ok, msg_warn, msg_error
|
||||
|
||||
# The private networks ProxMenux creates for multi-container applications.
|
||||
@@ -118,11 +119,13 @@ def remove(root, vmid):
|
||||
config = guest_config(member)
|
||||
if config is None:
|
||||
msg_warn(f"{translate('The container no longer exists:')} CT {member}")
|
||||
oci_console.remove_log(member)
|
||||
elif instances.identity(config) != record['installation_id']:
|
||||
msg_warn(f"{translate('The VMID belongs to another container now and is not touched:')} CT {member}")
|
||||
else:
|
||||
subprocess.run(['pct', 'stop', str(member), '--skiplock', '1'], check=False, capture_output=True)
|
||||
run('pct', 'destroy', str(member), '--purge', '1', '--destroy-unreferenced-disks', '1')
|
||||
oci_console.remove_log(member)
|
||||
msg_ok(f"{translate('Container removed:')} CT {member}")
|
||||
if bridge and not bridge_in_use(bridge, set(members)):
|
||||
release_bridge(bridge)
|
||||
|
||||
Reference in New Issue
Block a user