Merge branch 'ckuehl_python_package'
This commit is contained in:
commit
6f6814e91b
17 changed files with 328 additions and 124 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -1,3 +1,5 @@
|
||||||
dumb-init
|
dumb-init
|
||||||
dist/
|
dist/
|
||||||
*.deb
|
*.deb
|
||||||
|
*.egg-info
|
||||||
|
.tox
|
||||||
|
|
26
.pre-commit-config.yaml
Normal file
26
.pre-commit-config.yaml
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks.git
|
||||||
|
sha: 003e43251aea1da33f2072f2365ec8b9ceaae070
|
||||||
|
hooks:
|
||||||
|
- id: autopep8-wrapper
|
||||||
|
- id: check-added-large-files
|
||||||
|
- id: check-docstring-first
|
||||||
|
- id: check-json
|
||||||
|
- id: check-merge-conflict
|
||||||
|
- id: check-xml
|
||||||
|
- id: check-yaml
|
||||||
|
- id: debug-statements
|
||||||
|
- id: detect-private-key
|
||||||
|
- id: double-quote-string-fixer
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
- id: flake8
|
||||||
|
- id: name-tests-test
|
||||||
|
- id: requirements-txt-fixer
|
||||||
|
- id: trailing-whitespace
|
||||||
|
- repo: https://github.com/asottile/reorder_python_imports.git
|
||||||
|
sha: 3d86483455ab5bd06cc1069fdd5ac57be5463f10
|
||||||
|
hooks:
|
||||||
|
- id: reorder-python-imports
|
||||||
|
- repo: https://github.com/Lucas-C/pre-commit-hooks.git
|
||||||
|
sha: 181a63c511691da58116fa19a7241956018660bc
|
||||||
|
hooks:
|
||||||
|
- id: remove-tabs
|
1
MANIFEST.in
Normal file
1
MANIFEST.in
Normal file
|
@ -0,0 +1 @@
|
||||||
|
include dumb-init.c
|
59
Makefile
59
Makefile
|
@ -1,13 +1,31 @@
|
||||||
DOCKER_TEST := sh -c 'dpkg -i /mnt/dist/*.deb && cd /mnt && ./test'
|
DOCKER_RUN_TEST := docker run -v $(PWD):/mnt:ro
|
||||||
|
DOCKER_DEB_TEST := sh -euxc ' \
|
||||||
|
apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends procps \
|
||||||
|
&& dpkg -i /mnt/dist/*.deb \
|
||||||
|
&& cd /mnt \
|
||||||
|
&& ./test \
|
||||||
|
'
|
||||||
|
DOCKER_PYTHON_TEST := sh -uexc ' \
|
||||||
|
apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends python-pip build-essential procps \
|
||||||
|
&& pip install -vv /mnt \
|
||||||
|
&& cd /mnt \
|
||||||
|
&& ./test \
|
||||||
|
'
|
||||||
|
|
||||||
.PHONY: build
|
.PHONY: build
|
||||||
build:
|
build:
|
||||||
$(CC) -static -Wall -Werror -o dumb-init dumb-init.c
|
$(CC) -static -Wall -Werror -o dumb-init dumb-init.c
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean
|
||||||
clean:
|
clean: clean-tox
|
||||||
rm -rf dumb-init dist/ *.deb
|
rm -rf dumb-init dist/ *.deb
|
||||||
|
|
||||||
|
.PHONY: clean-tox
|
||||||
|
clean-tox:
|
||||||
|
rm -rf .tox
|
||||||
|
|
||||||
.PHONY: builddeb
|
.PHONY: builddeb
|
||||||
builddeb:
|
builddeb:
|
||||||
debuild -us -uc -b
|
debuild -us -uc -b
|
||||||
|
@ -22,24 +40,31 @@ builddeb-docker: docker-image
|
||||||
docker-image:
|
docker-image:
|
||||||
docker build -t dumb-init-build .
|
docker build -t dumb-init-build .
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test:
|
||||||
|
tox
|
||||||
|
|
||||||
|
.PHONY: install-hooks
|
||||||
|
install-hooks:
|
||||||
|
tox -e pre-commit -- install -f --install-hooks
|
||||||
|
|
||||||
.PHONY: itest itest_lucid itest_precise itest_trusty itest_wheezy itest_jessie itest_stretch
|
.PHONY: itest itest_lucid itest_precise itest_trusty itest_wheezy itest_jessie itest_stretch
|
||||||
itest: itest_lucid itest_precise itest_trusty itest_wheezy itest_jessie itest_stretch
|
itest: itest_lucid itest_precise itest_trusty itest_wheezy itest_jessie itest_stretch
|
||||||
|
|
||||||
itest_lucid: builddeb-docker
|
itest_lucid: _itest-ubuntu-lucid
|
||||||
docker run -v $(PWD):/mnt:ro ubuntu:lucid \
|
itest_precise: _itest-ubuntu-precise
|
||||||
sh -ec "apt-get -y install timeout; $(DOCKER_TEST)"
|
itest_trusty: _itest-ubuntu-trusty
|
||||||
|
itest_wheezy: _itest-debian-wheezy
|
||||||
|
itest_jessie: _itest-debian-jessie
|
||||||
|
itest_stretch: _itest-debian-stretch
|
||||||
|
|
||||||
itest_precise: builddeb-docker
|
_itest-%: _itest_deb-% _itest_python-%
|
||||||
docker run -v $(PWD):/mnt:ro ubuntu:precise $(DOCKER_TEST)
|
@true
|
||||||
|
|
||||||
itest_trusty: builddeb-docker
|
_itest_python-%:
|
||||||
docker run -v $(PWD):/mnt:ro ubuntu:trusty $(DOCKER_TEST)
|
$(eval DOCKER_IMG := $(shell echo $@ | cut -d- -f2 | sed 's/-/:/'))
|
||||||
|
$(DOCKER_RUN_TEST) $(DOCKER_IMG) $(DOCKER_PYTHON_TEST)
|
||||||
|
|
||||||
itest_wheezy: builddeb-docker
|
_itest_deb-%:
|
||||||
docker run -v $(PWD):/mnt:ro debian:wheezy $(DOCKER_TEST)
|
$(eval DOCKER_IMG := $(shell echo $@ | cut -d- -f2 | sed 's/-/:/'))
|
||||||
|
$(DOCKER_RUN_TEST) $(DOCKER_IMG) $(DOCKER_DEB_TEST)
|
||||||
itest_jessie: builddeb-docker
|
|
||||||
docker run -v $(PWD):/mnt:ro debian:jessie $(DOCKER_TEST)
|
|
||||||
|
|
||||||
itest_stretch: builddeb-docker
|
|
||||||
docker run -v $(PWD):/mnt:ro debian:stretch $(DOCKER_TEST)
|
|
||||||
|
|
|
@ -60,6 +60,14 @@ If you don't have an internal apt server, you can use `dpkg -i` to install the
|
||||||
(mounting a directory or `wget`-ing it are some options).
|
(mounting a directory or `wget`-ing it are some options).
|
||||||
|
|
||||||
|
|
||||||
|
### Option 3: Installing from PyPI
|
||||||
|
|
||||||
|
dumb-init can be installed [from PyPI](https://pypi.python.org/pypi/dumb-init)
|
||||||
|
using pip. Since dumb-init is written in C, you'll want to first install gcc
|
||||||
|
(on Debian/Ubuntu, `apt-get install gcc` is sufficient), then just `pip install
|
||||||
|
dumb-init`.
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
Once installed inside your Docker container, simply prefix your commands with
|
Once installed inside your Docker container, simply prefix your commands with
|
||||||
|
|
2
debian/control
vendored
2
debian/control
vendored
|
@ -2,7 +2,7 @@ Source: dumb-init
|
||||||
Section: utils
|
Section: utils
|
||||||
Priority: extra
|
Priority: extra
|
||||||
Maintainer: Chris Kuehl <ckuehl@yelp.com>
|
Maintainer: Chris Kuehl <ckuehl@yelp.com>
|
||||||
Build-Depends: debhelper (>= 7), gcc, fakeroot
|
Build-Depends: debhelper (>= 7), gcc, fakeroot, procps
|
||||||
Standards-Version: 3.9.6
|
Standards-Version: 3.9.6
|
||||||
|
|
||||||
Package: dumb-init
|
Package: dumb-init
|
||||||
|
|
3
debian/rules
vendored
3
debian/rules
vendored
|
@ -4,3 +4,6 @@
|
||||||
|
|
||||||
override_dh_builddeb:
|
override_dh_builddeb:
|
||||||
dh_builddeb -- -Zgzip
|
dh_builddeb -- -Zgzip
|
||||||
|
|
||||||
|
override_dh_auto_test:
|
||||||
|
./test ./dumb-init
|
||||||
|
|
107
setup.py
Normal file
107
setup.py
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
import os.path
|
||||||
|
from distutils.command.build import build as orig_build
|
||||||
|
from distutils.core import Command
|
||||||
|
|
||||||
|
from setuptools import Distribution
|
||||||
|
from setuptools import Extension
|
||||||
|
from setuptools import setup
|
||||||
|
from setuptools.command.install import install as orig_install
|
||||||
|
|
||||||
|
|
||||||
|
class ExeDistribution(Distribution):
|
||||||
|
c_executables = ()
|
||||||
|
|
||||||
|
|
||||||
|
class build(orig_build):
|
||||||
|
sub_commands = orig_build.sub_commands + [
|
||||||
|
('build_cexe', None),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class install(orig_install):
|
||||||
|
sub_commands = orig_install.sub_commands + [
|
||||||
|
('install_cexe', None),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class install_cexe(Command):
|
||||||
|
description = 'install C executables'
|
||||||
|
outfiles = ()
|
||||||
|
|
||||||
|
def initialize_options(self):
|
||||||
|
self.build_dir = self.install_dir = None
|
||||||
|
|
||||||
|
def finalize_options(self):
|
||||||
|
# this initializes attributes based on other commands' attributes
|
||||||
|
self.set_undefined_options('build', ('build_scripts', 'build_dir'))
|
||||||
|
self.set_undefined_options(
|
||||||
|
'install', ('install_scripts', 'install_dir'))
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
self.outfiles = self.copy_tree(self.build_dir, self.install_dir)
|
||||||
|
|
||||||
|
def get_outputs(self):
|
||||||
|
return self.outfiles
|
||||||
|
|
||||||
|
|
||||||
|
class build_cexe(Command):
|
||||||
|
description = 'build C executables'
|
||||||
|
|
||||||
|
def initialize_options(self):
|
||||||
|
self.build_scripts = None
|
||||||
|
self.build_temp = None
|
||||||
|
|
||||||
|
def finalize_options(self):
|
||||||
|
self.set_undefined_options(
|
||||||
|
'build',
|
||||||
|
('build_scripts', 'build_scripts'),
|
||||||
|
('build_temp', 'build_temp'),
|
||||||
|
)
|
||||||
|
|
||||||
|
def run(self):
|
||||||
|
# stolen and simplified from distutils.command.build_ext
|
||||||
|
from distutils.ccompiler import new_compiler
|
||||||
|
|
||||||
|
compiler = new_compiler(verbose=True)
|
||||||
|
|
||||||
|
for exe in self.distribution.c_executables:
|
||||||
|
objects = compiler.compile(
|
||||||
|
exe.sources,
|
||||||
|
output_dir=self.build_temp,
|
||||||
|
)
|
||||||
|
compiler.link_executable(
|
||||||
|
objects,
|
||||||
|
exe.name,
|
||||||
|
output_dir=self.build_scripts,
|
||||||
|
extra_postargs=exe.extra_link_args,
|
||||||
|
)
|
||||||
|
|
||||||
|
def get_outputs(self):
|
||||||
|
return [
|
||||||
|
os.path.join(self.build_scripts, exe.name)
|
||||||
|
for exe in self.distribution.c_executables
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name='dumb-init',
|
||||||
|
description='Simple wrapper script which proxies signals to a child',
|
||||||
|
version='0.0.2',
|
||||||
|
author='Yelp',
|
||||||
|
platforms='linux',
|
||||||
|
|
||||||
|
c_executables=[
|
||||||
|
Extension(
|
||||||
|
'dumb-init',
|
||||||
|
['dumb-init.c'],
|
||||||
|
extra_link_args=['-static'],
|
||||||
|
),
|
||||||
|
],
|
||||||
|
cmdclass={
|
||||||
|
'build': build,
|
||||||
|
'build_cexe': build_cexe,
|
||||||
|
'install': install,
|
||||||
|
'install_cexe': install_cexe,
|
||||||
|
},
|
||||||
|
distclass=ExeDistribution,
|
||||||
|
)
|
19
test
19
test
|
@ -1,8 +1,19 @@
|
||||||
#!/bin/sh -eux
|
#!/bin/bash -eux
|
||||||
|
if [ "$#" -eq 1 ]; then
|
||||||
|
dumb_init_bin=$(readlink -f "$1")
|
||||||
|
else
|
||||||
|
dumb_init_bin=$(which dumb-init) || {
|
||||||
|
echo "Couldn't find dumb-init on your path, exiting."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Running with dumb-init at '$dumb_init_bin'"
|
||||||
|
|
||||||
run_tests() {
|
run_tests() {
|
||||||
./test-proxies-signals
|
./test-proxies-signals "$dumb_init_bin"
|
||||||
./test-exit-status
|
./test-exit-status "$dumb_init_bin"
|
||||||
./test-help-message
|
./test-help-message "$dumb_init_bin"
|
||||||
}
|
}
|
||||||
|
|
||||||
cd tests
|
cd tests
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#!/bin/sh -eu
|
#!/bin/bash -eux
|
||||||
# Print received signals into a file, one per line
|
# Print received signals into a file, one per line
|
||||||
file="$1"
|
file="$1"
|
||||||
|
|
||||||
|
@ -10,5 +10,6 @@ done
|
||||||
|
|
||||||
echo 'ready' > "$file"
|
echo 'ready' > "$file"
|
||||||
|
|
||||||
# loop forever
|
echo 'loop forever...'
|
||||||
|
set +x
|
||||||
while :; do true; done
|
while :; do true; done
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
#!/bin/sh -u
|
#!/bin/bash -eux
|
||||||
|
dumb_init="$1"
|
||||||
|
|
||||||
# dumb-init should exit with the same exit status as the process it launches.
|
# dumb-init should exit with the same exit status as the process it launches.
|
||||||
for i in $(seq 0 255); do
|
for i in $(seq 0 255); do
|
||||||
status=$(dumb-init sh -c "exit $i"; echo $?)
|
status=$($dumb_init sh -c "exit $i"; echo $?)
|
||||||
|
|
||||||
if [ "$status" -ne "$i" ]; then
|
if [ "$status" -ne "$i" ]; then
|
||||||
echo "Error: Expected exit status $i, got $status."
|
echo "Error: Expected exit status $i, got $status."
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
#!/bin/sh -u
|
#!/bin/bash -eux
|
||||||
# dumb-init should say something useful when called with no arguments, and exit
|
# dumb-init should say something useful when called with no arguments, and exit
|
||||||
# nonzero.
|
# nonzero.
|
||||||
|
|
||||||
status=$(dumb-init > /dev/null 2>&1; echo $?)
|
dumb_init="$1"
|
||||||
|
|
||||||
|
status=$($dumb_init > /dev/null 2>&1; echo $?)
|
||||||
|
|
||||||
if [ "$status" -ne 0 ]; then
|
if [ "$status" -ne 0 ]; then
|
||||||
msg=$(dumb-init 2>&1 || true)
|
msg=$($dumb_init 2>&1 || true)
|
||||||
msg_len=${#msg}
|
msg_len=${#msg}
|
||||||
|
|
||||||
if [ "$msg_len" -le 50 ]; then
|
if [ "$msg_len" -le 50 ]; then
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#!/bin/sh -eum
|
#!/bin/bash -euxm
|
||||||
# dumb-init should proxy all possible signals to the child process.
|
# dumb-init should proxy all possible signals to the child process.
|
||||||
|
dumb_init="$1"
|
||||||
|
|
||||||
# Try sending all signals via dumb-init to our `print-signals` script, ensure
|
# Try sending all signals via dumb-init to our `print-signals` script, ensure
|
||||||
# they were all received.
|
# they were all received.
|
||||||
|
@ -11,7 +12,7 @@ fifo=$(mktemp -u)
|
||||||
mkfifo -m 600 "$fifo"
|
mkfifo -m 600 "$fifo"
|
||||||
read_cmd="timeout 1 head -n1 $fifo"
|
read_cmd="timeout 1 head -n1 $fifo"
|
||||||
|
|
||||||
dumb-init ./lib/print-signals "$fifo" &
|
$dumb_init ./lib/print-signals "$fifo" &
|
||||||
pid="$!"
|
pid="$!"
|
||||||
|
|
||||||
# Wait for `print-signals` to indicate it's ready.
|
# Wait for `print-signals` to indicate it's ready.
|
||||||
|
@ -37,5 +38,9 @@ done
|
||||||
# Turn off job monitoring so we don't get a spurious "[1] + Killed" printed
|
# Turn off job monitoring so we don't get a spurious "[1] + Killed" printed
|
||||||
set +m
|
set +m
|
||||||
|
|
||||||
kill -9 "$pid"
|
# $pid is the PID of the dumb-init process. Since print-signals ignores all
|
||||||
|
# signals, we need to `kill -9` it. If we just `kill -9` the dumb-init process,
|
||||||
|
# `print-signals` will still be running. So we instead kill children of the
|
||||||
|
# dumb-init process.
|
||||||
|
pkill -9 -P "$pid"
|
||||||
rm "$fifo"
|
rm "$fifo"
|
||||||
|
|
11
tox.ini
Normal file
11
tox.ini
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[tox]
|
||||||
|
envlist = py27,py34
|
||||||
|
|
||||||
|
[testenv]
|
||||||
|
deps = pre-commit>=0.5.0
|
||||||
|
commands =
|
||||||
|
./test
|
||||||
|
pre-commit run --all-files
|
||||||
|
|
||||||
|
[testenv:pre-commit]
|
||||||
|
commands = pre-commit {posargs}
|
Loading…
Reference in a new issue