fix: rootless podman UID mapping for container data dirs
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:
parent
d25969e2e5
commit
20289c5bec
@ -431,11 +431,29 @@ impl RpcHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create data directories for volume mounts under /var/lib/archipelago/.
|
/// 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]) {
|
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 {
|
for volume in volumes {
|
||||||
if let Some(host_path) = volume.split(':').next() {
|
if let Some(host_path) = volume.split(':').next() {
|
||||||
if host_path.starts_with("/var/lib/archipelago/") {
|
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")
|
let create_dir = tokio::process::Command::new("sudo")
|
||||||
.args(["mkdir", "-p", host_path])
|
.args(["mkdir", "-p", host_path])
|
||||||
.output()
|
.output()
|
||||||
@ -443,13 +461,11 @@ impl RpcHandler {
|
|||||||
if let Err(e) = create_dir {
|
if let Err(e) = create_dir {
|
||||||
debug!("Failed to create directory {}: {}", host_path, e);
|
debug!("Failed to create directory {}: {}", host_path, e);
|
||||||
}
|
}
|
||||||
// Grafana runs as UID 472 — fix permissions
|
// Set ownership to the mapped UID for rootless podman
|
||||||
if package_id == "grafana" && host_path.contains("grafana") {
|
let _ = tokio::process::Command::new("sudo")
|
||||||
let _ = tokio::process::Command::new("sudo")
|
.args(["chown", "-R", &uid_str, host_path])
|
||||||
.args(["chown", "-R", "472:472", host_path])
|
.output()
|
||||||
.output()
|
.await;
|
||||||
.await;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user