mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-01 18:32:13 +00:00
OCI manager Apps - "Install an image that is not in the catalog" reads an oci-compose from a file of the host or from an address. - A file written by hand states the image, its ports, variables and volumes, and what the installation asks; the rest is completed when it is read. A complete file, or the record of an installation, is installed as it is, and of a record only the template is used. - Errors name the field they are in, also on a host without python3-jsonschema. - oci/README.md describes the engine and the oci-compose block by block, with two examples in oci/examples/. - The documentation page of the option covers it, in English and Spanish. Log2RAM (reported by @f3rs3n) - The sync removes the old active journal file from the disk copy, so a boot no longer restores it and journald deletes its oldest archives first. Log2RAM optimization 1.7; it takes effect from the next reboot. Translations - The bot keeps "oci-compose" as written. - Spanish texts for the new option and for the Log2RAM notice.
94 lines
4.1 KiB
Python
94 lines
4.1 KiB
Python
"""Log2RAM syncs only the archived journal files, so the active file it found
|
|
on disk when it was installed stays there and is restored at every boot.
|
|
journald then continues an old sequence and deletes its newest archives first.
|
|
The post-install makes the sync remove that file from the disk copy."""
|
|
|
|
from pathlib import Path
|
|
import shutil
|
|
import stat
|
|
import subprocess
|
|
import tempfile
|
|
import unittest
|
|
|
|
ROOT = Path(__file__).resolve().parents[3]
|
|
SHARED = ROOT / "scripts/global/utils-install-functions.sh"
|
|
FLOWS = {"auto_post_install.sh": "install_log2ram_auto", "customizable_post_install.sh": "configure_log2ram"}
|
|
|
|
# The sync of Log2RAM in its journald-aware mode, as its project ships it.
|
|
JOURNALD_AWARE = '''#!/usr/bin/env bash
|
|
sync_to_disk() {
|
|
is_safe
|
|
|
|
local optional_params=()
|
|
|
|
if journald_logrotate; then
|
|
optional_params+=("--include=journal/*/*@*.journal")
|
|
optional_params+=("--exclude=journal/*/*")
|
|
fi
|
|
|
|
rsync -aXv --no-acls --delete-after "${optional_params[@]}" "${RAM_LOG}"/ "${HDD_LOG}"/
|
|
}
|
|
'''
|
|
NOT_AWARE = '''#!/usr/bin/env bash
|
|
sync_to_disk() {
|
|
rsync -aXv --delete-after "${RAM_LOG}"/ "${HDD_LOG}"/
|
|
}
|
|
'''
|
|
|
|
|
|
def gnu_sed():
|
|
return shutil.which("bash") and subprocess.run(["sed", "--version"], capture_output=True).returncode == 0
|
|
|
|
|
|
@unittest.skipUnless(gnu_sed(), "bash and GNU sed are needed")
|
|
class Log2ramJournalSyncTests(unittest.TestCase):
|
|
def correct(self, folder, content, times=1):
|
|
script = Path(folder) / "log2ram"
|
|
script.write_text(content)
|
|
script.chmod(0o755)
|
|
calls = "; ".join(['pmx_log2ram_drop_stale_journal "$1"; echo "rc=$?"'] * times)
|
|
# As the change journal does, the new content is read whole before it is written.
|
|
write = 'pmx_write_file() { local content; content="$(cat)"; printf "%s\\n" "$content" > "$1"; }'
|
|
run = subprocess.run(["bash", "-c", f'source "{SHARED}"; {write}; {calls}',
|
|
"bash", str(script)], capture_output=True, text=True, check=False)
|
|
return script, run.stdout.split()
|
|
|
|
def test_the_sync_removes_what_it_does_not_copy(self):
|
|
with tempfile.TemporaryDirectory() as folder:
|
|
script, results = self.correct(folder, JOURNALD_AWARE)
|
|
lines = script.read_text().splitlines()
|
|
position = lines.index(' optional_params+=("--exclude=journal/*/*")')
|
|
self.assertEqual(lines[position + 1], ' optional_params+=("--delete-excluded")')
|
|
self.assertEqual(lines[position + 2], " fi")
|
|
self.assertEqual(results, ["rc=0"])
|
|
self.assertEqual(subprocess.run(["bash", "-n", str(script)]).returncode, 0)
|
|
self.assertTrue(script.stat().st_mode & stat.S_IXUSR)
|
|
self.assertEqual(Path(str(script) + ".proxmenux.bak").read_text(), JOURNALD_AWARE)
|
|
|
|
def test_it_is_applied_once(self):
|
|
with tempfile.TemporaryDirectory() as folder:
|
|
script, results = self.correct(folder, JOURNALD_AWARE, times=2)
|
|
self.assertEqual(results, ["rc=0", "rc=1"])
|
|
self.assertEqual(script.read_text().count("--delete-excluded"), 1)
|
|
|
|
def test_a_sync_that_copies_every_file_is_left_as_it_is(self):
|
|
with tempfile.TemporaryDirectory() as folder:
|
|
script, results = self.correct(folder, NOT_AWARE)
|
|
self.assertEqual(results, ["rc=1"])
|
|
self.assertEqual(script.read_text(), NOT_AWARE)
|
|
self.assertFalse(Path(str(script) + ".proxmenux.bak").exists())
|
|
|
|
def test_both_flows_apply_it_to_new_and_existing_installations(self):
|
|
for name, function in FLOWS.items():
|
|
with self.subTest(flow=name):
|
|
text = (ROOT / "scripts/post_install" / name).read_text()
|
|
self.assertEqual(text.count("pmx_log2ram_drop_stale_journal"), 2)
|
|
# An existing installation is told that it needs a reboot.
|
|
self.assertIn('if pmx_log2ram_drop_stale_journal "$log2ram_bin"; then\n NECESSARY_REBOOT=1', text)
|
|
# The version is what offers the update to existing installations.
|
|
self.assertIn(f'{function}() {{\n local FUNC_VERSION="1.7"', text)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|