Skip to content

Commit

Permalink
feat(docker): /container-init.d for advanced initialization (#6577)
Browse files Browse the repository at this point in the history
* Add initialization directory support to Docker image
* Add sharness test, fix bugs in init script
Fixed in init script:
- Added some missing quotes around expansions
- Fixed INIT_ARGS to not pass any args if IPFS_PROFILE isn't specified
- Use printf instead of "echo -e"
- Only run scripts in top-level of init dir
- Handle filenames correctly when finding init scripts (by using find + xargs)

* chore: docker cleanup
cleans up containers and images (useful when run on developer machine)

* remove container init documentation from README
There is already IPFS Docker documentation where this should live:
https://docs.ipfs.io/how-to/run-ipfs-inside-docker/

Co-authored-by: Caian <caian@ggaunicamp.com>
Co-authored-by: Marcin Rataj <lidel@lidel.org>
Co-authored-by: Gus Eggert <gus@gus.dev>
  • Loading branch information
4 people authored Apr 12, 2022
1 parent bb68a68 commit 63b0025
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 12 deletions.
5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ LABEL maintainer="Steven Allen <steven@stebalien.com>"
ENV SRC_DIR /go-ipfs
COPY --from=0 $SRC_DIR/cmd/ipfs/ipfs /usr/local/bin/ipfs
COPY --from=0 $SRC_DIR/bin/container_daemon /usr/local/bin/start_ipfs
COPY --from=0 $SRC_DIR/bin/container_init_run /usr/local/bin/container_init_run
COPY --from=0 /tmp/su-exec/su-exec-static /sbin/su-exec
COPY --from=0 /tmp/tini /sbin/tini
COPY --from=0 /bin/fusermount /usr/local/bin/fusermount
Expand Down Expand Up @@ -93,6 +94,10 @@ RUN mkdir -p $IPFS_PATH \
RUN mkdir /ipfs /ipns \
&& chown ipfs:users /ipfs /ipns

# Create the init scripts directory
RUN mkdir /container-init.d \
&& chown ipfs:users /container-init.d

# Expose the fs-repo as a volume.
# start_ipfs initializes an fs-repo if none is mounted.
# Important this happens after the USER directive so permissions are correct.
Expand Down
19 changes: 9 additions & 10 deletions bin/container_daemon
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#!/bin/sh
set -e

user=ipfs
repo="$IPFS_PATH"

if [ `id -u` -eq 0 ]; then
if [ "$(id -u)" -eq 0 ]; then
echo "Changing user to $user"
# ensure folder is writable
su-exec "$user" test -w "$repo" || chown -R -- "$user" "$repo"
Expand All @@ -14,14 +15,11 @@ fi
# 2nd invocation with regular user
ipfs version


if [ -e "$repo/config" ]; then
echo "Found IPFS fs-repo at $repo"
else
case "$IPFS_PROFILE" in
"") INIT_ARGS="" ;;
*) INIT_ARGS="--profile=$IPFS_PROFILE" ;;
esac
ipfs init $INIT_ARGS
ipfs init ${IPFS_PROFILE:+"--profile=$IPFS_PROFILE"}
ipfs config Addresses.API /ip4/0.0.0.0/tcp/5001
ipfs config Addresses.Gateway /ip4/0.0.0.0/tcp/8080

Expand All @@ -31,9 +29,9 @@ else
SWARM_KEY_PERM=0400

# Create a swarm key from a given environment variable
if [ ! -z "$IPFS_SWARM_KEY" ] ; then
if [ -n "$IPFS_SWARM_KEY" ] ; then
echo "Copying swarm key from variable..."
echo -e "$IPFS_SWARM_KEY" >"$SWARM_KEY_FILE" || exit 1
printf "%s\n" "$IPFS_SWARM_KEY" >"$SWARM_KEY_FILE" || exit 1
chmod $SWARM_KEY_PERM "$SWARM_KEY_FILE"
fi

Expand All @@ -43,14 +41,15 @@ else
# Check during initialization if a swarm key was provided and
# copy it to the ipfs directory with the right permissions
# WARNING: This will replace the swarm key if it exists
if [ ! -z "$IPFS_SWARM_KEY_FILE" ] ; then
if [ -n "$IPFS_SWARM_KEY_FILE" ] ; then
echo "Copying swarm key from file..."
install -m $SWARM_KEY_PERM "$IPFS_SWARM_KEY_FILE" "$SWARM_KEY_FILE" || exit 1
fi

