Check whether the current user has subuid/subgid ranges configured. Rootless Podman requires entries in `/etc/subuid` and `/etc/subgid` for the running user. If missing, container creation fails with an obscure error. This pre-flight check emits a warning to guide operators.
()
| 823 | /// the running user. If missing, container creation fails with an obscure |
| 824 | /// error. This pre-flight check emits a warning to guide operators. |
| 825 | fn check_subuid_range() { |
| 826 | let uid = nix::unistd::getuid().as_raw(); |
| 827 | let username = nix::unistd::User::from_uid(nix::unistd::Uid::from_raw(uid)) |
| 828 | .ok() |
| 829 | .flatten() |
| 830 | .map(|u| u.name); |
| 831 | |
| 832 | let has_range = |path: &str| -> bool { |
| 833 | let Ok(content) = std::fs::read_to_string(path) else { |
| 834 | return false; |
| 835 | }; |
| 836 | let uid_str = uid.to_string(); |
| 837 | content.lines().any(|line| { |
| 838 | let Some(entry) = line.split(':').next() else { |
| 839 | return false; |
| 840 | }; |
| 841 | entry == uid_str || username.as_deref() == Some(entry) |
| 842 | }) |
| 843 | }; |
| 844 | |
| 845 | if !has_range("/etc/subuid") || !has_range("/etc/subgid") { |
| 846 | let user_display = username.as_deref().map_or_else( |
| 847 | || format!("UID {uid}"), |
| 848 | |name| format!("{name} (UID {uid})"), |
| 849 | ); |
| 850 | warn!( |
| 851 | user = %user_display, |
| 852 | "Rootless Podman detected but no /etc/subuid or /etc/subgid entry found. \ |
| 853 | Container creation may fail. Add entries with: \ |
| 854 | sudo usermod --add-subuids 100000-165535 --add-subgids 100000-165535 $(whoami)" |
| 855 | ); |
| 856 | } |
| 857 | } |
| 858 | |
| 859 | #[cfg(test)] |
| 860 | mod tests { |