mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-10-21 21:12:01 +00:00
feat(oci): recover applications after a Proxmox reinstall, cluster records and AMD GPU profiles
The installation record of an OCI application travels with its container: a copy inside the container and another in /etc/pve, written together with the one kept on the host. A container restored on a newly installed Proxmox, restored with another ID or moved to another node of a cluster is recognised and registered again, with its private network, hookscript, Rclone mount, host firewall rule and NVIDIA runtime. The Monitor offers the same recovery from the Updates tab. AMD GPUs are offered by generation. A GPU the ROCm image supports takes the profile as it is; one of a supported family (Radeon 680M, 780M) is an experimental option that asks for confirmation and is never proposed; an older one is not offered. The GPU is checked with a real inference before the installation accepts it. Recreate changes what runs recognition in an installed Immich, between the CPU and a GPU of the host. Updates: - A failed update that is restored and checked removes its temporary container and the disks of the failed attempt. - Every container volume is part of the backups, so Jellyfin, Plex and Hugo update with their default installation. - An image published with a Docker-format manifest is recognised by its layers and build time and updates. - The Proxmox notes of a multi-container application link to its LAN address.
This commit is contained in:
@@ -91,14 +91,57 @@ class ImmichAccelerationTests(unittest.TestCase):
|
||||
self.assertIn("No usable GPU", ui.messages[0])
|
||||
self.assertEqual(result, ("cpu", "cpu"), mode)
|
||||
|
||||
def test_an_amd_host_that_cannot_run_rocm_says_so_and_recognises_on_the_cpu(self, *_):
|
||||
for blocker, text in (("kfd", "/dev/kfd"), ("space", "40 GB")):
|
||||
with patch("proxmenux_oci.installer.host.rocm_blocker", return_value=blocker):
|
||||
ui, result, _ = self.plan(AMD, DEFAULT_MODE, "amd")
|
||||
def test_an_amd_host_that_cannot_run_rocm_offers_video_only_and_says_why(self, *_):
|
||||
for blocker, text in (("kfd", "/dev/kfd"), ("space", "40 GB"), ("generation", "no support for the AMD GPU")):
|
||||
with patch("proxmenux_oci.installer.host.rocm_blocker", return_value=blocker), \
|
||||
patch("proxmenux_oci.installer.host.amd_gpu_name", return_value="Lucienne (gfx90c)"):
|
||||
ui, result, _ = self.plan(AMD, DEFAULT_MODE)
|
||||
self.assertEqual(ui.options[PROMPT], ["cpu", "amd-video"], blocker)
|
||||
self.assertEqual(ui.defaults[PROMPT], "amd-video", blocker)
|
||||
self.assertEqual(result, ("vaapi", "cpu"), blocker)
|
||||
self.assertTrue(any(text in message and "Recognition runs on the CPU." in message
|
||||
self.assertTrue(any(text in message and "Recognition is not offered" in message
|
||||
for message in ui.messages), blocker)
|
||||
|
||||
def test_a_gpu_rocm_supports_is_proposed_whole(self, *_):
|
||||
for target in (100300, 110501, None):
|
||||
ui, result, plan = self.plan(dict(AMD, amd_gfx_target=target), DEFAULT_MODE)
|
||||
self.assertEqual(ui.defaults[PROMPT], "amd", target)
|
||||
self.assertEqual(result, ("vaapi", "rocm"), target)
|
||||
self.assertIsNone(plan["machine_learning"]["gfx_override"], target)
|
||||
|
||||
def test_a_gpu_rocm_does_not_support_officially_is_offered_as_experimental(self, *_):
|
||||
gpus = dict(AMD, amd_gfx_target=100305)
|
||||
with patch("proxmenux_oci.installer.host.amd_gpu_name", return_value="Radeon 680M (gfx1035)"):
|
||||
# Never the proposal: left alone, recognition stays on the CPU.
|
||||
ui, result, _ = self.plan(gpus, DEFAULT_MODE)
|
||||
self.assertEqual(ui.options[PROMPT], ["cpu", "amd", "amd-video", "amd-ml"])
|
||||
self.assertEqual(ui.defaults[PROMPT], "amd-video")
|
||||
self.assertEqual(result, ("vaapi", "cpu"))
|
||||
# Chosen and confirmed, it is installed with the generation of its family.
|
||||
ui = OptionsUI({PROMPT: "amd"})
|
||||
ui.confirm = lambda text, default=False: True if "ROCm does not support this GPU" in text else default
|
||||
with patch("proxmenux_oci.installer.host.gpus", return_value=gpus):
|
||||
plan = build_deployment(self.template, ui, DEFAULT_MODE)
|
||||
self.assertEqual(plan["machine_learning"]["acceleration"], "rocm")
|
||||
self.assertEqual(plan["machine_learning"]["gfx_override"], "10.3.0")
|
||||
# Declined, the menu is asked again.
|
||||
answers = iter(["amd", "amd-video"])
|
||||
ui = OptionsUI()
|
||||
ui.choose = lambda text, options, default=None: next(answers) if text == PROMPT else default
|
||||
with patch("proxmenux_oci.installer.host.gpus", return_value=gpus):
|
||||
plan = build_deployment(self.template, ui, DEFAULT_MODE)
|
||||
self.assertEqual(plan["machine_learning"]["acceleration"], "cpu")
|
||||
self.assertEqual(plan["video_transcoding"]["acceleration"], "vaapi")
|
||||
|
||||
def test_the_780m_family_is_presented_as_its_generation(self, *_):
|
||||
gpus = dict(AMD, amd_gfx_target=110003)
|
||||
ui = OptionsUI({PROMPT: "amd-ml"})
|
||||
ui.confirm = lambda text, default=False: True if "ROCm does not support this GPU" in text else default
|
||||
with patch("proxmenux_oci.installer.host.gpus", return_value=gpus), \
|
||||
patch("proxmenux_oci.installer.host.amd_gpu_name", return_value="Radeon 780M (gfx1103)"):
|
||||
plan = build_deployment(self.template, ui, DEFAULT_MODE)
|
||||
self.assertEqual(plan["machine_learning"]["gfx_override"], "11.0.0")
|
||||
|
||||
def test_machine_learning_gets_four_cores_and_at_least_four_gigabytes(self, *_):
|
||||
_, _, plan = self.plan(BOTH, DEFAULT_MODE, "cpu")
|
||||
self.assertEqual(plan["machine_learning"]["resources"]["cores"], 4)
|
||||
|
||||
Reference in New Issue
Block a user