# Unset the swarm key file variable
unset IPFS_SWARM_KEY_FILE

fi

find /container-init.d -maxdepth 1 -type f -iname '*.sh' -print0 | sort -z | xargs -n 1 -0 -r container_init_run

exec ipfs "$@"
14 changes: 14 additions & 0 deletions bin/container_init_run
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/sh

set -e

# used by the container startup script for running initialization scripts

script="$1"
if [ -x "$script" ] ; then
printf "Executing '%s'...\n" "$script"
"$script"
else
printf "Sourcing '%s'...\n" "$script"
. "$script"
fi
10 changes: 10 additions & 0 deletions test/ipfs-test-lib.sh
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ docker_stop() {
docker stop "$1"
}

# This takes a docker ID as argument
docker_rm() {
docker rm -f -v "$1" > /dev/null
}

# This takes a docker image name as argument
docker_rmi() {
docker rmi -f "$1" > /dev/null
}

# Test whether all the expected lines are included in a file. The file
# can have extra lines.
#
Expand Down
31 changes: 29 additions & 2 deletions test/sharness/t0300-docker-image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ TEST_TESTS_DIR=$(dirname "$TEST_SCRIPTS_DIR")
APP_ROOT_DIR=$(dirname "$TEST_TESTS_DIR")

test_expect_success "docker image build succeeds" '
docker_build "$TEST_TESTS_DIR/../Dockerfile" "$APP_ROOT_DIR" >build-actual ||
docker_build "$TEST_TESTS_DIR/../Dockerfile" "$APP_ROOT_DIR" | tee build-actual ||
test_fsh echo "TEST_TESTS_DIR: $TEST_TESTS_DIR" ||
test_fsh echo "APP_ROOT_DIR : $APP_ROOT_DIR" ||
test_fsh cat build-actual
Expand All @@ -41,8 +41,18 @@ test_expect_success "docker image build output looks good" '
test_fsh cat build-actual
'

test_expect_success "write init scripts" '
echo "ipfs config Foo Bar" > 001.sh &&
echo "ipfs config Baz Qux" > 002.sh &&
chmod +x 002.sh
'

test_expect_success "docker image runs" '
DOC_ID=$(docker run -d -p 127.0.0.1:5001:5001 -p 127.0.0.1:8080:8080 "$IMAGE_ID")
DOC_ID=$(docker run -d \
-p 127.0.0.1:5001:5001 -p 127.0.0.1:8080:8080 \
-v "$PWD/001.sh":/container-init.d/001.sh \
-v "$PWD/002.sh":/container-init.d/002.sh \
"$IMAGE_ID")
'

test_expect_success "docker container gateway is up" '
Expand All @@ -53,6 +63,21 @@ test_expect_success "docker container API is up" '
pollEndpoint -host=/ip4/127.0.0.1/tcp/5001 -http-url http://localhost:5001/version -v -tries 30 -tout 1s
'

test_expect_success "check that init scripts were run correctly and in the correct order" "
echo -e \"Sourcing '/container-init.d/001.sh'...\nExecuting '/container-init.d/002.sh'...\" > expected &&
docker logs $DOC_ID 2>/dev/null | grep -e 001.sh -e 002.sh > actual &&
test_cmp actual expected
"

test_expect_success "check that init script configs were applied" '
echo Bar > expected &&
docker exec "$DOC_ID" ipfs config Foo > actual &&
test_cmp actual expected &&
echo Qux > expected &&
docker exec "$DOC_ID" ipfs config Baz > actual &&
test_cmp actual expected
'

test_expect_success "simple ipfs add/cat can be run in docker container" '
expected="Hello Worlds" &&
HASH=$(docker_exec "$DOC_ID" "echo $(cat expected) | ipfs add | cut -d' ' -f2") &&
Expand All @@ -74,5 +99,7 @@ test_expect_success "stop docker container" '
docker_stop "$DOC_ID"
'

docker_rm "$DOC_ID"
docker_rmi "$IMAGE_ID"
test_done

2 changes: 2 additions & 0 deletions test/sharness/t0301-docker-migrate.sh
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,7 @@ test_expect_success "correct version was requested" '
grep "/fs-repo-6-to-7/v1.1.1/fs-repo-6-to-7_v1.1.1_linux-amd64.tar.gz" dist_serv_out > /dev/null
'

docker_rm "$DOC_ID"
docker_rmi "$IMAGE_ID"
test_done

0 comments on commit 63b0025

Please sign in to comment.