nginx-amplify-agent/amplify/agent/common/util/container.py

58 lines
1.8 KiB
Python

# -*- coding: utf-8 -*-
import os
from amplify.agent.common.util import subp
from amplify.agent.common.context import context
__author__ = "Grant Hulegaard"
__copyright__ = "Copyright (C) Nginx, Inc. All rights reserved."
__license__ = ""
__maintainer__ = "Grant Hulegaard"
__email__ = "grant.hulegaard@nginx.com"
def is_docker():
"""
Docker wants you to use their external API when trying to gain information/self-awareness of container state:
https://docs.docker.com/engine/reference/api/docker_remote_api/
The problem is that this API is optional and does not have a standard location from within a container (or rather it
can be configured to listen anywhere). Instead, this check will parse the `/proc` filesystem trying to parse the
docker ID from the output. If we find an ID, we will assume that we are in a docker container.
:return: Bool True if docker ID is found, False otherwise.
"""
try:
stdout, _ = subp.call('cat /proc/self/cgroup | fgrep -e docker | head -n 1 | sed "s/.*docker\/\(.*\)/\\1/"')
docker_id = stdout[0]
return len(docker_id) == 64 and ' ' not in docker_id
except Exception as e:
context.log.error('failed to find docker id due to %s' % e.__class__.__name__)
context.log.debug('additional info:', exc_info=True)
return False
def is_lxc():
"""
LXC sets an environment variable 'container' equal to 'lxc' when inside a continer.
:return: Bool True if 'lxc', False otherwise.
"""
container_env = os.environ.get('container')
return container_env == 'lxc'
CONTAINER_MAP = {
'docker': is_docker,
'lxc': is_lxc
}
def container_environment():
for container_type, check in CONTAINER_MAP.items():
if check():
return container_type