fix: rootless podman UID mapping for container data dirs
Some checks failed
Build Archipelago ISO (dev) / build-iso (push) Has been cancelled
Some checks failed
Build Archipelago ISO (dev) / build-iso (push) Has been cancelled
create_data_dirs now chowns data directories to the correct mapped UID for rootless podman (host_uid = 100000 + container_uid). Previously only Grafana (UID 472) was handled. Now all containers get the correct ownership: - Bitcoin Knots: 100101 (container UID 101) - Grafana: 100472 (UID 472) - LND: 101000 (UID 1000) - MariaDB: 100999 (UID 999) - Postgres: 100070 (UID 70) - All others: 100000 (UID 0, root) Without this, containers fail with "Operation not permitted" on chown during startup because rootless podman restricts UID operations. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -431,11 +431,29 @@ impl RpcHandler {
|
||||
}
|
||||
|
||||
/// Create data directories for volume mounts under /var/lib/archipelago/.
|
||||
/// Get the mapped host UID for a container's internal UID.
|
||||
/// Rootless podman maps container UIDs: host_uid = subuid_start + container_uid
|
||||
/// Default subuid start for archipelago user is 100000.
|
||||
fn mapped_uid(package_id: &str) -> u32 {
|
||||
let container_uid = match package_id {
|
||||
"bitcoin-knots" | "bitcoin" => 101,
|
||||
"grafana" => 472,
|
||||
"lnd" => 1000,
|
||||
"mariadb" | "mysql" => 999,
|
||||
"postgres" | "btcpay-postgres" | "immich-postgres" | "penpot-postgres" => 70,
|
||||
_ => 0, // Most containers run as root (UID 0)
|
||||
};
|
||||
100000 + container_uid
|
||||
}
|
||||
|
||||
async fn create_data_dirs(&self, package_id: &str, volumes: &[String]) {
|
||||
let uid = Self::mapped_uid(package_id);
|
||||
let uid_str = format!("{}:{}", uid, uid);
|
||||
|
||||
for volume in volumes {
|
||||
if let Some(host_path) = volume.split(':').next() {
|
||||
if host_path.starts_with("/var/lib/archipelago/") {
|
||||
debug!("Creating directory: {}", host_path);
|
||||
debug!("Creating directory: {} (owner: {})", host_path, uid_str);
|
||||
let create_dir = tokio::process::Command::new("sudo")
|
||||
.args(["mkdir", "-p", host_path])
|
||||
.output()
|
||||
@@ -443,13 +461,11 @@ impl RpcHandler {
|
||||
if let Err(e) = create_dir {
|
||||
debug!("Failed to create directory {}: {}", host_path, e);
|
||||
}
|
||||
// Grafana runs as UID 472 — fix permissions
|
||||
if package_id == "grafana" && host_path.contains("grafana") {
|
||||
let _ = tokio::process::Command::new("sudo")
|
||||
.args(["chown", "-R", "472:472", host_path])
|
||||
.output()
|
||||
.await;
|
||||
}
|
||||
// Set ownership to the mapped UID for rootless podman
|
||||
let _ = tokio::process::Command::new("sudo")
|
||||
.args(["chown", "-R", &uid_str, host_path])
|
||||
.output()
|
||||
.await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user