diff options
authorSergey Poznyakoff <gray@gnu.org>2020-12-02 09:56:12 +0200
committerSergey Poznyakoff <gray@gnu.org>2020-12-02 09:56:12 +0200
commit354db96f3bb277341ae4bf8b647d3fd606da7e1f (patch)
parent69431c377e35378306c1d6e87412af32d4b2a4a1 (diff)
Improve documentation
* doc/pies.texi: Improve documentation of variable expansion and the use of pies in docker entry points. * src/pies.h (vlogmsg): New proto. * src/progman.c (prog_start_prologue): Set ws_error member to ensure errors from ${X:?WORD} construct are properly reported.
3 files changed, 164 insertions, 7 deletions
diff --git a/doc/pies.texi b/doc/pies.texi
index 1e9afa3..9871641 100644
--- a/doc/pies.texi
+++ b/doc/pies.texi
@@ -662,6 +662,7 @@ to
In this subsection we assume the reader is sufficiently
acquainted with @command{m4} macro processor.
@flindex pp-setup
The external preprocessor is invoked with @option{-s} flag, instructing
it to include line synchronization information in its output. This
@@ -1306,6 +1307,7 @@ the @code{command} statement are not expanded. If you need to expand
them, there are two @dfn{flags} (@pxref{flags}) at your disposal:
@samp{shell} and @samp{expandenv}.
+@kwindex shell
The @samp{shell} flag instructs @command{pies} to pass the command
line specified by the the @code{command} statement as the argument to
the @samp{/bin/sh -c} command (or another shell, if specified by the
@@ -1317,15 +1319,45 @@ can be eliminated by using the @code{exec} statement before the
command, to instruct the shell to replace itself with the command
without creating a new process.
+ Use this flag if the command you use in the component definition
+is a shell built-in, a pipe or another complex shell statement.
+@kwindex expandenv
Another way to expand environment variables in the command line is by
specifying the @samp{expandenv} flag. This flag instructs
@command{pies} to expand any variable references the same way that the
Bourne shell would expand them, but without actually invoking the
- Which way to choose depends on he command. If it is a shell
-built-in, a pipe or a complex shell command, use @samp{flags shell}.
-Otherwise, you'd be better off using @samp{flags expandenv}.
+ A variable reference has the form @samp{$@var{variable}} or
+@samp{$@{@var{variable}@}}, where @var{variable} is the variable
+name. The two forms are entirely equivalent. The form with curly
+braces is normally used if the variable name is immediately followed
+by an alphanumeric symbol, which will otherwise be considered part of it.
+This form also allows for specifying the action to take if the
+variable is undefined or expands to an empty value:
+@table @asis
+@item $@{@var{variable}:-@var{word}@}
+@dfn{Use Default Values}. If @var{variable} is unset or null, the expansion
+of @var{word} is substituted. Otherwise, the value of @var{variable} is
+@item $@{@var{variable}:=@var{word}@}
+@dfn{Assign Default Values}. If @var{variable} is unset or null, the
+expansion of @var{word} is assigned to variable. The value of
+@var{variable} is then substituted.
+@item $@{@var{variable}:?@var{word}@}
+@dfn{Display Error if Null or Unset}. If @var{variable} is null or unset,
+the expansion of @var{word} (or a message to that effect if @var{word} is
+not present) is output to the current logging channel. Otherwise, the
+value of @var{variable} is substituted.
+@item $@{@var{variable}:+@var{word}@}
+@dfn{Use Alternate Value}. If @var{variable} is null or unset, nothing is
+substituted, otherwise the expansion of @var{word} is substituted.
+@end table
When the two flags are used together, the preference is given to
@samp{shell}, and a warning message to that effect is issued.
@@ -3868,7 +3900,7 @@ Unset environment variable @var{var}.
@node Docker Entrypoint
@chapter Using Pies as Entrypoint for Docker Container
+@cindex docker
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,
@@ -3880,7 +3912,120 @@ 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.
+the case. The option, however, is still retained.
+The following @file{Dockerfile} fragment illustrates how to configure
+@command{pies} to be run from a container:
+COPY pies.conf /etc
+ENTRYPOINT [ "/usr/sbin/pies", "--foreground", "--stderr" ]
+@end example
+It is supposed, of course, that the configuration file
+@file{pies.conf} is available in the same directory as
+It is a common practice to supply configuration settings via the
+environment variables. To implement it in @file{pies.conf}, use
+either @code{expandenv} or @code{shell} flag (@pxref{Early Environment
+Expansion}). For example:
+ flags expandenv;
+ command "syslogd -n -R $LOGHOST";
+@end example
+This will expand the environment variable @env{LOGHOST} and pass its
+value as one of the arguments to @command{syslog}. The usual shell
+syntax is supported. For example, to provide a default value for the
+@option{-R} option above (in case @env{LOGHOST} is empty or
+undefined), use:
+ flags expandenv;
+ command "syslogd -n -R $@{LOGHOST:-}";
+@end example
+Configuration preprocessing (@pxref{Preprocessor}) can be used to
+conditionally enable parts of the @file{pies.conf} file, depending
+on the value of an environment variable. The technique described
+below assumes that you use GNU @command{m4} as preprocessor.
+Define the following two M4 macros:
+@deffn {M4 macro} CF_WITH_ENVAR @var{name} @var{text}
+Expands the environment variable @var{name} within @var{text}.
+The macro does so by temporarily redefining the symbol @var{name} to
+the value of the environment variable @var{name} and expanding
+The definition of the macro is:
+`m4_pushdef(`$1',m4_esyscmd(printf "$`$1'"))m4_dnl
+@end example
+This macro allows you to use environment expansion where it is not
+normally supported. Consider, for example, this fragment:
+component @{
+ ...
+@end example
+If you set @code{WORKDIR=/var/wd} prior to invoking @command{pies}, it
+will actually expand to
+component @{
+ chdir "/var/wd";
+ ...
+@end example
+@xref{Actions Before Startup, chdir}, for details about the
+@code{chdir} statement.
+@end deffn
+@deffn {M4 macro} CF_IF_ENVAR @var{name} @var{if-set} @var{if-unset}
+If the environment variable @var{name} is defined and has a non-empty
+value, expand @var{if-set}, otherwise expand @var{if-unset}. Expand
+each occurrence of @var{name} in @var{if-set} to the actual value of
+the environment variable.
+Following is the definition of this macro:
+@end example
+This macro makes it possible to conditionally enable configuration
+file fragments depending on whether some environment variable is
+defined. E.g.:
+component logger @{
+ command "syslogd -n -R LOGHOST;
+@end example
+@end deffn
+Place both macros in a single file and include it at the top of your
+@file{pies.conf} using the @code{m4_include} command. Alternatively,
+you can place them in the @file{pp-setup} file (@pxref{pp-setup}),
+in which case they will be included automatically.
@node Configuration Examples
@chapter Configuration Examples
diff --git a/src/pies.h b/src/pies.h
index ffccecd..f2aa5ef 100644
--- a/src/pies.h
+++ b/src/pies.h
@@ -522,6 +522,7 @@ void diag_setup (int flags);
void diagmsg (int logf, int prio, const char *fmt, ...)
+void vlogmsg (int prio, const char *fmt, va_list ap);
void logmsg (int prio, const char *fmt, ...) PIES_PRINTFLIKE(2,3);
void logmsg_printf (int prio, const char *fmt, ...) PIES_PRINTFLIKE(2,3);
void logmsg_vprintf (int prio, const char *fmt, va_list ap);
diff --git a/src/progman.c b/src/progman.c
index 1cd5f9d..22482ae 100644
--- a/src/progman.c
+++ b/src/progman.c
@@ -808,6 +808,16 @@ prog_open_socket (struct prog *prog)
static void
+progman_ws_error (const char *fmt, ...)
+ va_list ap;
+ va_start (ap, fmt);
+ vlogmsg (LOG_ERR, fmt, ap);
+ va_end (ap);
+static void
prog_start_prologue (struct prog *prog)
if (prog->v.p.comp->dir)
@@ -848,8 +858,9 @@ prog_start_prologue (struct prog *prog)
size_t argc;
ws.ws_env = (const char **) environ_ptr (prog->v.p.env);
+ ws.ws_error = progman_ws_error;
if (wordsplit (prog->v.p.comp->command, &ws,
logmsg (LOG_ERR, _("%s: can't split command line: %s"),
prog_tag (prog), wordsplit_strerror (&ws));

Return to:

Send suggestions and report system problems to the System administrator.