diff options
-rw-r--r-- | NEWS | 8 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | doc/pies.texi | 29 | ||||
-rw-r--r-- | lib/envop.c | 1 | ||||
-rw-r--r-- | src/pies.c | 75 | ||||
-rw-r--r-- | src/utmp.c | 41 |
6 files changed, 123 insertions, 33 deletions
@@ -1,13 +1,17 @@ -GNU Pies NEWS -- history of user-visible changes. 2020-10-12 +GNU Pies NEWS -- history of user-visible changes. 2020-10-17 See the end of file for copying conditions. Please send Pies bug reports to <bug-pies@gnu.org> or <bug-pies@gnu.org.ua> -Version 1.4.90 (git) +Version 1.4.91 (git) + +* Detect if pies is started from docker. + +This makes the --no-init option unnecessary. * When running with PID 1, install SIGCHLD handler early This is to make sure the exited preprocessor command is cleaned up properly. diff --git a/configure.ac b/configure.ac index 65dd50c..d890d76 100644 --- a/configure.ac +++ b/configure.ac @@ -12,13 +12,13 @@ # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. AC_PREREQ([2.63]) -AC_INIT([GNU Pies], [1.4.90], [bug-pies@gnu.org.ua]) +AC_INIT([GNU Pies], [1.4.91], [bug-pies@gnu.org.ua]) AC_CONFIG_SRCDIR([src/pies.h]) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([1.11 gnits tar-ustar dist-bzip2 std-options silent-rules]) # Enable silent rules by default: diff --git a/doc/pies.texi b/doc/pies.texi index 4bd2f8f..5a1bf72 100644 --- a/doc/pies.texi +++ b/doc/pies.texi @@ -80,20 +80,21 @@ documents @command{pies} Version @value{VERSION}. * Intro:: Introduction to Process Management with @command{Pies}. * Dependencies:: Inter-process dependencies. * Configuration:: Configuration Files of Various Syntaxes. * Pies Debugging:: Debugging @command{Pies}. * piesctl:: Communication with Running @command{pies} Instances. * Init Process:: Using @command{Pies} as Parent of All Processes. +* Docker Entrypoint:: Using @command{Pies} as Entrypoint in Docker Container. * Configuration Examples:: Examples of Configuration Files. * Command Line Usage:: * Invocation:: * Reporting Bugs:: Appendices -* inetd.conf:: @file{Inetd.conf} Format. +* inetd configuration:: @file{Inetd.conf} Format. * User-Group ACLs:: * Copying This Manual:: The GNU Free Documentation License. * Concept Index:: Index of Concepts. @detailmenu --- The Detailed Node Listing --- @@ -892,13 +893,13 @@ component X @{ @kwindex wait @item wait This flag is valid only for @samp{inetd} components. It has the same meaning as @samp{wait} in @file{inetd.conf} file, i.e. it tells @command{pies} to wait for the server program to -return. @xref{inetd.conf, wait}. +return. @xref{inetd configuration, wait}. @kwindex tcpmux @item tcpmux This is a @acronym{TCPMUX} component. @xref{TCPMUX}. @kwindex tcpmuxplus @@ -3821,12 +3822,28 @@ will be sent the SIGKILL signal. The default value is 5 seconds. Define environment variable @var{var} as having value @var{value}. @item -e @var{var} Unset environment variable @var{var}. @end table +@node Docker Entrypoint +@chapter Using Pies as Entrypoint for Docker Container + +Another use for @command{pies} is as an entrypoint in a docker +container. This is similar to the @command{init} mode described in +the previous chapter in that @command{pies} runs with PID 1. However, +in this case @command{pies} uses its regular configuration file. + +@opindex --no-init +When started with PID 1 from a docker container, @command{pies} +detects the fact automatically and switches to the entrypoint mode. +Up to version 1.4.90, automatical detection was not implemented, and +it was necessary to use the @option{--no-init} option to discern +between the @code{entrypoint} and @code{init} modes. This is no longer +necessary. The option, however, is still retained. + @node Configuration Examples @chapter Configuration Examples In this section we provide several examples of working @command{pies} configuration files. @menu @@ -4145,15 +4162,14 @@ of @var{level}. @opsummary{dump-depmap} @item --dump-depmap Dump dependency map. @xref{dump-depmap}. @opsummary{no-init} @item --no-init -Don't assume @dfn{init mode} (@pxref{Init Process} if running with PID -1. This option is useful if you intend to run @command{pies} as a -process manager in a docker container. +Don't assume @dfn{init mode} (@pxref{Init Process}) if running with PID +1. @xref{Docker Entrypoint}. @opsummary{trace-depend} @item --trace-depend List dependencies for components named in the command line. Without arguments, dependencies for each component are listed. @xref{trace-depend}. @@ -4295,13 +4311,14 @@ it. The information needed is: @item Run-time configuration (@file{pies.conf} file and the command line options used). @item Detailed description of the bug. @item Conditions under which the bug appears. @end itemize -@node inetd.conf +@node inetd configuration +@anchor{inetd.conf} @appendix @file{Inetd.conf} Format @include inetd.texi @node User-Group ACLs @appendix User-Group ACLs @include usr-acl.texi diff --git a/lib/envop.c b/lib/envop.c index 93bd425..14c3273 100644 --- a/lib/envop.c +++ b/lib/envop.c @@ -14,12 +14,13 @@ You should have received a copy of the GNU General Public License along with GNU Pies. If not, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H # include <config.h> #endif +#include <sys/types.h> #include <stdlib.h> #include <string.h> #include <errno.h> #include <ctype.h> #include "envop.h" #include "wordsplit.h" @@ -2259,13 +2259,72 @@ set_state_file_names (const char *base) { if (!pidfile) pidfile = mkfilename (statedir, base, ".pid"); if (!qotdfile) qotdfile = mkfilename (statedir, base, ".qotd"); } + +/* Return 1 if pies is run from docker and 0 otherwise. */ +static int +is_docker (void) +{ + FILE *fp; + char *id = NULL; + int res; + + fp = fopen ("/proc/self/cgroup", "r"); + if (!fp) + return 0; + res = fscanf (fp, "%*d:%*[^:]:/docker/%ms\n", &id) == 1; + fclose (fp); + free (id); + return res; +} + +/* + * Check if `--no-init' option is present in argv/argc. Return 1 if so, + * 0 otherwise. + */ +static int +no_init_option (int argc, char **argv) +{ + int i; + for (i = 1; i < argc; i++) + { + if (strcmp (argv[i], "--no-init") == 0) + return 1; + } + return 0; +} +/* + * init_detect - detect if we're run as init process. + * + * Pies runs as init process if (1) it has PID 1, (2) is not started as docker + * entrypoint, and (3) the `--no-init' command line option is not given. + * + * The function sets init_process to 1 if pies runs as init process and 0 + * otherwise. + * + * No matter the result, if PID is 1 it installs an early SIGCHLD handler, + * to ensure that the configuration preprocessor (if such is started) will be + * cleaned up properly on exit. + */ +static void +init_detect (int argc, char **argv) +{ + init_process = getpid () == 1; + if (init_process) + { + int s[] = { SIGCHLD }; + setsigvhan (sigchld_early, s, 1); + if (no_init_option (argc, argv) || is_docker ()) + init_process = 0; + } +} + size_t pies_master_argc; char **pies_master_argv; int main (int argc, char **argv) { @@ -2287,28 +2346,14 @@ main (int argc, char **argv) pies_master_argc = argc; pies_master_argv = argv; set_quoting_style (NULL, shell_quoting_style); - init_process = getpid () == 1; - if (init_process) - { - int s[] = { SIGCHLD }; - setsigvhan (sigchld_early, s, 1); - } + init_detect (argc, argv); - for (i = 1; i < argc; i++) - { - if (strcmp (argv[i], "--no-init") == 0) - { - init_process = 0; - break; - } - } - /* Set default logging */ if (SYSVINIT_ACTIVE) { log_facility = LOG_DAEMON; diag_flags = DIAG_TO_STDERR | DIAG_REOPEN_LOG; } @@ -23,16 +23,12 @@ # include <utmpx.h> typedef struct utmpx UTMPX; # if HAVE_UPDWTMPX # define pies_updwtmpx updwtmpx # endif # define GETUTXID getutxid -# undef UTMP_FILE -# define UTMP_FILE UTMPX_FILE -# undef WTMP_FILE -# define WTMP_FILE WTMPX_FILE # if defined HAVE_STRUCT_UTMPX_UT_NAME # define UT_NAME(u) ((u)->ut_name) # elif defined HAVE_STRUCT_UTMPX_UT_USER # define UT_NAME(u) ((u)->ut_user) # endif #else @@ -49,12 +45,39 @@ typedef struct utmp UTMPX; # define GETUTXID getutid # define setutxent setutent # define pututxline pututline # define endutxent endutent #endif +#if !defined(UTMPX_FILE) || !defined(WTMPX_FILE) +# if !defined(UTMP_FILE) || !defined(WTMP_FILE) +# ifndef HAVE_UTMPX_H +# include <utmp.h> +# endif +# if !defined(UTMP_FILE) +# if !defined(_PATH_UTMP) +# error "None of UTMPX_FILE, UTMP_FILE or _PATH_UTMP defined" +# else +# define UTMP_FILE _PATH_UTMP +# endif +# endif +# if !defined(WTMP_FILE) +# if !defined(_PATH_WTMP) +# error "None of WTMPX_FILE, WTMP_FILE or _PATH_WTMP defined" +# else +# define WTMP_FILE _PATH_WTMP +# endif +# endif +# endif +# if !defined(UTMPX_FILE) +# define UTMPX_FILE UTMP_FILE +# endif +# if !defined(WTMPX_FILE) +# define WTMPX_FILE WTMP_FILE +# endif +#endif #ifndef pies_updwtmpx static void pies_updwtmpx (const char *wtmp_file, const UTMPX *ut) { int fd = open (wtmp_file, O_WRONLY|O_APPEND); @@ -108,39 +131,39 @@ void write_wtmpx (int type, const char *user, const char *id, pid_t pid, const char *line) { UTMPX utmp; static int wtmpxreboot = 0; - debug (2, (_("cannot open %s for writing"), WTMP_FILE)); - if (access (WTMP_FILE, W_OK)) + debug (2, (_("cannot open %s for writing"), WTMPX_FILE)); + if (access (WTMPX_FILE, W_OK)) { if (type == BOOT_TIME) wtmpxreboot++; return; } if (wtmpxreboot) { write_wtmpx (BOOT_TIME, "reboot", "~~", 0, "~"); --wtmpxreboot; } fill_utmp (&utmp, type, user, id, pid, line); - pies_updwtmpx (WTMP_FILE, &utmp); + pies_updwtmpx (WTMPX_FILE, &utmp); } void write_utmpx (int type, const char *user, const char *id, pid_t pid, const char *line) { UTMPX utmp; static int utmpreboot = 0; - if (access (UTMP_FILE, W_OK)) + if (access (UTMPX_FILE, W_OK)) { - debug (1, (_("cannot open %s for writing"), UTMP_FILE)); + debug (1, (_("cannot open %s for writing"), UTMPX_FILE)); if (type == BOOT_TIME) utmpreboot++; return; } if (utmpreboot) |