mirror of https://github.com/krallin/tini.git
Merge pull request #60 from krallin/white-label
"White label" when MINIMAL is set
This commit is contained in:
commit
4a92b9e201
10
.travis.yml
10
.travis.yml
|
@ -5,10 +5,10 @@ language: generic
|
|||
|
||||
env:
|
||||
matrix:
|
||||
- CC=gcc ARCH_SUFFIX=amd64 ARCH_NATIVE=1 NO_ARGS=
|
||||
- CC=arm-linux-gnueabihf-gcc ARCH_SUFFIX=armhf ARCH_NATIVE= NO_ARGS=
|
||||
- CC=aarch64-linux-gnu-gcc ARCH_SUFFIX=arm64 ARCH_NATIVE= NO_ARGS=
|
||||
- CC=gcc ARCH_SUFFIX=amd64 ARCH_NATIVE=1 NO_ARGS=1
|
||||
- CC=gcc ARCH_SUFFIX=amd64 ARCH_NATIVE=1 MINIMAL=
|
||||
- CC=arm-linux-gnueabihf-gcc ARCH_SUFFIX=armhf ARCH_NATIVE= MINIMAL=
|
||||
- CC=aarch64-linux-gnu-gcc ARCH_SUFFIX=arm64 ARCH_NATIVE= MINIMAL=
|
||||
- CC=gcc ARCH_SUFFIX=amd64 ARCH_NATIVE=1 MINIMAL=1
|
||||
global:
|
||||
- SIGN_BINARIES=1
|
||||
- secure: "RKF9Z9gLxp6k/xITqn7ma1E9HfpYcDXuJFf4862WeH9EMnK9lDq+TWnGsQfkIlqh8h9goe7U+BvRiTibj9MiD5u7eluLo3dlwsLxPpYtyswYeLeC1wKKdT5LPGAXbRKomvBalRYMI+dDnGIM4w96mHgGGvx2zZXGkiAQhm6fJ3k="
|
||||
|
@ -31,4 +31,4 @@ deploy:
|
|||
on:
|
||||
repo: krallin/tini
|
||||
tags: true
|
||||
condition: '-z "$NO_ARGS"'
|
||||
condition: '-z "$MINIMAL"'
|
||||
|
|
|
@ -3,14 +3,14 @@ project (tini C)
|
|||
|
||||
# Config
|
||||
set (tini_VERSION_MAJOR 0)
|
||||
set (tini_VERSION_MINOR 12)
|
||||
set (tini_VERSION_MINOR 13)
|
||||
set (tini_VERSION_PATCH 0)
|
||||
|
||||
# Build options
|
||||
option(NO_ARGS "Disable argument parsing" OFF)
|
||||
option(MINIMAL "Disable argument parsing and verbose output" OFF)
|
||||
|
||||
if(NO_ARGS)
|
||||
add_definitions(-DTINI_NO_ARGS=1)
|
||||
if(MINIMAL)
|
||||
add_definitions(-DTINI_MINIMAL=1)
|
||||
endif()
|
||||
|
||||
# Extract git version and dirty-ness
|
||||
|
|
22
README.md
22
README.md
|
@ -37,7 +37,7 @@ In Docker, you will want to use an entrypoint so you don't have to remember
|
|||
to manually invoke Tini:
|
||||
|
||||
# Add Tini
|
||||
ENV TINI_VERSION v0.12.0
|
||||
ENV TINI_VERSION v0.13.0
|
||||
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
|
||||
RUN chmod +x /tini
|
||||
ENTRYPOINT ["/tini", "--"]
|
||||
|
@ -63,7 +63,7 @@ The `tini` and `tini-static` binaries are signed using the key `595E85A6B1B4779E
|
|||
You can verify their signatures using `gpg` (which you may install using
|
||||
your package manager):
|
||||
|
||||
ENV TINI_VERSION v0.12.0
|
||||
ENV TINI_VERSION v0.13.0
|
||||
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini /tini
|
||||
ADD https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini.asc /tini.asc
|
||||
RUN gpg --keyserver ha.pool.sks-keyservers.net --recv-keys 595E85A6B1B4779EA4DAAEC70B588DFF0527A9B7 \
|
||||
|
@ -214,18 +214,20 @@ Maintainer:
|
|||
|
||||
Contributors:
|
||||
|
||||
+ [Tianon Gravi][21]
|
||||
+ [David Wragg][22]
|
||||
+ [Tianon Gravi][30]
|
||||
+ [David Wragg][31]
|
||||
+ [Michael Crosby][32]
|
||||
|
||||
Special thanks to:
|
||||
|
||||
+ [Danilo Bürger][23] for packaging Tini for Alpine
|
||||
+ [Asko Soukka][24] for packaging Tini for Nix
|
||||
+ [Danilo Bürger][40] for packaging Tini for Alpine
|
||||
+ [Asko Soukka][41] for packaging Tini for Nix
|
||||
|
||||
|
||||
[10]: https://github.com/krallin/tini-images
|
||||
[20]: https://github.com/krallin/
|
||||
[21]: https://github.com/tianon
|
||||
[22]: https://github.com/dpw
|
||||
[23]: https://github.com/danilobuerger
|
||||
[24]: https://github.com/datakurre
|
||||
[30]: https://github.com/tianon
|
||||
[31]: https://github.com/dpw
|
||||
[32]: https://github.com/crosbymichael
|
||||
[40]: https://github.com/danilobuerger
|
||||
[41]: https://github.com/datakurre
|
||||
|
|
|
@ -45,8 +45,8 @@ export PATH="${SOURCE_DIR}/ci/util:${PATH}"
|
|||
|
||||
# Build
|
||||
CMAKE_ARGS=(-B"${BUILD_DIR}" -H"${SOURCE_DIR}")
|
||||
if [[ -n "${NO_ARGS:-}" ]]; then
|
||||
CMAKE_ARGS+=(-DNO_ARGS=ON)
|
||||
if [[ -n "${MINIMAL:-}" ]]; then
|
||||
CMAKE_ARGS+=(-DMINIMAL=ON)
|
||||
fi
|
||||
cmake "${CMAKE_ARGS[@]}"
|
||||
|
||||
|
@ -71,10 +71,21 @@ if [[ -n "${ARCH_NATIVE:=}" ]]; then
|
|||
|
||||
# Smoke tests (actual tests need Docker to run; they don't run within the CI environment)
|
||||
for tini in "${BUILD_DIR}/tini" "${BUILD_DIR}/tini-static"; do
|
||||
echo "Testing ${tini} --version"
|
||||
"$tini" --version | grep "tini version"
|
||||
echo "Smoke test for ${tini}"
|
||||
"$tini" --version
|
||||
|
||||
if [[ -n "${NO_ARGS:-}" ]]; then
|
||||
echo "Testing ${tini} --version"
|
||||
"$tini" --version | grep -q "tini version"
|
||||
|
||||
echo "Testing ${tini} without arguments exits with 1"
|
||||
! "$tini" 2>/dev/null
|
||||
|
||||
echo "Testing ${tini} shows help message"
|
||||
{
|
||||
! "$tini" 2>&1
|
||||
} | grep -q "supervision of a valid init process"
|
||||
|
||||
if [[ -n "${MINIMAL:-}" ]]; then
|
||||
echo "Testing $tini with: true"
|
||||
"${tini}" true
|
||||
|
||||
|
@ -83,6 +94,11 @@ if [[ -n "${ARCH_NATIVE:=}" ]]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
echo "Testing ${tini} does not reference options that don't exist"
|
||||
! {
|
||||
! "$tini" 2>&1
|
||||
} | grep -q "more verbose"
|
||||
|
||||
# We try running binaries named after flags (both valid and invalid
|
||||
# flags) and test that they run.
|
||||
for flag in h s x; do
|
||||
|
@ -94,15 +110,15 @@ if [[ -n "${ARCH_NATIVE:=}" ]]; then
|
|||
|
||||
echo "Testing $tini can run binary --version if args are given"
|
||||
cp "$(which true)" "${BIN_TEST_DIR}/--version"
|
||||
if "$tini" "--version" --foo | grep "tini version"; then
|
||||
if "$tini" "--version" --foo | grep -q "tini version"; then
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
echo "Smoke test for $tini"
|
||||
echo "Testing ${tini} -h"
|
||||
"${tini}" -h
|
||||
|
||||
echo "Testing $tini for license"
|
||||
"${tini}" -l | grep -i "mit license"
|
||||
"${tini}" -l | grep -q -i "mit license"
|
||||
|
||||
echo "Testing $tini with: true"
|
||||
"${tini}" -vvv true
|
||||
|
@ -112,13 +128,35 @@ if [[ -n "${ARCH_NATIVE:=}" ]]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
# Test stdin / stdout are handed over to child
|
||||
echo "Testing pipe"
|
||||
echo "exit 0" | "${tini}" -vvv sh
|
||||
if [[ ! "$?" -eq "0" ]]; then
|
||||
echo "Pipe test failed"
|
||||
exit 1
|
||||
fi
|
||||
echo "Testing ${tini} references options that exist"
|
||||
{
|
||||
! "$tini" 2>&1
|
||||
} | grep -q "more verbose"
|
||||
fi
|
||||
|
||||
echo "Testing ${tini} supports TINI_VERBOSITY"
|
||||
TINI_VERBOSITY=3 "$tini" true 2>&1 | grep -q 'Received SIGCHLD'
|
||||
|
||||
echo "Testing ${tini} exits with 127 if the command does not exist"
|
||||
"$tini" foobar123 && rc="$?" || rc="$?"
|
||||
if [[ "$rc" != 127 ]]; then
|
||||
echo "Exit code was: ${rc}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Testing ${tini} exits with 126 if the command is not executable"
|
||||
"$tini" /etc && rc="$?" || rc="$?"
|
||||
if [[ "$rc" != 126 ]]; then
|
||||
echo "Exit code was: ${rc}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Test stdin / stdout are handed over to child
|
||||
echo "Testing ${tini} does not break pipes"
|
||||
echo "exit 0" | "${tini}" sh
|
||||
if [[ ! "$?" -eq "0" ]]; then
|
||||
echo "Pipe test failed"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Checking hardening on $tini"
|
||||
|
|
2
ddist.sh
2
ddist.sh
|
@ -24,5 +24,5 @@ docker run -it --rm \
|
|||
-e CC="${CC:=gcc}" \
|
||||
-e ARCH_NATIVE="${ARCH_NATIVE-1}" \
|
||||
-e ARCH_SUFFIX="${ARCH_SUFFIX-}" \
|
||||
-e NO_ARGS="${NO_ARGS-}" \
|
||||
-e MINIMAL="${MINIMAL-}" \
|
||||
"${IMG}" "${SRC}/ci/run_build.sh"
|
||||
|
|
89
src/tini.c
89
src/tini.c
|
@ -17,11 +17,21 @@
|
|||
#include "tiniConfig.h"
|
||||
#include "tiniLicense.h"
|
||||
|
||||
#if TINI_MINIMAL
|
||||
#define PRINT_FATAL(...) fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n");
|
||||
#define PRINT_WARNING(...) if (verbosity > 0) { fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); }
|
||||
#define PRINT_INFO(...) if (verbosity > 1) { fprintf(stdout, __VA_ARGS__); fprintf(stdout, "\n"); }
|
||||
#define PRINT_DEBUG(...) if (verbosity > 2) { fprintf(stdout, __VA_ARGS__); fprintf(stdout, "\n"); }
|
||||
#define PRINT_TRACE(...) if (verbosity > 3) { fprintf(stdout, __VA_ARGS__); fprintf(stdout, "\n"); }
|
||||
#define DEFAULT_VERBOSITY 0
|
||||
#else
|
||||
#define PRINT_FATAL(...) fprintf(stderr, "[FATAL tini (%i)] ", getpid()); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n");
|
||||
#define PRINT_WARNING(...) if (verbosity > 0) { fprintf(stderr, "[WARN tini (%i)] ", getpid()); fprintf(stderr, __VA_ARGS__); fprintf(stderr, "\n"); }
|
||||
#define PRINT_INFO(...) if (verbosity > 1) { fprintf(stdout, "[INFO tini (%i)] ", getpid()); fprintf(stdout, __VA_ARGS__); fprintf(stdout, "\n"); }
|
||||
#define PRINT_DEBUG(...) if (verbosity > 2) { fprintf(stdout, "[DEBUG tini (%i)] ", getpid()); fprintf(stdout, __VA_ARGS__); fprintf(stdout, "\n"); }
|
||||
#define PRINT_TRACE(...) if (verbosity > 3) { fprintf(stdout, "[TRACE tini (%i)] ", getpid()); fprintf(stdout, __VA_ARGS__); fprintf(stdout, "\n"); }
|
||||
#define DEFAULT_VERBOSITY 1
|
||||
#endif
|
||||
|
||||
#define ARRAY_LEN(x) (sizeof(x) / sizeof(x[0]))
|
||||
|
||||
|
@ -31,6 +41,7 @@ typedef struct {
|
|||
struct sigaction* const sigttou_action_ptr;
|
||||
} signal_configuration_t;
|
||||
|
||||
static unsigned int verbosity = DEFAULT_VERBOSITY;
|
||||
|
||||
#ifdef PR_SET_CHILD_SUBREAPER
|
||||
#define HAS_SUBREAPER 1
|
||||
|
@ -41,13 +52,14 @@ typedef struct {
|
|||
#define OPT_STRING "hvgl"
|
||||
#endif
|
||||
|
||||
#define VERBOSITY_ENV_VAR "TINI_VERBOSITY"
|
||||
|
||||
#define TINI_VERSION_STRING "tini version " TINI_VERSION TINI_GIT
|
||||
|
||||
|
||||
#if HAS_SUBREAPER
|
||||
static unsigned int subreaper = 0;
|
||||
#endif
|
||||
static unsigned int verbosity = 1;
|
||||
static unsigned int kill_process_group = 0;
|
||||
|
||||
static struct timespec ts = { .tv_sec = 1, .tv_nsec = 0 };
|
||||
|
@ -56,13 +68,16 @@ static const char reaper_warning[] = "Tini is not running as PID 1 "
|
|||
#if HAS_SUBREAPER
|
||||
"and isn't registered as a child subreaper"
|
||||
#endif
|
||||
".\n\
|
||||
Zombie processes will not be re-parented to Tini, so zombie reaping won't work.\n\
|
||||
To fix the problem, "
|
||||
".\n\
|
||||
Zombie processes will not be re-parented to Tini, so zombie reaping won't work.\n\
|
||||
To fix the problem, "
|
||||
#if HAS_SUBREAPER
|
||||
"use -s or set the environment variable " SUBREAPER_ENV_VAR " to register Tini as a child subreaper, or "
|
||||
#ifndef TINI_MINIMAL
|
||||
"use the -s option "
|
||||
#endif
|
||||
"run Tini as PID 1.";
|
||||
"or set the environment variable " SUBREAPER_ENV_VAR " to register Tini as a child subreaper, or "
|
||||
#endif
|
||||
"run Tini as PID 1.";
|
||||
|
||||
int restore_signals(const signal_configuration_t* const sigconf_ptr) {
|
||||
if (sigprocmask(SIG_SETMASK, sigconf_ptr->sigmask_ptr, NULL)) {
|
||||
|
@ -86,7 +101,7 @@ int restore_signals(const signal_configuration_t* const sigconf_ptr) {
|
|||
int isolate_child() {
|
||||
// Put the child into a new process group.
|
||||
if (setpgid(0, 0) < 0) {
|
||||
PRINT_FATAL("setpgid failed: '%s'", strerror(errno));
|
||||
PRINT_FATAL("setpgid failed: %s", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -102,7 +117,7 @@ int isolate_child() {
|
|||
if (errno == ENOTTY) {
|
||||
PRINT_DEBUG("tcsetpgrp failed: no tty (ok to proceed)")
|
||||
} else {
|
||||
PRINT_FATAL("tcsetpgrp failed: '%s'", strerror(errno));
|
||||
PRINT_FATAL("tcsetpgrp failed: %s", strerror(errno));
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -118,7 +133,7 @@ int spawn(const signal_configuration_t* const sigconf_ptr, char* const argv[], i
|
|||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
PRINT_FATAL("Fork failed: '%s'", strerror(errno));
|
||||
PRINT_FATAL("fork failed: %s", strerror(errno));
|
||||
return 1;
|
||||
} else if (pid == 0) {
|
||||
|
||||
|
@ -133,8 +148,21 @@ int spawn(const signal_configuration_t* const sigconf_ptr, char* const argv[], i
|
|||
}
|
||||
|
||||
execvp(argv[0], argv);
|
||||
PRINT_FATAL("Executing child process '%s' failed: '%s'", argv[0], strerror(errno));
|
||||
return 1;
|
||||
|
||||
// execvp will only return on an error so make sure that we check the errno
|
||||
// and exit with the correct return status for the error that we encountered
|
||||
// See: http://www.tldp.org/LDP/abs/html/exitcodes.html#EXITCODESREF
|
||||
int status = 1;
|
||||
switch errno {
|
||||
case ENOENT:
|
||||
status = 127;
|
||||
break;
|
||||
case EACCES:
|
||||
status = 126;
|
||||
break;
|
||||
}
|
||||
PRINT_FATAL("exec %s failed: %s", argv[0], strerror(errno));
|
||||
return status;
|
||||
} else {
|
||||
// Parent
|
||||
PRINT_INFO("Spawned child process '%s' with pid '%i'", argv[0], pid);
|
||||
|
@ -145,8 +173,20 @@ int spawn(const signal_configuration_t* const sigconf_ptr, char* const argv[], i
|
|||
|
||||
void print_usage(char* const name, FILE* const file) {
|
||||
fprintf(file, "%s (%s)\n", basename(name), TINI_VERSION_STRING);
|
||||
fprintf(file, "Usage: %s [OPTIONS] PROGRAM -- [ARGS]\n\n", basename(name));
|
||||
|
||||
#if TINI_MINIMAL
|
||||
fprintf(file, "Usage: %s PROGRAM [ARGS] | --version\n\n", basename(name));
|
||||
#else
|
||||
fprintf(file, "Usage: %s [OPTIONS] PROGRAM -- [ARGS] | --version\n\n", basename(name));
|
||||
#endif
|
||||
fprintf(file, "Execute a program under the supervision of a valid init process (%s)\n\n", basename(name));
|
||||
|
||||
fprintf(file, "Command line options:\n\n");
|
||||
|
||||
fprintf(file, " --version: Show version and exit.\n");
|
||||
|
||||
#if TINI_MINIMAL
|
||||
#else
|
||||
fprintf(file, " -h: Show this help message and exit.\n");
|
||||
#if HAS_SUBREAPER
|
||||
fprintf(file, " -s: Register as a process subreaper (requires Linux >= 3.4).\n");
|
||||
|
@ -154,6 +194,16 @@ void print_usage(char* const name, FILE* const file) {
|
|||
fprintf(file, " -v: Generate more verbose output. Repeat up to 3 times.\n");
|
||||
fprintf(file, " -g: Send signals to the child's process group.\n");
|
||||
fprintf(file, " -l: Show license and exit.\n");
|
||||
#endif
|
||||
|
||||
fprintf(file, "\n");
|
||||
|
||||
fprintf(file, "Environment variables:\n\n");
|
||||
#if HAS_SUBREAPER
|
||||
fprintf(file, " %s: Register as a process subreaper (requires Linux >= 3.4)\n", SUBREAPER_ENV_VAR);
|
||||
#endif
|
||||
fprintf(file, " %s: Set the verbosity level (default: %d)\n", VERBOSITY_ENV_VAR, DEFAULT_VERBOSITY);
|
||||
|
||||
fprintf(file, "\n");
|
||||
}
|
||||
|
||||
|
@ -172,9 +222,7 @@ int parse_args(const int argc, char* const argv[], char* (**child_args_ptr_ptr)[
|
|||
return 1;
|
||||
}
|
||||
|
||||
#if TINI_NO_ARGS
|
||||
*parse_fail_exitcode_ptr = 0;
|
||||
#else
|
||||
#ifndef TINI_MINIMAL
|
||||
int c;
|
||||
while ((c = getopt(argc, argv, OPT_STRING)) != -1) {
|
||||
switch (c) {
|
||||
|
@ -237,6 +285,12 @@ int parse_env() {
|
|||
subreaper++;
|
||||
}
|
||||
#endif
|
||||
|
||||
char* env_verbosity = getenv(VERBOSITY_ENV_VAR);
|
||||
if (env_verbosity != NULL) {
|
||||
verbosity = atoi(env_verbosity);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -468,8 +522,9 @@ int main(int argc, char *argv[]) {
|
|||
reaper_check();
|
||||
|
||||
/* Go on */
|
||||
if (spawn(&child_sigconf, *child_args_ptr, &child_pid)) {
|
||||
return 1;
|
||||
int spawn_ret = spawn(&child_sigconf, *child_args_ptr, &child_pid);
|
||||
if (spawn_ret) {
|
||||
return spawn_ret;
|
||||
}
|
||||
free(child_args_ptr);
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ def main():
|
|||
src = os.environ["SOURCE_DIR"]
|
||||
build = os.environ["BUILD_DIR"]
|
||||
|
||||
args_disabled = os.environ.get("NO_ARGS")
|
||||
args_disabled = os.environ.get("MINIMAL")
|
||||
|
||||
proxy = os.path.join(src, "test", "subreaper-proxy.py")
|
||||
tini = os.path.join(build, "tini")
|
||||
|
@ -80,10 +80,14 @@ def main():
|
|||
p.send_signal(signal.SIGUSR1)
|
||||
busy_wait(lambda: p.poll() is not None, 10)
|
||||
|
||||
|
||||
# Run failing test
|
||||
# Run failing test. Force verbosity to 1 so we see the subreaper warning
|
||||
# regardless of whether MINIMAL is set.
|
||||
print "Running zombie reaping failure test (Tini should warn)"
|
||||
p = subprocess.Popen([tini, os.path.join(src, "test", "reaping", "stage_1.py")], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
p = subprocess.Popen(
|
||||
[tini, os.path.join(src, "test", "reaping", "stage_1.py")],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
|
||||
env={'TINI_VERBOSITY': '1'}
|
||||
)
|
||||
out, err = p.communicate()
|
||||
assert "zombie reaping won't work" in err, "No warning message was output!"
|
||||
ret = p.wait()
|
||||
|
|
|
@ -65,15 +65,19 @@ class Command(object):
|
|||
|
||||
|
||||
def attach_and_type_exit_0(name):
|
||||
print "Attaching to {0} to exit 0".format(name)
|
||||
p = pexpect.spawn("docker attach {0}".format(name))
|
||||
p.sendline('')
|
||||
p.sendline('exit 0')
|
||||
p.close()
|
||||
|
||||
|
||||
def attach_and_issue_ctrl_c(name):
|
||||
print "Attaching to {0} to CTRL+C".format(name)
|
||||
p = pexpect.spawn("docker attach {0}".format(name))
|
||||
p.expect_exact('#')
|
||||
p.sendintr()
|
||||
p.close()
|
||||
|
||||
|
||||
def test_tty_handling(img, name, base_cmd, fail_cmd, container_command, exit_function, expect_exit_code):
|
||||
|
@ -83,7 +87,11 @@ def test_tty_handling(img, name, base_cmd, fail_cmd, container_command, exit_fun
|
|||
shell_ready_event = threading.Event()
|
||||
|
||||
def spawn():
|
||||
p = pexpect.spawn(" ".join(base_cmd + ["--tty", "--interactive", img, "/tini/dist/tini", "-vvv", "--", container_command]))
|
||||
cmd = base_cmd + ["--tty", "--interactive", img, "/tini/dist/tini"]
|
||||
if os.environ.get("MINIMAL") is None:
|
||||
cmd.append("--")
|
||||
cmd.append(container_command)
|
||||
p = pexpect.spawn(" ".join(cmd))
|
||||
p.expect_exact("#")
|
||||
shell_ready_event.set()
|
||||
rc.value = p.wait()
|
||||
|
@ -112,6 +120,7 @@ def test_tty_handling(img, name, base_cmd, fail_cmd, container_command, exit_fun
|
|||
def main():
|
||||
img = sys.argv[1]
|
||||
name = "{0}-test".format(img)
|
||||
args_disabled = os.environ.get("MINIMAL")
|
||||
|
||||
root = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
|
||||
|
||||
|
@ -129,8 +138,8 @@ def main():
|
|||
for entrypoint in ["/tini/dist/tini", "/tini/dist/tini-static"]:
|
||||
functional_base_cmd = base_cmd + [
|
||||
"--entrypoint={0}".format(entrypoint),
|
||||
"-e", "TINI_VERBOSITY=3",
|
||||
img,
|
||||
"-vvv",
|
||||
]
|
||||
|
||||
# Reaping test
|
||||
|
@ -139,20 +148,24 @@ def main():
|
|||
# Signals test
|
||||
for sig, retcode in [("INT", 1), ("TERM", 143)]:
|
||||
Command(
|
||||
functional_base_cmd + ["--", "/tini/test/signals/test.py"],
|
||||
functional_base_cmd + ["/tini/test/signals/test.py"],
|
||||
fail_cmd,
|
||||
["docker", "kill", "-s", sig, name],
|
||||
2
|
||||
).run(timeout=10, retcode=retcode)
|
||||
|
||||
# Exit code test
|
||||
Command(functional_base_cmd + ["-z"], fail_cmd).run(retcode=1)
|
||||
Command(functional_base_cmd + ["--", "zzzz"], fail_cmd).run(retcode=1)
|
||||
Command(functional_base_cmd + ["-h"], fail_cmd).run()
|
||||
Command(functional_base_cmd + ["-z"], fail_cmd).run(retcode=127 if args_disabled else 1)
|
||||
Command(functional_base_cmd + ["-h"], fail_cmd).run(retcode=127 if args_disabled else 0)
|
||||
Command(functional_base_cmd + ["zzzz"], fail_cmd).run(retcode=127)
|
||||
|
||||
# Valgrind test (we only run this on the dynamic version, because otherwise Valgrind may bring up plenty of errors that are
|
||||
# actually from libc)
|
||||
Command(functional_base_cmd + ["--", "valgrind", "--leak-check=full", "--error-exitcode=1", "/tini/dist/tini", "-v", "--", "ls"], fail_cmd).run()
|
||||
Command(base_cmd + [img, "valgrind", "--leak-check=full", "--error-exitcode=1", "/tini/dist/tini", "ls"], fail_cmd).run()
|
||||
|
||||
# Test tty handling
|
||||
test_tty_handling(img, name, base_cmd, fail_cmd, "dash", attach_and_type_exit_0, 0)
|
||||
test_tty_handling(img, name, base_cmd, fail_cmd, "dash -c 'while true; do echo \#; sleep 0.1; done'", attach_and_issue_ctrl_c, 128 + signal.SIGINT)
|
||||
|
||||
# Installation tests (sh -c is used for globbing and &&)
|
||||
for image, pkg_manager, extension in [
|
||||
|
@ -164,10 +177,5 @@ def main():
|
|||
Command(base_cmd + [image, "sh", "-c", "{0} -i /tini/dist/*.{1} && /usr/bin/tini true".format(pkg_manager, extension)], fail_cmd).run()
|
||||
|
||||
|
||||
# Test tty handling
|
||||
test_tty_handling(img, name, base_cmd, fail_cmd, "dash", attach_and_type_exit_0, 0)
|
||||
test_tty_handling(img, name, base_cmd, fail_cmd, "dash -c 'while true; do echo \#; sleep 0.1; done'", attach_and_issue_ctrl_c, 128 + signal.SIGINT)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
|
|
@ -214,18 +214,20 @@ Maintainer:
|
|||
|
||||
Contributors:
|
||||
|
||||
+ [Tianon Gravi][21]
|
||||
+ [David Wragg][22]
|
||||
+ [Tianon Gravi][30]
|
||||
+ [David Wragg][31]
|
||||
+ [Michael Crosby][32]
|
||||
|
||||
Special thanks to:
|
||||
|
||||
+ [Danilo Bürger][23] for packaging Tini for Alpine
|
||||
+ [Asko Soukka][24] for packaging Tini for Nix
|
||||
+ [Danilo Bürger][40] for packaging Tini for Alpine
|
||||
+ [Asko Soukka][41] for packaging Tini for Nix
|
||||
|
||||
|
||||
[10]: https://github.com/krallin/tini-images
|
||||
[20]: https://github.com/krallin/
|
||||
[21]: https://github.com/tianon
|
||||
[22]: https://github.com/dpw
|
||||
[23]: https://github.com/danilobuerger
|
||||
[24]: https://github.com/datakurre
|
||||
[30]: https://github.com/tianon
|
||||
[31]: https://github.com/dpw
|
||||
[32]: https://github.com/crosbymichael
|
||||
[40]: https://github.com/danilobuerger
|
||||
[41]: https://github.com/datakurre
|
||||
|
|
Loading…
Reference in New Issue