Skip to content
This repository was archived by the owner on Jul 2, 2024. It is now read-only.

Commit 738d959

Browse files
committed
#695: Adds feature to self-destruct a container after a (1 hour default) timeout.
1 parent a02576c commit 738d959

File tree

12 files changed

+156
-2
lines changed

12 files changed

+156
-2
lines changed

Diff for: .env.example

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
SSH_AUTHORIZED_KEYS=
2+
SSH_AUTOSTART_REAPER=false
23
SSH_AUTOSTART_SSHD=true
34
SSH_AUTOSTART_SSHD_BOOTSTRAP=true
45
SSH_CHROOT_DIRECTORY=%h
56
SSH_INHERIT_ENVIRONMENT=false
67
SSH_PASSWORD_AUTHENTICATION=false
8+
SSH_REAPER_TIMEOUT=3600
79
SSH_SUDO=ALL=(ALL) ALL
810
SSH_TIMEZONE=UTC
911
SSH_USER=app-admin
@@ -13,4 +15,4 @@ SSH_USER_ID=500:500
1315
SSH_USER_PASSWORD=
1416
SSH_USER_PASSWORD_HASHED=false
1517
SSH_USER_PRIVATE_KEY=
16-
SSH_USER_SHELL=/bin/bash
18+
SSH_USER_SHELL=/bin/bash

Diff for: CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ Summary of release changes for Version 2 - CentOS-7
1515
- Adds `inspect`, `reload` and `top` Makefile targets.
1616
- Adds improved lock/state file implementation in bootstrap and wrapper scripts.
1717
- Adds improved `clean` Makefile target; includes exited containers and dangling images.
18+
- Adds feature to optionally exit the container after a specified timout period.
19+
- Adds `SSH_AUTOSTART_REAPER` to control startup of `reaper`.
20+
- Adds `SSH_REAPER_TIMEOUT` with a default value of 3600 seconds (i.e 1 hour).
1821
- Fixes port incrementation failures when installing systemd units via `scmi`.
1922
- Fixes etcd port registration failures when installing systemd units via `scmi` with the `--register` option.
2023
- Fixes binary paths in systemd unit files for compatibility with both EL and Ubuntu hosts.

Diff for: Dockerfile

+5-1
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@ RUN rpm --rebuilddb \
2828
openssl-1.0.2k-16.el7 \
2929
python-setuptools-0.9.8-7.el7 \
3030
sudo-1.8.23-3.el7 \
31+
sysvinit-tools-2.88-14.dsf.el7 \
3132
yum-plugin-versionlock-1.1.31-50.el7 \
3233
&& yum versionlock add \
3334
openssh \
3435
openssh-server \
3536
openssh-clients \
3637
python-setuptools \
3738
sudo \
39+
sysvinit-tools \
3840
yum-plugin-versionlock \
3941
&& yum clean all \
4042
&& easy_install \
@@ -83,7 +85,7 @@ RUN ln -sf \
8385
&& chmod 644 \
8486
/etc/{supervisord.conf,supervisord.d/sshd-{bootstrap,wrapper}.conf} \
8587
&& chmod 700 \
86-
/usr/{bin/healthcheck,sbin/{scmi,sshd-{bootstrap,wrapper}}}
88+
/usr/{bin/healthcheck,sbin/{reaper,scmi,sshd-{bootstrap,wrapper}}}
8789

8890
EXPOSE 22
8991

@@ -92,12 +94,14 @@ EXPOSE 22
9294
# ------------------------------------------------------------------------------
9395
ENV \
9496
SSH_AUTHORIZED_KEYS="" \
97+
SSH_AUTOSTART_REAPER="false" \
9598
SSH_AUTOSTART_SSHD="true" \
9699
SSH_AUTOSTART_SSHD_BOOTSTRAP="true" \
97100
SSH_AUTOSTART_SUPERVISOR_STDOUT="false" \
98101
SSH_CHROOT_DIRECTORY="%h" \
99102
SSH_INHERIT_ENVIRONMENT="false" \
100103
SSH_PASSWORD_AUTHENTICATION="false" \
104+
SSH_REAPER_TIMEOUT="3600" \
101105
SSH_SUDO="ALL=(ALL) ALL" \
102106
SSH_TIMEZONE="UTC" \
103107
SSH_USER="app-admin" \

Diff for: default.mk

+2
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,14 @@ define DOCKER_CONTAINER_PARAMETERS
4242
--name $(DOCKER_NAME) \
4343
--restart $(DOCKER_RESTART_POLICY) \
4444
--env "SSH_AUTHORIZED_KEYS=$(SSH_AUTHORIZED_KEYS)" \
45+
--env "SSH_AUTOSTART_REAPER=$(SSH_AUTOSTART_REAPER)" \
4546
--env "SSH_AUTOSTART_SSHD=$(SSH_AUTOSTART_SSHD)" \
4647
--env "SSH_AUTOSTART_SSHD_BOOTSTRAP=$(SSH_AUTOSTART_SSHD_BOOTSTRAP)" \
4748
--env "SSH_AUTOSTART_SUPERVISOR_STDOUT=$(SSH_AUTOSTART_SUPERVISOR_STDOUT)" \
4849
--env "SSH_CHROOT_DIRECTORY=$(SSH_CHROOT_DIRECTORY)" \
4950
--env "SSH_INHERIT_ENVIRONMENT=$(SSH_INHERIT_ENVIRONMENT)" \
5051
--env "SSH_PASSWORD_AUTHENTICATION=$(SSH_PASSWORD_AUTHENTICATION)" \
52+
--env "SSH_REAPER_TIMEOUT=$(SSH_REAPER_TIMEOUT)" \
5153
--env "SSH_SUDO=$(SSH_SUDO)" \
5254
--env "SSH_TIMEZONE=$(SSH_TIMEZONE)" \
5355
--env "SSH_USER=$(SSH_USER)" \

Diff for: docker-compose.yml

+2
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,13 @@ services:
2929
dockerfile: "Dockerfile"
3030
environment:
3131
SSH_AUTHORIZED_KEYS: "${SSH_AUTHORIZED_KEYS}"
32+
SSH_AUTOSTART_REAPER: "${SSH_AUTOSTART_REAPER}"
3233
SSH_AUTOSTART_SSHD: "${SSH_AUTOSTART_SSHD}"
3334
SSH_AUTOSTART_SSHD_BOOTSTRAP: "${SSH_AUTOSTART_SSHD_BOOTSTRAP}"
3435
SSH_CHROOT_DIRECTORY: "${SSH_CHROOT_DIRECTORY}"
3536
SSH_INHERIT_ENVIRONMENT: "${SSH_INHERIT_ENVIRONMENT}"
3637
SSH_PASSWORD_AUTHENTICATION: "${SSH_PASSWORD_AUTHENTICATION}"
38+
SSH_REAPER_TIMEOUT: "${SSH_REAPER_TIMEOUT}"
3739
SSH_SUDO: "${SSH_SUDO}"
3840
SSH_TIMEZONE: "${SSH_TIMEZONE}"
3941
SSH_USER: "${SSH_USER}"

Diff for: environment.mk

+2
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ STARTUP_TIME ?= 2
2424
# Application container configuration
2525
# ------------------------------------------------------------------------------
2626
SSH_AUTHORIZED_KEYS ?=
27+
SSH_AUTOSTART_REAPER ?= false
2728
SSH_AUTOSTART_SSHD ?= true
2829
SSH_AUTOSTART_SSHD_BOOTSTRAP ?= true
2930
SSH_AUTOSTART_SUPERVISOR_STDOUT ?= false
3031
SSH_CHROOT_DIRECTORY ?= %h
3132
SSH_INHERIT_ENVIRONMENT ?= false
3233
SSH_PASSWORD_AUTHENTICATION ?= false
34+
SSH_REAPER_TIMEOUT ?= 3600
3335
SSH_SUDO ?= ALL=(ALL) ALL
3436
SSH_TIMEZONE ?= UTC
3537
SSH_USER ?= app-admin

Diff for: src/etc/supervisord.d/01-reaper.conf

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[program:reaper]
2+
autorestart = false
3+
autostart = %(ENV_SSH_AUTOSTART_REAPER)s
4+
command = /usr/sbin/reaper --verbose
5+
priority = 1
6+
startsecs = 0
7+
stderr_logfile = /dev/stderr
8+
stderr_logfile_maxbytes = 0
9+
stdout_logfile = /dev/stdout
10+
stdout_logfile_maxbytes = 0

Diff for: src/etc/systemd/system/[email protected]

+4
Original file line numberDiff line numberDiff line change
@@ -57,12 +57,14 @@ Environment="DOCKER_IMAGE_TAG={{RELEASE_VERSION}}"
5757
Environment="DOCKER_PORT_MAP_TCP_22=2020"
5858
Environment="DOCKER_USER=jdeathe"
5959
Environment="SSH_AUTHORIZED_KEYS="
60+
Environment="SSH_AUTOSTART_REAPER=false"
6061
Environment="SSH_AUTOSTART_SSHD=true"
6162
Environment="SSH_AUTOSTART_SSHD_BOOTSTRAP=true"
6263
Environment="SSH_AUTOSTART_SUPERVISOR_STDOUT=false"
6364
Environment="SSH_CHROOT_DIRECTORY=%%h"
6465
Environment="SSH_INHERIT_ENVIRONMENT=false"
6566
Environment="SSH_PASSWORD_AUTHENTICATION=false"
67+
Environment="SSH_REAPER_TIMEOUT=3600"
6668
Environment="SSH_SUDO=ALL=(ALL) ALL"
6769
Environment="SSH_TIMEZONE=UTC"
6870
Environment="SSH_USER=app-admin"
@@ -130,12 +132,14 @@ ExecStart=/bin/bash -c \
130132
"exec /usr/bin/docker run \
131133
--name %p.%i \
132134
--env \"SSH_AUTHORIZED_KEYS=${SSH_AUTHORIZED_KEYS}\" \
135+
--env \"SSH_AUTOSTART_REAPER=${SSH_AUTOSTART_REAPER}\" \
133136
--env \"SSH_AUTOSTART_SSHD=${SSH_AUTOSTART_SSHD}\" \
134137
--env \"SSH_AUTOSTART_SSHD_BOOTSTRAP=${SSH_AUTOSTART_SSHD_BOOTSTRAP}\" \
135138
--env \"SSH_AUTOSTART_SUPERVISOR_STDOUT=${SSH_AUTOSTART_SUPERVISOR_STDOUT}\" \
136139
--env \"SSH_CHROOT_DIRECTORY=${SSH_CHROOT_DIRECTORY}\" \
137140
--env \"SSH_INHERIT_ENVIRONMENT=${SSH_INHERIT_ENVIRONMENT}\" \
138141
--env \"SSH_PASSWORD_AUTHENTICATION=${SSH_PASSWORD_AUTHENTICATION}\" \
142+
--env \"SSH_REAPER_TIMEOUT=${SSH_REAPER_TIMEOUT}\" \
139143
--env \"SSH_SUDO=${SSH_SUDO}\" \
140144
--env \"SSH_TIMEZONE=${SSH_TIMEZONE}\" \
141145
--env \"SSH_USER=${SSH_USER}\" \

Diff for: src/opt/scmi/default.sh

+2
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,14 @@ fi
4747
DOCKER_CONTAINER_PARAMETERS="--name ${DOCKER_NAME} \
4848
--restart ${DOCKER_RESTART_POLICY} \
4949
--env \"SSH_AUTHORIZED_KEYS=${SSH_AUTHORIZED_KEYS}\" \
50+
--env \"SSH_AUTOSTART_REAPER=${SSH_AUTOSTART_REAPER}\" \
5051
--env \"SSH_AUTOSTART_SSHD=${SSH_AUTOSTART_SSHD}\" \
5152
--env \"SSH_AUTOSTART_SSHD_BOOTSTRAP=${SSH_AUTOSTART_SSHD_BOOTSTRAP}\" \
5253
--env \"SSH_AUTOSTART_SUPERVISOR_STDOUT=${SSH_AUTOSTART_SUPERVISOR_STDOUT}\" \
5354
--env \"SSH_CHROOT_DIRECTORY=${SSH_CHROOT_DIRECTORY}\" \
5455
--env \"SSH_INHERIT_ENVIRONMENT=${SSH_INHERIT_ENVIRONMENT}\" \
5556
--env \"SSH_PASSWORD_AUTHENTICATION=${SSH_PASSWORD_AUTHENTICATION}\" \
57+
--env \"SSH_REAPER_TIMEOUT=${SSH_REAPER_TIMEOUT}\" \
5658
--env \"SSH_SUDO=${SSH_SUDO}\" \
5759
--env \"SSH_TIMEZONE=${SSH_TIMEZONE}\" \
5860
--env \"SSH_USER=${SSH_USER}\" \

Diff for: src/opt/scmi/environment.sh

