add bundle:docker-engine
This commit is contained in:
parent
729b975b77
commit
4238eeb6d8
7 changed files with 348 additions and 1 deletions
39
bundles/docker-engine/files/check_docker_container
Normal file
39
bundles/docker-engine/files/check_docker_container
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
from json import loads
|
||||||
|
from subprocess import check_output
|
||||||
|
from sys import argv
|
||||||
|
|
||||||
|
try:
|
||||||
|
container_name = argv[1]
|
||||||
|
|
||||||
|
docker_ps = check_output([
|
||||||
|
'docker',
|
||||||
|
'container',
|
||||||
|
'ls',
|
||||||
|
'--all',
|
||||||
|
'--format',
|
||||||
|
'json',
|
||||||
|
'--filter',
|
||||||
|
f'name={container_name}'
|
||||||
|
])
|
||||||
|
|
||||||
|
containers = loads(f"[{','.join([l for l in docker_ps.decode().splitlines() if l])}]")
|
||||||
|
|
||||||
|
if not containers:
|
||||||
|
print(f'CRITICAL: container {container_name} not found!')
|
||||||
|
exit(2)
|
||||||
|
|
||||||
|
if len(containers) > 1:
|
||||||
|
print(f'Found more than one container matching {container_name}!')
|
||||||
|
print(docker_ps)
|
||||||
|
exit(3)
|
||||||
|
|
||||||
|
if containers[0]['State'] != 'running':
|
||||||
|
print(f'WARNING: container {container_name} not "running"')
|
||||||
|
exit(2)
|
||||||
|
|
||||||
|
print(f"OK: {containers[0]['Status']}")
|
||||||
|
except Exception as e:
|
||||||
|
print(repr(e))
|
||||||
|
exit(2)
|
50
bundles/docker-engine/files/docker-wrapper
Normal file
50
bundles/docker-engine/files/docker-wrapper
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
[[ -n "$DEBUG" ]] && set -x
|
||||||
|
|
||||||
|
ACTION="$1"
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
if [[ -z "$ACTION" ]]
|
||||||
|
then
|
||||||
|
echo "Usage: $0 start|stop"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
PUID="$(id -u "docker-${name}")"
|
||||||
|
PGID="$(id -g "docker-${name}")"
|
||||||
|
|
||||||
|
if [ "$ACTION" == "start" ]
|
||||||
|
then
|
||||||
|
docker run -d \
|
||||||
|
--name "${name}" \
|
||||||
|
--env "PUID=$PUID" \
|
||||||
|
--env "PGID=$PGID" \
|
||||||
|
--env "TZ=${timezone}" \
|
||||||
|
% for k, v in sorted(environment.items()):
|
||||||
|
--env "${k}=${v}" \
|
||||||
|
% endfor
|
||||||
|
--network host \
|
||||||
|
% for host_port, container_port in sorted(ports.items()):
|
||||||
|
--expose "127.0.0.1:${host_port}:${container_port}" \
|
||||||
|
% endfor
|
||||||
|
% for host_path, container_path in sorted(volumes.items()):
|
||||||
|
--volume "/var/opt/docker-engine/${name}/${host_path}:${container_path}" \
|
||||||
|
% endfor
|
||||||
|
--restart unless-stopped \
|
||||||
|
"${image}"
|
||||||
|
|
||||||
|
elif [ "$ACTION" == "stop" ]
|
||||||
|
then
|
||||||
|
docker stop "${name}"
|
||||||
|
docker rm "${name}"
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "Unknown action $ACTION"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
% if node.has_bundle('nftables'):
|
||||||
|
systemctl reload nftables
|
||||||
|
% endif
|
14
bundles/docker-engine/files/docker-wrapper.service
Normal file
14
bundles/docker-engine/files/docker-wrapper.service
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
[Unit]
|
||||||
|
Description=docker-engine app ${name}
|
||||||
|
After=network.target
|
||||||
|
Requires=${' '.join(sorted(requires))}
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
WorkingDirectory=/var/opt/docker-engine/${name}/
|
||||||
|
ExecStart=/opt/docker-engine/${name} start
|
||||||
|
ExecStop=/opt/docker-engine/${name} stop
|
||||||
|
Type=simple
|
||||||
|
RemainAfterExit=true
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
99
bundles/docker-engine/items.py
Normal file
99
bundles/docker-engine/items.py
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
from bundlewrap.metadata import metadata_to_json
|
||||||
|
|
||||||
|
deps = {
|
||||||
|
'pkg_apt:docker-ce',
|
||||||
|
'pkg_apt:docker-ce-cli',
|
||||||
|
}
|
||||||
|
|
||||||
|
directories['/opt/docker-engine'] = {
|
||||||
|
'purge': True,
|
||||||
|
}
|
||||||
|
directories['/var/opt/docker-engine'] = {}
|
||||||
|
|
||||||
|
files['/etc/docker/daemon.json'] = {
|
||||||
|
'content': metadata_to_json(node.metadata.get('docker-engine/config')),
|
||||||
|
'triggers': {
|
||||||
|
'svc_systemd:docker:restart',
|
||||||
|
},
|
||||||
|
# install config before installing packages to ensure the config is
|
||||||
|
# applied to the first start as well
|
||||||
|
'before': deps,
|
||||||
|
}
|
||||||
|
|
||||||
|
svc_systemd['docker'] = {
|
||||||
|
'needs': deps,
|
||||||
|
}
|
||||||
|
|
||||||
|
files['/usr/local/share/icinga/plugins/check_docker_container'] = {
|
||||||
|
'mode': '0755',
|
||||||
|
}
|
||||||
|
|
||||||
|
for app, config in node.metadata.get('docker-engine/containers', {}).items():
|
||||||
|
volumes = config.get('volumes', {})
|
||||||
|
|
||||||
|
files[f'/opt/docker-engine/{app}'] = {
|
||||||
|
'source': 'docker-wrapper',
|
||||||
|
'content_type': 'mako',
|
||||||
|
'context': {
|
||||||
|
'environment': config.get('environment', {}),
|
||||||
|
'image': config['image'],
|
||||||
|
'name': app,
|
||||||
|
'ports': config.get('ports', {}),
|
||||||
|
'timezone': node.metadata.get('timezone'),
|
||||||
|
'volumes': volumes,
|
||||||
|
},
|
||||||
|
'mode': '0755',
|
||||||
|
'triggers': {
|
||||||
|
f'svc_systemd:docker-{app}:restart',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
users[f'docker-{app}'] = {
|
||||||
|
'home': f'/var/opt/docker-engine/{app}',
|
||||||
|
'groups': {
|
||||||
|
'docker',
|
||||||
|
},
|
||||||
|
'after': {
|
||||||
|
# provides docker group
|
||||||
|
'pkg_apt:docker-ce',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
files[f'/usr/local/lib/systemd/system/docker-{app}.service'] = {
|
||||||
|
'source': 'docker-wrapper.service',
|
||||||
|
'content_type': 'mako',
|
||||||
|
'context': {
|
||||||
|
'name': app,
|
||||||
|
'requires': {
|
||||||
|
*set(config.get('requires', set())),
|
||||||
|
'docker.service',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'triggers': {
|
||||||
|
'action:systemd-reload',
|
||||||
|
f'svc_systemd:docker-{app}:restart',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
svc_systemd[f'docker-{app}'] = {
|
||||||
|
'needs': {
|
||||||
|
*deps,
|
||||||
|
f'file:/opt/docker-engine/{app}',
|
||||||
|
f'file:/usr/local/lib/systemd/system/docker-{app}.service',
|
||||||
|
f'user:docker-{app}',
|
||||||
|
'svc_systemd:docker',
|
||||||
|
*set(config.get('needs', set())),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for volume in volumes:
|
||||||
|
directories[f'/var/opt/docker-engine/{app}/{volume}'] = {
|
||||||
|
'owner': f'docker-{app}',
|
||||||
|
'group': f'docker-{app}',
|
||||||
|
'needed_by': {
|
||||||
|
f'svc_systemd:docker-{app}',
|
||||||
|
},
|
||||||
|
# don't do anything if the directory exists, docker images
|
||||||
|
# mangle owners
|
||||||
|
'unless': f'test -d /var/opt/docker-engine/{app}/{volume}',
|
||||||
|
}
|
83
bundles/docker-engine/metadata.py
Normal file
83
bundles/docker-engine/metadata.py
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
defaults = {
|
||||||
|
'apt': {
|
||||||
|
'packages': {
|
||||||
|
'docker-ce': {},
|
||||||
|
'docker-ce-cli': {},
|
||||||
|
'docker-compose-plugin': {},
|
||||||
|
},
|
||||||
|
'repos': {
|
||||||
|
'docker': {
|
||||||
|
'items': {
|
||||||
|
'deb https://download.docker.com/linux/debian {os_release} stable',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'backups': {
|
||||||
|
'paths': {
|
||||||
|
'/var/opt/docker-engine',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'hosts': {
|
||||||
|
'entries': {
|
||||||
|
'172.17.0.1': {
|
||||||
|
'host.docker.internal',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'docker-engine': {
|
||||||
|
'config': {
|
||||||
|
'iptables': False,
|
||||||
|
'no-new-privileges': True,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'zfs': {
|
||||||
|
'datasets': {
|
||||||
|
'tank/docker-data': {
|
||||||
|
'mountpoint': '/var/opt/docker-engine',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@metadata_reactor.provides(
|
||||||
|
'icinga2_api/docker-engine/services',
|
||||||
|
)
|
||||||
|
def monitoring(metadata):
|
||||||
|
services = {
|
||||||
|
'DOCKER PROCESS': {
|
||||||
|
'command_on_monitored_host': '/usr/lib/nagios/plugins/check_procs -C dockerd -c 1:',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for app in metadata.get('docker-engine/containers', {}):
|
||||||
|
services[f'DOCKER CONTAINER {app}'] = {
|
||||||
|
'command_on_monitored_host': f'sudo /usr/local/share/icinga/plugins/check_docker_container {app}'
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
'icinga2_api': {
|
||||||
|
'docker-engine': {
|
||||||
|
'services': services,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@metadata_reactor.provides(
|
||||||
|
'zfs/datasets',
|
||||||
|
)
|
||||||
|
def zfs(metadata):
|
||||||
|
datasets = {}
|
||||||
|
|
||||||
|
for app in metadata.get('docker-engine/containers', {}):
|
||||||
|
datasets[f'tank/docker-data/{app}'] = {
|
||||||
|
'mountpoint': f'/var/opt/docker-engine/{app}'
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
'zfs': {
|
||||||
|
'datasets': datasets,
|
||||||
|
},
|
||||||
|
}
|
|
@ -29,7 +29,7 @@ defaults = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if not node.has_bundle('vmhost'):
|
if not node.has_bundle('vmhost') and not node.has_bundle('docker-engine'):
|
||||||
# see comment in bundles/vmhost/items.py
|
# see comment in bundles/vmhost/items.py
|
||||||
defaults['apt']['packages']['iptables'] = {
|
defaults['apt']['packages']['iptables'] = {
|
||||||
'installed': False,
|
'installed': False,
|
||||||
|
|
62
data/apt/files/gpg-keys/docker.asc
Normal file
62
data/apt/files/gpg-keys/docker.asc
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||||
|
|
||||||
|
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
|
||||||
|
YT90qFF93M3v01BbxP+EIY2/9tiIPbrd
|
||||||
|
=0YYh
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
Loading…
Reference in a new issue