mirror of
https://github.com/systemd/systemd.git
synced 2024-11-01 00:51:24 +03:00
virt: detect Docker and Podman containers
Docker doesn't set $container, so it cannot be detected that way. Instead, we check for presence of /.dockerinit, which it creates. Podman does set $container, but some Red Hat images (in particular, Fedora images) override $container to equal "oci". So to correctly detect Podman containers, we check for presence of /run/.containerenv, which is created by Podman and is now the official way to get information about the container from within the container. Fixes https://github.com/systemd/systemd/issues/15393
This commit is contained in:
parent
46a906f414
commit
a4a9a6f7c6
@ -453,6 +453,34 @@ static const char *const container_table[_VIRTUALIZATION_MAX] = {
|
|||||||
|
|
||||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(container, int);
|
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(container, int);
|
||||||
|
|
||||||
|
static int detect_container_files(void) {
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
static const struct {
|
||||||
|
const char *file_path;
|
||||||
|
int id;
|
||||||
|
} container_file_table[] = {
|
||||||
|
/* https://github.com/containers/podman/issues/6192 */
|
||||||
|
/* https://github.com/containers/podman/issues/3586#issuecomment-661918679 */
|
||||||
|
{ "/run/.containerenv", VIRTUALIZATION_PODMAN },
|
||||||
|
/* https://github.com/moby/moby/issues/18355 */
|
||||||
|
/* Docker must be the last in this table, see below. */
|
||||||
|
{ "/.dockerenv", VIRTUALIZATION_DOCKER },
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i = 0; i < ELEMENTSOF(container_file_table); i++) {
|
||||||
|
if (access(container_file_table[i].file_path, F_OK) >= 0)
|
||||||
|
return container_file_table[i].id;
|
||||||
|
|
||||||
|
if (errno != ENOENT)
|
||||||
|
log_debug_errno(errno,
|
||||||
|
"Checking if %s exists failed, ignoring: %m",
|
||||||
|
container_file_table[i].file_path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return VIRTUALIZATION_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
int detect_container(void) {
|
int detect_container(void) {
|
||||||
static thread_local int cached_found = _VIRTUALIZATION_INVALID;
|
static thread_local int cached_found = _VIRTUALIZATION_INVALID;
|
||||||
_cleanup_free_ char *m = NULL, *o = NULL, *p = NULL;
|
_cleanup_free_ char *m = NULL, *o = NULL, *p = NULL;
|
||||||
@ -530,7 +558,7 @@ int detect_container(void) {
|
|||||||
*/
|
*/
|
||||||
e = getenv("container");
|
e = getenv("container");
|
||||||
if (!e)
|
if (!e)
|
||||||
goto none;
|
goto check_files;
|
||||||
if (isempty(e)) {
|
if (isempty(e)) {
|
||||||
r = VIRTUALIZATION_NONE;
|
r = VIRTUALIZATION_NONE;
|
||||||
goto finish;
|
goto finish;
|
||||||
@ -558,12 +586,28 @@ int detect_container(void) {
|
|||||||
if (r < 0) /* This only works if we have CAP_SYS_PTRACE, hence let's better ignore failures here */
|
if (r < 0) /* This only works if we have CAP_SYS_PTRACE, hence let's better ignore failures here */
|
||||||
log_debug_errno(r, "Failed to read $container of PID 1, ignoring: %m");
|
log_debug_errno(r, "Failed to read $container of PID 1, ignoring: %m");
|
||||||
|
|
||||||
none:
|
check_files:
|
||||||
/* If that didn't work, give up, assume no container manager. */
|
/* Check for existence of some well-known files. We only do this after checking
|
||||||
|
* for other specific container managers, otherwise we risk mistaking another
|
||||||
|
* container manager for Docker: the /.dockerenv file could inadvertently end up
|
||||||
|
* in a file system image. */
|
||||||
|
r = detect_container_files();
|
||||||
|
if (r)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
/* If none of that worked, give up, assume no container manager. */
|
||||||
r = VIRTUALIZATION_NONE;
|
r = VIRTUALIZATION_NONE;
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
translate_name:
|
translate_name:
|
||||||
|
if (streq(e, "oci")) {
|
||||||
|
/* Some images hardcode container=oci, but OCI is not a specific container manager.
|
||||||
|
* Try to detect one based on well-known files. */
|
||||||
|
r = detect_container_files();
|
||||||
|
if (!r)
|
||||||
|
r = VIRTUALIZATION_CONTAINER_OTHER;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
r = container_from_string(e);
|
r = container_from_string(e);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
r = VIRTUALIZATION_CONTAINER_OTHER;
|
r = VIRTUALIZATION_CONTAINER_OTHER;
|
||||||
|
Loading…
Reference in New Issue
Block a user