Skip to content

Instantly share code, notes, and snippets.

@muayyad-alsadi
Created August 31, 2016 12:36
Show Gist options
  • Save muayyad-alsadi/ca4153efc636f761e26b76a186832077 to your computer and use it in GitHub Desktop.
Save muayyad-alsadi/ca4153efc636f761e26b76a186832077 to your computer and use it in GitHub Desktop.
dumb-init
diff --git a/README.md b/README.md
index f224b04..c272d09 100644
--- a/README.md
+++ b/README.md
@@ -186,7 +186,8 @@ then just `pip install dumb-init`.
## Usage
Once installed inside your Docker container, simply prefix your commands with
-`dumb-init`.
+`dumb-init` (and make sure that you're using [the recommended JSON
+syntax][docker-cmd-json]).
Within a Dockerfile, it's a good practice to use dumb-init as your container's
entrypoint. An "entrypoint" is a partial command that gets prepended to your
@@ -209,6 +210,10 @@ Running this same command without `dumb-init` would result in being unable to
stop the container without `SIGKILL`, but with `dumb-init`, you can send it
more humane signals like `SIGTERM`.
+It's important that you use [the JSON syntax][docker-cmd-json] for `CMD` and
+`ENTRYPOINT`. Otherwise, Docker invokes a shell to run your command, resulting
+in the shell as PID 1 instead of dumb-init.
+
## Building dumb-init
@@ -255,3 +260,4 @@ your machine.
[systemd]: https://wiki.freedesktop.org/www/Software/systemd/
[sysvinit]: https://wiki.archlinux.org/index.php/SysVinit
[docker]: https://www.docker.com/
+[docker-cmd-json]: https://docs.docker.com/engine/reference/builder/#run
diff --git a/testing/__init__.py b/testing/__init__.py
index ef2d543..1d87f30 100644
--- a/testing/__init__.py
+++ b/testing/__init__.py
@@ -50,14 +50,17 @@ def child_pids(pid):
"""Return a list of direct child PIDs for the given PID."""
children = set()
for p in LocalPath('/proc').listdir():
- stat = p.join('stat')
- if stat.isfile():
- stat = stat.open().read()
- m = re.match('^\d+ \([^\)]+\) [a-zA-Z] (\d+) ', stat)
+ try:
+ stat = open(p.join('stat').strpath).read()
+ m = re.match('^\d+ \(.+?\) [a-zA-Z] (\d+) ', stat)
assert m, stat
ppid = int(m.group(1))
if ppid == pid:
children.add(int(p.basename))
+ except IOError:
+ # Happens when the process exits after listing it, or between
+ # opening stat and reading it.
+ pass
return children
diff --git a/tests/exit_status_test.py b/tests/exit_status_test.py
index bb7be1d..f67a17c 100644
--- a/tests/exit_status_test.py
+++ b/tests/exit_status_test.py
@@ -1,4 +1,5 @@
import signal
+import sys
from subprocess import Popen
import pytest
@@ -17,7 +18,7 @@ def test_exit_status_regular_exit(exit_status):
@pytest.mark.parametrize('signal', [
signal.SIGTERM,
- signal.SIGINT,
+ signal.SIGHUP,
signal.SIGQUIT,
signal.SIGKILL,
])
@@ -26,6 +27,10 @@ def test_exit_status_terminated_by_signal(signal):
"""dumb-init should exit with status 128 + signal when the child process is
terminated by a signal.
"""
- proc = Popen(('dumb-init', 'sh', '-c', 'kill -{0} $$'.format(signal)))
+ # We use Python because sh is "dash" on Debian and "bash" on others.
+ # https://github.com/Yelp/dumb-init/issues/115
+ proc = Popen(('dumb-init', sys.executable, '-c', 'import os; os.kill(os.getpid(), {0})'.format(
+ signal,
+ )))
proc.wait()
assert proc.returncode == 128 + signal
Name: dumb-init
Version: 1.1.3
Release: 9%{?dist}
Summary: Entry-point for containers that proxies signals
License: MIT
URL: https://github.com/Yelp/dumb-init
Source0: %{url}/archive/v%{version}/%{name}-%{version}.tar.gz
# merged upstream patch https://github.com/Yelp/dumb-init/pull/116/
Patch0: dumb-init.fix-test.patch
BuildRequires: gcc, help2man
# EPEL does not have python3-pytest python3-mock
%if 0%{?rhel}
BuildRequires: python34, python34-pytest python34-mock
%else
BuildRequires: python3, python3-pytest python3-mock
%endif
# /bin/xxd of vim-common of is needed for non-released versions
# BuildRequires: vim-common
%description
dumb-init is a simple process supervisor and init system designed to run as
PID 1 inside minimal container environments (such as Docker).
* It can handle orphaned zombie processes.
* It can pass signals properly for simple containers.
%prep
%setup -q
%patch0 -p1
%build
# uncomment next line when building a non-released version
# make VERSION.h
gcc -std=gnu99 %{optflags} -o %{name} dumb-init.c
help2man --no-discard-stderr --include debian/help2man --no-info --name '%{summary}' ./%{name} > %{name}.1
%check
PATH=.:$PATH py.test-3 tests/
%install
install -Dpm0755 %{name} %{buildroot}%{_bindir}/%{name}
install -Dpm0644 %{name}.1 %{buildroot}%{_mandir}/man1/%{name}.1
%files
%{_bindir}/%{name}
%{_mandir}/man1/%{name}.1*
%license LICENSE
%doc README.md
%changelog
* Wed Aug 31 2016 Muayyad Alsadi <[email protected]> - 1.1.3-9
- support epel
* Fri Aug 26 2016 Muayyad Alsadi <[email protected]> - 1.1.3-8
- run tests
* Wed Aug 17 2016 Muayyad Alsadi <[email protected]> - 1.1.3-7
- let manpage automatically marked as document
* Wed Aug 17 2016 Muayyad Alsadi <[email protected]> - 1.1.3-6
- remove gzip after help2man
- add missing BuildRequire
* Wed Aug 17 2016 Muayyad Alsadi <[email protected]> - 1.1.3-4
- install 644 for manpage
* Wed Aug 17 2016 Muayyad Alsadi <[email protected]> - 1.1.3-3
- remove vim-common and use install
* Mon Aug 15 2016 Muayyad Alsadi <[email protected]> - 1.1.3-2
- initial packaging
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment