From 1e3a79ce83847517691999e100490f5166eb6429 Mon Sep 17 00:00:00 2001 From: "W. Trevor King" Date: Wed, 12 Mar 2014 11:46:03 -0700 Subject: [PATCH] gentoo-syslog/Dockerfile.template: Add tail-syslog (and other tweaks) The main change here is a new tail-syslog script that traps SIGTERM and shuts down running OpenRC processes (using 'rc shutdown'). This gives us clean shutdowns for 'docker stop' and friends, which makes 'docker restart' and host reboots more reliable. The tail-syslog script is not the most elegant solution. In fact, rc(8) suggests: There are some special runlevels that you should be aware of: ... shutdown Changes to the shutdown runlevel and then halts the host. You should not call any of these runlevels yourself. Instead you should use init(8) and shutdown(8) and let them call these special runlevels. Indead, using 'CMD /sbin/init' seems to work fine, but I can't figure out how to get the logs out via 'docker logs'. I tried a number of things, including RUN sed -i 's|^\([^#].*/sbin/agetty.*\)|#\1|' /etc/inittab RUN echo 'log1:12345:respawn:/usr/bin/tail -F /var/log/messages >/dev/console' >> /etc/inittab but none of my attempts along those lines worked. You could work around this by volume-mounting a host directory to the container's /var/log, or by configuring syslog-ng to forward logs to a remote destination with something like: RUN sed -i 's/^\(destination messages\).*;$/\1 { tcp("logs.example.net" port(514) };/' /etc/syslog-ng/syslog-ng.conf But we don't have a central syslog instance to forward to, and I like 'docker logs' ;). So that nixed the /sbin/init approach, and I started looking at signal trapping in a shell script [1]. When I tried to use 'shutdown -h now' in place of 'rc shutdown', I got log messages like: Mar 12 18:29:14 f50a7b4bd8c9 logger: trapped SIGTERM, shutting down Mar 12 18:29:14 f50a7b4bd8c9 shutdown[272]: shutting down for system halt shutdown: /dev/initctl: No such file or directory init: /dev/initctl: No such file or directory because /sbin/init (which creates /dev/initctl) was not running). Using 'rc shutdown' directly avoids that problem. Also in this commit: * Add an initial ^ to the console_all sed line, which just makes explicit the fact that I'm matching from the beginning of the line. * Enable boot logging to /var/log/rc.log, in case someone actually does run /sbin/init. [1]: 'trap' is in POSIX.1-2008 (IEEE Std 1003.1, 2013 Edition) http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_28 --- gentoo-syslog/Dockerfile.template | 10 ++++++-- gentoo-syslog/tail-syslog.sh | 41 +++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 2 deletions(-) create mode 100755 gentoo-syslog/tail-syslog.sh diff --git a/gentoo-syslog/Dockerfile.template b/gentoo-syslog/Dockerfile.template index 7f5ee25..193ea93 100644 --- a/gentoo-syslog/Dockerfile.template +++ b/gentoo-syslog/Dockerfile.template @@ -1,4 +1,4 @@ -# Copyright (C) 2013 W. Trevor King +# Copyright (C) 2013-2014 W. Trevor King # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions are met: @@ -28,6 +28,12 @@ MAINTAINER ${MAINTAINER} RUN emerge -v sys-process/vixie-cron app-admin/syslog-ng app-admin/logrotate RUN rc-update add syslog-ng default RUN rc-update add vixie-cron default +ADD tail-syslog.sh /usr/bin/tail-syslog # Disable logging to tty12 -RUN sed -i 's/\([^#].*console_all.*\)/#\1/' /etc/syslog-ng/syslog-ng.conf +RUN sed -i 's/^\([^#].*console_all.*\)/#\1/' /etc/syslog-ng/syslog-ng.conf + +# Log boot process to /var/log/rc.log +RUN sed -i 's/^#\(rc_logger="YES"\)$/\1/' /etc/rc.conf + +CMD rc default && exec tail-syslog diff --git a/gentoo-syslog/tail-syslog.sh b/gentoo-syslog/tail-syslog.sh new file mode 100755 index 0000000..0729a04 --- /dev/null +++ b/gentoo-syslog/tail-syslog.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# +# Copyright (C) 2014 W. Trevor King +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +# Tail syslog, trapping SIGTERM to trigger a clean container shutdown + +tail -F /var/log/messages & +pid="$!" + +trap " + trap '' TERM; + logger 'trapped SIGTERM, shutting down'; + rc shutdown; + kill '${pid}'; + wait '${pid}'; + exit + " TERM + +wait "${pid}" -- 2.26.2