mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-01 10:22:08 +00:00
install from a hand-written oci-compose; Log2RAM journal fix
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.
This commit is contained in:
@@ -102,6 +102,9 @@ PROTECTED_TECHNICAL_TERMS = (
|
||||
# Open Container Initiative. Read as a word it becomes "BEC" in French,
|
||||
# which named nothing, across thirty-one strings of the OCI section.
|
||||
"OCI manager Apps",
|
||||
# The file an application is installed from. Its name is the one of the
|
||||
# file on disk; translated, it names something the menu does not offer.
|
||||
"oci-compose",
|
||||
"OCI",
|
||||
"beta",
|
||||
# Debian release names. "Bookworm" is a bird and a reader of books, and
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
"""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()
|
||||
Reference in New Issue
Block a user