+2
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,14 @@ STARTUP_TIME="${STARTUP_TIME:-2}"
2525
# Application container configuration
2626
# ------------------------------------------------------------------------------
2727
SSH_AUTHORIZED_KEYS="${SSH_AUTHORIZED_KEYS:-}"
28+
SSH_AUTOSTART_REAPER="${SSH_AUTOSTART_REAPER:-false}"
2829
SSH_AUTOSTART_SSHD="${SSH_AUTOSTART_SSHD:-true}"
2930
SSH_AUTOSTART_SSHD_BOOTSTRAP="${SSH_AUTOSTART_SSHD_BOOTSTRAP:-true}"
3031
SSH_AUTOSTART_SUPERVISOR_STDOUT="${SSH_AUTOSTART_SUPERVISOR_STDOUT:-false}"
3132
SSH_CHROOT_DIRECTORY="${SSH_CHROOT_DIRECTORY:-%h}"
3233
SSH_INHERIT_ENVIRONMENT="${SSH_INHERIT_ENVIRONMENT:-false}"
3334
SSH_PASSWORD_AUTHENTICATION="${SSH_PASSWORD_AUTHENTICATION:-false}"
35+
SSH_REAPER_TIMEOUT="${SSH_REAPER_TIMEOUT:-3600}"
3436
SSH_SUDO="${SSH_SUDO:-ALL=(ALL) ALL}"
3537
SSH_TIMEZONE="${SSH_TIMEZONE:-UTC}"
3638
SSH_USER="${SSH_USER:-app-admin}"

Diff for: src/opt/scmi/service-unit.sh

+2
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,14 @@ readonly SERVICE_UNIT_ENVIRONMENT_KEYS="
77
DOCKER_IMAGE_TAG
88
DOCKER_PORT_MAP_TCP_22
99
SSH_AUTHORIZED_KEYS
10+
SSH_AUTOSTART_REAPER
1011
SSH_AUTOSTART_SSHD
1112
SSH_AUTOSTART_SSHD_BOOTSTRAP
1213
SSH_AUTOSTART_SUPERVISOR_STDOUT
1314
SSH_CHROOT_DIRECTORY
1415
SSH_INHERIT_ENVIRONMENT
1516
SSH_PASSWORD_AUTHENTICATION
17+
SSH_REAPER_TIMEOUT
1618
SSH_SUDO
1719
SSH_TIMEZONE
1820
SSH_USER

Diff for: src/usr/sbin/reaper

+119
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#!/usr/bin/env bash
2+
3+
set -e
4+
5+
function __get_ssh_reaper_timeout ()
6+
{
7+
local -r default_value="${1:-3600}"
8+
9+
local value="${SSH_REAPER_TIMEOUT}"
10+
11+
if ! __is_valid_ssh_reaper_timeout "${value}"
12+
then
13+
value="${default_value}"
14+
fi
15+
16+
printf -- '%s' "${value}"
17+
}
18+
19+
function __is_valid_positive_integer ()
20+
{
21+
local -r positive_integer='^[0-9]+$'
22+
local -r value="${1}"
23+
24+
if [[ ${value} =~ ${positive_integer} ]]
25+
then
26+
return 0
27+
fi
28+
29+
return 1
30+
}
31+
32+
function __is_valid_ssh_reaper_timeout ()
33+
{
34+
__is_valid_positive_integer "${@}"
35+
}
36+
37+
function __reap ()
38+
{
39+
kill -"${signal:-TERM}" "${pid:-1}"
40+
}
41+
42+
function main ()
43+
{
44+
local -r warning_timeout="30"
45+
46+
local pid="1"
47+
local signal="TERM"
48+
local timeout="$(
49+
__get_ssh_reaper_timeout
50+
)"
51+
local verbose="false"
52+
53+
while [[ "${#}" -gt 0 ]]
54+
do
55+
case "${1}" in
56+
-p)
57+
pid="${2}"
58+
shift 2 || break
59+
;;
60+
--pid)
61+
pid="${1#*=}"
62+
shift 1
63+
;;
64+
-s)
65+
signal="${2}"
66+
shift 2 || break
67+
;;
68+
--signal)
69+
signal="${1#*=}"
70+
shift 1
71+
;;
72+
-v|--verbose)
73+
verbose="true"
74+
shift 1
75+
;;
76+
esac
77+
done
78+
79+
if (( timeout > 0 ))
80+
then
81+
trap __reap \
82+
EXIT INT TERM
83+
84+
if (( timeout > warning_timeout ))
85+
then
86+
(( timeout -= warning_timeout ))
87+
else
88+
warning_timeout="0"
89+
fi
90+
91+
if coproc read -t "${timeout}"
92+
then
93+
wait "${!}" || :
94+
95+
if (( warning_timeout > 0 ))
96+
then
97+
wall "Session expired - exiting in ${warning_timeout} seconds."
98+
99+
if coproc read -t "${warning_timeout}"
100+
then
101+
wait "${!}" || :
102+
fi
103+
else
104+
wall "Session expired."
105+
fi
106+
fi
107+
108+
if [[ ${verbose} == true ]]
109+
then
110+
printf -- \
111+
'INFO: %s expiring session.\n' \
112+
"${0##*/}"
113+
fi
114+
fi
115+
116+
exit 0
117+
}
118+
119+
main "${@}"

0 commit comments

Comments
 (0)