diff --git a/AppImage/components/lxc-app-panel.tsx b/AppImage/components/lxc-app-panel.tsx index 0c7cd6e4..f55a0c6b 100644 --- a/AppImage/components/lxc-app-panel.tsx +++ b/AppImage/components/lxc-app-panel.tsx @@ -397,6 +397,10 @@ const SELFHST_THEME_LOGOS: Record -44 of 532 applications in the OCI catalog have been tested for real: 41 in the ProxMenux lab and 3 by the community. The OCI installer shows them as verified, with a ✓ in the lists. +52 of 532 applications in the OCI catalog have been tested for real: 49 in the ProxMenux lab and 3 by the community. The OCI installer shows them as verified, with a ✓ in the lists. Each test describes the scenario that was run and names the image it ran on. It does not cover every possible configuration of the application, and a newer image has not been tested until someone reports it. @@ -38,6 +38,7 @@ Questions and ideas about OCI testing go in [discussion #440](https://github.com | Alby Hub ✨ | Finance & Budgeting | | Alist | Files & Sharing | | aMule | Files & Downloads | +| Authentik | Authentication & Security | | Chromium | Browsers & Web Desktops | | CodeProject.AI Server | AI | | CopyParty | Files & Sharing | @@ -50,26 +51,33 @@ Questions and ideas about OCI testing go in [discussion #440](https://github.com | Flexget | *Arr Suite | | Frigate | NVR & Cameras | | Grafana | Monitoring & Analytics | +| HAOS One | IoT & Smart Home | | Immich | Media | | JDownloader | Files & Downloads | | Jenkins CI/CD | AI / Coding & Dev-Tools | | Linkwarden | Documents & Notes | +| Mariadb | Databases | | Memos | Documents & Notes | | MineOS | Gaming & Leisure | | Motioneye | NVR & Cameras | +| Navidrome | Media & Streaming | | Nextcloud | Productivity & Workflows | | Nextcloud Stack | Productivity & Workflows | | OpenList | Files & Sharing | | Openssh Server | Remote Access & VPN | | Paperless-ngx | Productivity & Workflows | | Phpmyadmin | Databases | +| Prowlarr | *Arr Suite | | Qbittorrent | Files & Downloads | | Rclone WebUI | Backup & Recovery | | Real-Debrid Torrent Client | Files & Downloads | +| Scanopy | Network & Firewall | | ShareCoveX | Files & Sharing | | SnapOtter | Media & Streaming | +| Sonarr | *Arr Suite | | Tandoor Recipes | Productivity & Workflows | | Thelounge | Communication & Community | | Trilium | Documents & Notes | +| Vaultwarden | Authentication & Security | | Wireguard | Remote Access & VPN | | WireGuard Easy | Remote Access & VPN | diff --git a/oci/catalog/apps/acestream-http-proxy.json b/oci/catalog/apps/acestream-http-proxy.json index 73f5cc0d..a0ad94f5 100644 --- a/oci/catalog/apps/acestream-http-proxy.json +++ b/oci/catalog/apps/acestream-http-proxy.json @@ -323,6 +323,9 @@ "AceStream HTTP Proxy has no web interface: a media player opens its streams.", "HLS stream: port 6878, path /ace/manifest.m3u8?id= followed by the channel ID.", "MPEG-TS stream: port 6878, path /ace/getstream?id= followed by the channel ID." + ], + "non_persistent_image_volumes": [ + "/home/appuser/.ACEStream" ] } }, diff --git a/oci/catalog/apps/bind9.json b/oci/catalog/apps/bind9.json index 8a385940..31bee94a 100644 --- a/oci/catalog/apps/bind9.json +++ b/oci/catalog/apps/bind9.json @@ -76,6 +76,38 @@ "backup": true, "default_size_gb": 2 } + }, + { + "id": "volume-1", + "container_path": "/etc/bind", + "compose_source_example": "./config", + "read_only": false, + "required": true, + "installation_choice": [ + "managed-volume", + "host-bind" + ], + "default": "managed-volume", + "managed_volume": { + "backup": true, + "default_size_gb": 1 + } + }, + { + "id": "volume-2", + "container_path": "/var/lib/bind", + "compose_source_example": "./lib", + "read_only": false, + "required": true, + "installation_choice": [ + "managed-volume", + "host-bind" + ], + "default": "managed-volume", + "managed_volume": { + "backup": true, + "default_size_gb": 1 + } } ], "ports": [ @@ -123,7 +155,9 @@ "53:53/tcp" ], "volumes": [ - "./bind:/var/cache/bind" + "./bind:/var/cache/bind", + "./config:/etc/bind", + "./lib:/var/lib/bind" ] } } @@ -151,6 +185,28 @@ "shared_with_other_lxc": false, "source_path": null, "source_path_prompt": null + }, + { + "id": "bind9-volume-1", + "service": "bind9", + "container_path": "/etc/bind", + "mode": "managed-volume", + "user_selectable": true, + "backup": true, + "shared_with_other_lxc": false, + "source_path": null, + "source_path_prompt": null + }, + { + "id": "bind9-volume-2", + "service": "bind9", + "container_path": "/var/lib/bind", + "mode": "managed-volume", + "user_selectable": true, + "backup": true, + "shared_with_other_lxc": false, + "source_path": null, + "source_path_prompt": null } ], "orchestration": { @@ -349,7 +405,11 @@ "validation": "not-requested-by-compose" } ], - "installer_profile": {}, + "installer_profile": { + "non_persistent_image_volumes": [ + "/var/log" + ] + }, "catalog": { "replaces_discovered_ids": [] } diff --git a/oci/catalog/apps/chrony.json b/oci/catalog/apps/chrony.json index 34c8a44e..06350504 100644 --- a/oci/catalog/apps/chrony.json +++ b/oci/catalog/apps/chrony.json @@ -339,7 +339,13 @@ "validation": "not-requested-by-compose" } ], - "installer_profile": {} + "installer_profile": { + "non_persistent_image_volumes": [ + "/etc/chrony", + "/run/chrony", + "/var/lib/chrony" + ] + } }, "compatibility": { "automatic_install_candidate": true, diff --git a/oci/catalog/apps/gotosocial.json b/oci/catalog/apps/gotosocial.json index 105585ae..8da1fa45 100644 --- a/oci/catalog/apps/gotosocial.json +++ b/oci/catalog/apps/gotosocial.json @@ -409,7 +409,10 @@ "request_timeout_seconds": 10, "stability_seconds": 4, "verify_tls": true - } + }, + "non_persistent_image_volumes": [ + "/gotosocial/.cache" + ] } }, "compatibility": { diff --git a/oci/catalog/apps/jaeger.json b/oci/catalog/apps/jaeger.json index 764b4949..0fdf6d69 100644 --- a/oci/catalog/apps/jaeger.json +++ b/oci/catalog/apps/jaeger.json @@ -345,7 +345,11 @@ "validation": "not-requested-by-compose" } ], - "installer_profile": {}, + "installer_profile": { + "non_persistent_image_volumes": [ + "/tmp" + ] + }, "catalog": { "replaces_discovered_ids": [] } diff --git a/oci/catalog/apps/kanboard.json b/oci/catalog/apps/kanboard.json index f0cb3cf3..ed0ba4f3 100644 --- a/oci/catalog/apps/kanboard.json +++ b/oci/catalog/apps/kanboard.json @@ -94,6 +94,22 @@ "backup": true, "default_size_gb": 8 } + }, + { + "id": "volume-2", + "container_path": "/etc/nginx/ssl", + "compose_source_example": "./ssl", + "read_only": false, + "required": true, + "installation_choice": [ + "managed-volume", + "host-bind" + ], + "default": "managed-volume", + "managed_volume": { + "backup": true, + "default_size_gb": 1 + } } ], "ports": [ @@ -134,7 +150,8 @@ ], "volumes": [ "./data:/var/www/app/data", - "./plugins:/var/www/app/plugins" + "./plugins:/var/www/app/plugins", + "./ssl:/etc/nginx/ssl" ] } } @@ -171,6 +188,17 @@ "shared_with_other_lxc": false, "source_path": null, "source_path_prompt": null + }, + { + "id": "kanboard-volume-2", + "service": "kanboard", + "container_path": "/etc/nginx/ssl", + "mode": "managed-volume", + "user_selectable": false, + "backup": true, + "shared_with_other_lxc": false, + "source_path": null, + "source_path_prompt": null } ], "orchestration": { @@ -391,6 +419,12 @@ "remove_lost_found": true, "owner_strategy": "mapped-application-user", "only_when_mount_type": "managed-volume" + }, + { + "container_path": "/etc/nginx/ssl", + "remove_lost_found": true, + "owner_strategy": "mapped-root", + "only_when_mount_type": "managed-volume" } ], "startup_healthcheck": { diff --git a/oci/catalog/apps/plantuml-server.json b/oci/catalog/apps/plantuml-server.json index 4f3c555d..40c0e6c2 100644 --- a/oci/catalog/apps/plantuml-server.json +++ b/oci/catalog/apps/plantuml-server.json @@ -329,7 +329,10 @@ "request_timeout_seconds": 10, "stability_seconds": 4, "verify_tls": true - } + }, + "non_persistent_image_volumes": [ + "/tmp/jetty" + ] } }, "compatibility": { diff --git a/oci/catalog/apps/romm.json b/oci/catalog/apps/romm.json index cd98a442..b2597f6e 100644 --- a/oci/catalog/apps/romm.json +++ b/oci/catalog/apps/romm.json @@ -788,6 +788,9 @@ "owner_strategy": "mapped-root", "only_when_mount_type": "managed-volume" } + ], + "non_persistent_image_volumes": [ + "/romm" ] } }, diff --git a/oci/catalog/apps/tor.json b/oci/catalog/apps/tor.json index f1504e02..7947d3e0 100644 --- a/oci/catalog/apps/tor.json +++ b/oci/catalog/apps/tor.json @@ -60,7 +60,24 @@ "pull_policy": "resolve-written-reference-to-architecture-digest-at-install" }, "environment": [], - "volumes": [], + "volumes": [ + { + "id": "volume-0", + "container_path": "/var/lib/tor", + "compose_source_example": "./tor-data", + "read_only": false, + "required": true, + "installation_choice": [ + "managed-volume", + "host-bind" + ], + "default": "managed-volume", + "managed_volume": { + "backup": true, + "default_size_gb": 1 + } + } + ], "ports": [ { "container_port": 9050, @@ -103,6 +120,9 @@ "ports": [ "9050:9050", "8118:8118" + ], + "volumes": [ + "./tor-data:/var/lib/tor" ] } } @@ -119,7 +139,19 @@ "dependency_external_access": "disabled-unless-service-publishes-ports", "prompt_user_for_private_network": false }, - "storage": [], + "storage": [ + { + "id": "tor-volume-0", + "service": "tor", + "container_path": "/var/lib/tor", + "mode": "managed-volume", + "user_selectable": false, + "backup": true, + "shared_with_other_lxc": false, + "source_path": null, + "source_path_prompt": null + } + ], "orchestration": { "reserve_vmids_atomically": 1, "start_order": [ @@ -323,7 +355,19 @@ "SOCKS5 proxy: configure your application with the LXC IP address shown above and port 9050.", "HTTP CONNECT proxy: use the same IP address and port 8118. These addresses are proxy settings, not web links.", "Only applications configured to use this proxy send their traffic through Tor." - ] + ], + "volume_preparations": [ + { + "container_path": "/var/lib/tor", + "remove_lost_found": true, + "owner_strategy": "mapped-application-user", + "only_when_mount_type": "managed-volume" + } + ], + "volume_owner": { + "uid": 101, + "gid": 102 + } } }, "compatibility": { diff --git a/oci/catalog/apps/urbackup.json b/oci/catalog/apps/urbackup.json index 7c82370d..213d5bcd 100644 --- a/oci/catalog/apps/urbackup.json +++ b/oci/catalog/apps/urbackup.json @@ -323,7 +323,10 @@ "request_timeout_seconds": 10, "stability_seconds": 4, "verify_tls": true - } + }, + "non_persistent_image_volumes": [ + "/var/log" + ] }, "adaptations": [ { diff --git a/oci/catalog/apps/whoogle.json b/oci/catalog/apps/whoogle.json index 2e173160..308617ed 100644 --- a/oci/catalog/apps/whoogle.json +++ b/oci/catalog/apps/whoogle.json @@ -77,7 +77,24 @@ "source": "upstream-documentation" } ], - "volumes": [], + "volumes": [ + { + "id": "volume-0", + "container_path": "/config", + "compose_source_example": "./config", + "read_only": false, + "required": true, + "installation_choice": [ + "managed-volume", + "host-bind" + ], + "default": "managed-volume", + "managed_volume": { + "backup": true, + "default_size_gb": 1 + } + } + ], "ports": [ { "container_port": 5000, @@ -117,7 +134,10 @@ "environment": { "WHOOGLE_USER": "admin", "WHOOGLE_PASS": "${GENERATED_WHOOGLE_PASS}" - } + }, + "volumes": [ + "./config:/config" + ] } } ], @@ -133,7 +153,19 @@ "dependency_external_access": "disabled-unless-service-publishes-ports", "prompt_user_for_private_network": false }, - "storage": [], + "storage": [ + { + "id": "whoogle-volume-0", + "service": "whoogle", + "container_path": "/config", + "mode": "managed-volume", + "user_selectable": false, + "backup": true, + "shared_with_other_lxc": false, + "source_path": null, + "source_path_prompt": null + } + ], "orchestration": { "reserve_vmids_atomically": 1, "start_order": [ @@ -378,6 +410,18 @@ "bytes": 24, "prompt": false } + }, + "volume_preparations": [ + { + "container_path": "/config", + "remove_lost_found": true, + "owner_strategy": "mapped-application-user", + "only_when_mount_type": "managed-volume" + } + ], + "volume_owner": { + "uid": 927, + "gid": 927 } }, "catalog": { diff --git a/oci/catalog/curated/acestream-http-proxy.json b/oci/catalog/curated/acestream-http-proxy.json index 73f5cc0d..a0ad94f5 100644 --- a/oci/catalog/curated/acestream-http-proxy.json +++ b/oci/catalog/curated/acestream-http-proxy.json @@ -323,6 +323,9 @@ "AceStream HTTP Proxy has no web interface: a media player opens its streams.", "HLS stream: port 6878, path /ace/manifest.m3u8?id= followed by the channel ID.", "MPEG-TS stream: port 6878, path /ace/getstream?id= followed by the channel ID." + ], + "non_persistent_image_volumes": [ + "/home/appuser/.ACEStream" ] } }, diff --git a/oci/catalog/curated/bind9.json b/oci/catalog/curated/bind9.json index 8a385940..31bee94a 100644 --- a/oci/catalog/curated/bind9.json +++ b/oci/catalog/curated/bind9.json @@ -76,6 +76,38 @@ "backup": true, "default_size_gb": 2 } + }, + { + "id": "volume-1", + "container_path": "/etc/bind", + "compose_source_example": "./config", + "read_only": false, + "required": true, + "installation_choice": [ + "managed-volume", + "host-bind" + ], + "default": "managed-volume", + "managed_volume": { + "backup": true, + "default_size_gb": 1 + } + }, + { + "id": "volume-2", + "container_path": "/var/lib/bind", + "compose_source_example": "./lib", + "read_only": false, + "required": true, + "installation_choice": [ + "managed-volume", + "host-bind" + ], + "default": "managed-volume", + "managed_volume": { + "backup": true, + "default_size_gb": 1 + } } ], "ports": [ @@ -123,7 +155,9 @@ "53:53/tcp" ], "volumes": [ - "./bind:/var/cache/bind" + "./bind:/var/cache/bind", + "./config:/etc/bind", + "./lib:/var/lib/bind" ] } } @@ -151,6 +185,28 @@ "shared_with_other_lxc": false, "source_path": null, "source_path_prompt": null + }, + { + "id": "bind9-volume-1", + "service": "bind9", + "container_path": "/etc/bind", + "mode": "managed-volume", + "user_selectable": true, + "backup": true, + "shared_with_other_lxc": false, + "source_path": null, + "source_path_prompt": null + }, + { + "id": "bind9-volume-2", + "service": "bind9", + "container_path": "/var/lib/bind", + "mode": "managed-volume", + "user_selectable": true, + "backup": true, + "shared_with_other_lxc": false, + "source_path": null, + "source_path_prompt": null } ], "orchestration": { @@ -349,7 +405,11 @@ "validation": "not-requested-by-compose" } ], - "installer_profile": {}, + "installer_profile": { + "non_persistent_image_volumes": [ + "/var/log" + ] + }, "catalog": { "replaces_discovered_ids": [] } diff --git a/oci/catalog/curated/chrony.json b/oci/catalog/curated/chrony.json index 34c8a44e..06350504 100644 --- a/oci/catalog/curated/chrony.json +++ b/oci/catalog/curated/chrony.json @@ -339,7 +339,13 @@ "validation": "not-requested-by-compose" } ], - "installer_profile": {} + "installer_profile": { + "non_persistent_image_volumes": [ + "/etc/chrony", + "/run/chrony", + "/var/lib/chrony" + ] + } }, "compatibility": { "automatic_install_candidate": true, diff --git a/oci/catalog/curated/gotosocial.json b/oci/catalog/curated/gotosocial.json index 105585ae..8da1fa45 100644 --- a/oci/catalog/curated/gotosocial.json +++ b/oci/catalog/curated/gotosocial.json @@ -409,7 +409,10 @@ "request_timeout_seconds": 10, "stability_seconds": 4, "verify_tls": true - } + }, + "non_persistent_image_volumes": [ + "/gotosocial/.cache" + ] } }, "compatibility": { diff --git a/oci/catalog/curated/jaeger.json b/oci/catalog/curated/jaeger.json index c9aa3ebe..81d54ffc 100644 --- a/oci/catalog/curated/jaeger.json +++ b/oci/catalog/curated/jaeger.json @@ -345,7 +345,11 @@ "validation": "not-requested-by-compose" } ], - "installer_profile": {}, + "installer_profile": { + "non_persistent_image_volumes": [ + "/tmp" + ] + }, "catalog": { "replaces_discovered_ids": [] } diff --git a/oci/catalog/curated/kanboard.json b/oci/catalog/curated/kanboard.json index f0cb3cf3..ed0ba4f3 100644 --- a/oci/catalog/curated/kanboard.json +++ b/oci/catalog/curated/kanboard.json @@ -94,6 +94,22 @@ "backup": true, "default_size_gb": 8 } + }, + { + "id": "volume-2", + "container_path": "/etc/nginx/ssl", + "compose_source_example": "./ssl", + "read_only": false, + "required": true, + "installation_choice": [ + "managed-volume", + "host-bind" + ], + "default": "managed-volume", + "managed_volume": { + "backup": true, + "default_size_gb": 1 + } } ], "ports": [ @@ -134,7 +150,8 @@ ], "volumes": [ "./data:/var/www/app/data", - "./plugins:/var/www/app/plugins" + "./plugins:/var/www/app/plugins", + "./ssl:/etc/nginx/ssl" ] } } @@ -171,6 +188,17 @@ "shared_with_other_lxc": false, "source_path": null, "source_path_prompt": null + }, + { + "id": "kanboard-volume-2", + "service": "kanboard", + "container_path": "/etc/nginx/ssl", + "mode": "managed-volume", + "user_selectable": false, + "backup": true, + "shared_with_other_lxc": false, + "source_path": null, + "source_path_prompt": null } ], "orchestration": { @@ -391,6 +419,12 @@ "remove_lost_found": true, "owner_strategy": "mapped-application-user", "only_when_mount_type": "managed-volume" + }, + { + "container_path": "/etc/nginx/ssl", + "remove_lost_found": true, + "owner_strategy": "mapped-root", + "only_when_mount_type": "managed-volume" } ], "startup_healthcheck": { diff --git a/oci/catalog/curated/plantuml-server.json b/oci/catalog/curated/plantuml-server.json index 4f3c555d..40c0e6c2 100644 --- a/oci/catalog/curated/plantuml-server.json +++ b/oci/catalog/curated/plantuml-server.json @@ -329,7 +329,10 @@ "request_timeout_seconds": 10, "stability_seconds": 4, "verify_tls": true - } + }, + "non_persistent_image_volumes": [ + "/tmp/jetty" + ] } }, "compatibility": { diff --git a/oci/catalog/curated/tor.json b/oci/catalog/curated/tor.json index f1504e02..7947d3e0 100644 --- a/oci/catalog/curated/tor.json +++ b/oci/catalog/curated/tor.json @@ -60,7 +60,24 @@ "pull_policy": "resolve-written-reference-to-architecture-digest-at-install" }, "environment": [], - "volumes": [], + "volumes": [ + { + "id": "volume-0", + "container_path": "/var/lib/tor", + "compose_source_example": "./tor-data", + "read_only": false, + "required": true, + "installation_choice": [ + "managed-volume", + "host-bind" + ], + "default": "managed-volume", + "managed_volume": { + "backup": true, + "default_size_gb": 1 + } + } + ], "ports": [ { "container_port": 9050, @@ -103,6 +120,9 @@ "ports": [ "9050:9050", "8118:8118" + ], + "volumes": [ + "./tor-data:/var/lib/tor" ] } } @@ -119,7 +139,19 @@ "dependency_external_access": "disabled-unless-service-publishes-ports", "prompt_user_for_private_network": false }, - "storage": [], + "storage": [ + { + "id": "tor-volume-0", + "service": "tor", + "container_path": "/var/lib/tor", + "mode": "managed-volume", + "user_selectable": false, + "backup": true, + "shared_with_other_lxc": false, + "source_path": null, + "source_path_prompt": null + } + ], "orchestration": { "reserve_vmids_atomically": 1, "start_order": [ @@ -323,7 +355,19 @@ "SOCKS5 proxy: configure your application with the LXC IP address shown above and port 9050.", "HTTP CONNECT proxy: use the same IP address and port 8118. These addresses are proxy settings, not web links.", "Only applications configured to use this proxy send their traffic through Tor." - ] + ], + "volume_preparations": [ + { + "container_path": "/var/lib/tor", + "remove_lost_found": true, + "owner_strategy": "mapped-application-user", + "only_when_mount_type": "managed-volume" + } + ], + "volume_owner": { + "uid": 101, + "gid": 102 + } } }, "compatibility": { diff --git a/oci/catalog/curated/urbackup.json b/oci/catalog/curated/urbackup.json index 7c82370d..213d5bcd 100644 --- a/oci/catalog/curated/urbackup.json +++ b/oci/catalog/curated/urbackup.json @@ -323,7 +323,10 @@ "request_timeout_seconds": 10, "stability_seconds": 4, "verify_tls": true - } + }, + "non_persistent_image_volumes": [ + "/var/log" + ] }, "adaptations": [ { diff --git a/oci/catalog/curated/whoogle.json b/oci/catalog/curated/whoogle.json index 2e173160..308617ed 100644 --- a/oci/catalog/curated/whoogle.json +++ b/oci/catalog/curated/whoogle.json @@ -77,7 +77,24 @@ "source": "upstream-documentation" } ], - "volumes": [], + "volumes": [ + { + "id": "volume-0", + "container_path": "/config", + "compose_source_example": "./config", + "read_only": false, + "required": true, + "installation_choice": [ + "managed-volume", + "host-bind" + ], + "default": "managed-volume", + "managed_volume": { + "backup": true, + "default_size_gb": 1 + } + } + ], "ports": [ { "container_port": 5000, @@ -117,7 +134,10 @@ "environment": { "WHOOGLE_USER": "admin", "WHOOGLE_PASS": "${GENERATED_WHOOGLE_PASS}" - } + }, + "volumes": [ + "./config:/config" + ] } } ], @@ -133,7 +153,19 @@ "dependency_external_access": "disabled-unless-service-publishes-ports", "prompt_user_for_private_network": false }, - "storage": [], + "storage": [ + { + "id": "whoogle-volume-0", + "service": "whoogle", + "container_path": "/config", + "mode": "managed-volume", + "user_selectable": false, + "backup": true, + "shared_with_other_lxc": false, + "source_path": null, + "source_path_prompt": null + } + ], "orchestration": { "reserve_vmids_atomically": 1, "start_order": [ @@ -378,6 +410,18 @@ "bytes": 24, "prompt": false } + }, + "volume_preparations": [ + { + "container_path": "/config", + "remove_lost_found": true, + "owner_strategy": "mapped-application-user", + "only_when_mount_type": "managed-volume" + } + ], + "volume_owner": { + "uid": 927, + "gid": 927 } }, "catalog": { diff --git a/oci/catalog/overlays/romm.json b/oci/catalog/overlays/romm.json index 444ee835..dedea738 100644 --- a/oci/catalog/overlays/romm.json +++ b/oci/catalog/overlays/romm.json @@ -99,6 +99,9 @@ "owner_strategy": "mapped-root", "only_when_mount_type": "managed-volume" } + ], + "non_persistent_image_volumes": [ + "/romm" ] } } diff --git a/oci/catalog/verification.json b/oci/catalog/verification.json index 6a346f0b..ba2bf5b8 100644 --- a/oci/catalog/verification.json +++ b/oci/catalog/verification.json @@ -19,6 +19,9 @@ "amule": { "status": "laboratory-validated" }, + "authentik": { + "status": "laboratory-validated" + }, "chromium": { "status": "laboratory-validated" }, @@ -62,6 +65,9 @@ "grafana": { "status": "laboratory-validated" }, + "haos-one": { + "status": "laboratory-validated" + }, "immich": { "status": "laboratory-validated" }, @@ -74,6 +80,9 @@ "linkwarden": { "status": "laboratory-validated" }, + "mariadb": { + "status": "laboratory-validated" + }, "memos": { "status": "laboratory-validated" }, @@ -83,6 +92,9 @@ "motioneye": { "status": "laboratory-validated" }, + "navidrome": { + "status": "laboratory-validated" + }, "nextcloud": { "status": "laboratory-validated" }, @@ -108,6 +120,9 @@ "report": "https://github.com/MacRimi/ProxMenux/discussions/392#discussioncomment-18623868" } }, + "prowlarr": { + "status": "laboratory-validated" + }, "qbittorrent": { "status": "laboratory-validated" }, @@ -117,12 +132,18 @@ "rdtclient": { "status": "laboratory-validated" }, + "scanopy": { + "status": "laboratory-validated" + }, "sharecovex": { "status": "laboratory-validated" }, "snapotter": { "status": "laboratory-validated" }, + "sonarr": { + "status": "laboratory-validated" + }, "tandoor": { "status": "laboratory-validated" }, @@ -140,6 +161,9 @@ "trilium": { "status": "laboratory-validated" }, + "vaultwarden": { + "status": "laboratory-validated" + }, "wg-easy": { "status": "laboratory-validated" }, diff --git a/oci/remote/oci_instance_transaction.py b/oci/remote/oci_instance_transaction.py index 2599b067..ca92744d 100644 --- a/oci/remote/oci_instance_transaction.py +++ b/oci/remote/oci_instance_transaction.py @@ -728,8 +728,9 @@ def preflight(record, candidate, config, coordinated=None, in_place=False, basel raise ValueError(translate('Required persistent paths cannot be removed')) image_paths = set(record['observed']['image']['defaults'].get('Volumes') or {}) image_paths -= non_persistent_image_volumes(record['template']) - if any(not any(p == target or p.startswith(target.rstrip('/') + '/') for target in old) for p in image_paths): - raise ValueError(translate('The image declares data paths that are still stored in the rootfs')) + in_rootfs = sorted(p for p in image_paths if not any(p == target or p.startswith(target.rstrip('/') + '/') for target in old)) + if in_rootfs: + raise ValueError(f"{translate('The image declares data paths that are still stored in the rootfs')}: {', '.join(in_rootfs)}") check = effective_healthcheck(candidate['template']) if not check and not coordinated: raise ValueError(translate('Updates are not available yet for this application in this beta')) diff --git a/oci/src/proxmenux_oci/stack.py b/oci/src/proxmenux_oci/stack.py index be85c17a..0ba2727d 100644 --- a/oci/src/proxmenux_oci/stack.py +++ b/oci/src/proxmenux_oci/stack.py @@ -219,6 +219,11 @@ def service_template(parent, service, main=False): own_preparations.append(entry) if own_preparations: single['proxmox'].setdefault('installer_profile', {})['volume_preparations'] = own_preparations + # Image paths the oci-compose states hold no data; an image that does not + # declare one of them is not affected by it. + transient = parent.get('proxmox', {}).get('installer_profile', {}).get('non_persistent_image_volumes') + if transient: + single['proxmox'].setdefault('installer_profile', {})['non_persistent_image_volumes'] = list(transient) return single @@ -784,10 +789,11 @@ def apply_stack_support(template): template['status'] = 'generated-review-required' return template['proxmox'].pop('generic_stack_review',None) - preserved_preparations = template['proxmox'].get('installer_profile',{}).get('volume_preparations') + profile = template['proxmox'].get('installer_profile',{}) template['proxmox']['installer_profile'] = {'stack_driver':'generic-multi-lxc-stack'} - if preserved_preparations: - template['proxmox']['installer_profile']['volume_preparations'] = preserved_preparations + for key in ('volume_preparations', 'non_persistent_image_volumes'): + if profile.get(key): + template['proxmox']['installer_profile'][key] = profile[key] template['compatibility']['untranslated_blockers'] = [] template['compatibility']['automatic_install_candidate'] = True template['status'] = 'generated-unvalidated' diff --git a/oci/tests/test_stack_transient_image_volumes.py b/oci/tests/test_stack_transient_image_volumes.py new file mode 100644 index 00000000..42c8f365 --- /dev/null +++ b/oci/tests/test_stack_transient_image_volumes.py @@ -0,0 +1,30 @@ +"""Image paths a stack's oci-compose states hold no data reach the template +of every container of the stack, where updates and Modify read them.""" +import copy +from pathlib import Path +import sys +import unittest + +ROOT = Path(__file__).resolve().parents[1] +sys.path.insert(0, str(ROOT / "src")) + +from proxmenux_oci.catalog import Catalog +from proxmenux_oci.stack import apply_stack_support, build_stack, DefaultsUI + + +class StackTransientImageVolumesTests(unittest.TestCase): + def test_each_container_of_romm_receives_the_transient_paths(self): + result = build_stack(Catalog(ROOT).compose("romm"), DefaultsUI(), mode="simple") + for service in result["services"]: + profile = service["template"]["proxmox"]["installer_profile"] + self.assertEqual(profile.get("non_persistent_image_volumes"), ["/romm"], service["name"]) + + def test_the_stack_profile_keeps_them_when_it_is_rewritten(self): + template = copy.deepcopy(Catalog(ROOT).compose("romm")) + template["proxmox"]["installer_profile"]["stack_driver"] = "generic-multi-lxc-stack" + apply_stack_support(template) + self.assertEqual(template["proxmox"]["installer_profile"].get("non_persistent_image_volumes"), ["/romm"]) + + +if __name__ == "__main__": + unittest.main() diff --git a/oci/tests/test_update_check.py b/oci/tests/test_update_check.py index f8141c11..26d6dcc5 100644 --- a/oci/tests/test_update_check.py +++ b/oci/tests/test_update_check.py @@ -164,7 +164,9 @@ class UpdateCheckTests(unittest.TestCase): check.check(self.root, self.configs, path=path, progress=lambda *event: events.append(event)) native.assert_called_once(); notify.assert_not_called(); external.assert_not_called() self.assertEqual(events[0], (0, 1)); self.assertEqual(events[-1], (1, 1)) - self.assertEqual([r['vmid'] for r in self.status()['available']], [110]) + # The bridge stamps its result with the real clock, so read it at the real time too. + available = check.cached(self.root, self.configs, apps=self.apps)['available'] + self.assertEqual([r['vmid'] for r in available], [110]) self.assertFalse((self.root / '.update-check.json').exists()) def test_missing_monitor_never_falls_back_to_registry_commands(self): diff --git a/web/data/changelog/es.md b/web/data/changelog/es.md index f898dad9..7830f229 100644 --- a/web/data/changelog/es.md +++ b/web/data/changelog/es.md @@ -23,7 +23,7 @@ Un agradecimiento especial a [@Vaso73](https://github.com/Vaso73), [@f3rs3n](htt - **La entrada de Ollama describe lo que ofrece la imagen** ([PR #566](https://github.com/MacRimi/ProxMenux/pull/566), aportado por [@jcastro](https://github.com/jcastro)): su API HTTP en el puerto 11434, con el enlace y la comprobación de arranque en `/api/version`. - **Una actualización elimina el snapshot que deja un backup interrumpido** ([#565](https://github.com/MacRimi/ProxMenux/issues/565), reportado por [@kiosvantra](https://github.com/kiosvantra)). Un snapshot hecho por el usuario detiene la actualización, porque un contenedor reconstruido no puede conservarlo. - **Un contenedor que ignora la señal de apagado se detiene a los 60 segundos**, como hace `docker stop`, durante una actualización y al recuperar una operación interrumpida. -- **SearXNG guarda su configuración en su propio volumen**, `/etc/searxng`, de modo que Modificar y las actualizaciones lo aceptan. +- **Modificar y las actualizaciones aceptan toda aplicación cuya imagen declara una ruta de datos**: SearXNG, Tor, Whoogle y BIND9 la guardan en un volumen propio, Kanboard conserva sus certificados, y Chrony, Jaeger, PlantUML, UrBackup, GoToSocial, AceStream HTTP Proxy y RomM marcan las rutas que no guardan datos. Cuando una instalación aún tiene una de esas rutas dentro del contenedor, el mensaje la nombra. ## 🖥️ Monitor — actualizaciones de Proxmox y reinicios pendientes