Merge pull request #22 from linuxserver/mod-bionic

adding pre-init modification logic
pull/30/head 5863f05e-pkg-5863f05e-ls7
aptalca 2019-05-01 18:21:01 -04:00 zatwierdzone przez GitHub
commit 8249d09c77
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
3 zmienionych plików z 321 dodań i 0 usunięć

80
root/docker-mods 100755
Wyświetl plik

@ -0,0 +1,80 @@
#!/usr/bin/with-contenv bash
# Exit if mods is not set
if [ -z ${DOCKER_MODS+x} ]; then
exit 0
fi
# Check for curl
if [ ! -f /usr/bin/curl ]; then
echo "[mod-init] Curl was not found on this system for Docker mods installing"
if [ -f /usr/bin/apt ]; then
## Ubuntu
apt-get update
apt-get install --no-install-recommends -y \
curl
elif [ -f /sbin/apk ]; then
# Alpine
apk add --no-cache \
curl
fi
fi
# Main run logic
echo "[mod-init] Attempting to run Docker Modification Logic"
IFS='|'
DOCKER_MODS=(${DOCKER_MODS})
for DOCKER_MOD in "${DOCKER_MODS[@]}"; do
FILENAME=$(echo ${DOCKER_MOD} | sed 's/[:\/]/./g')
ENDPOINT=$(echo ${DOCKER_MOD} | awk -F: '{print $1}')
USERNAME=$(echo ${ENDPOINT} | awk -F/ '{print $1}')
TAG=$(echo ${DOCKER_MOD} | awk -F: '{print $2}')
# Kill off modification logic if any of the usernames are banned
BLACKLIST=$(curl -s https://raw.githubusercontent.com/linuxserver/docker-mods/master/blacklist.txt)
IFS=$'\n'
BLACKLIST=(${BLACKLIST})
for BANNED in "${BLACKLIST[@]}"; do
if [ "${BANNED}" == "${USERNAME,,}" ]; then
if [ -z ${RUN_BANNED_MODS+x} ]; then
echo "[mod-init] ${DOCKER_MOD} is banned from use due to reported abuse aborting mod logic"
exit 0
else
echo "[mod-init] You have chosen to run banned mods ${DOCKER_MOD} will be applied"
fi
fi
done
echo "[mod-init] Applying ${DOCKER_MOD} files to container"
# Get Dockerhub token for api operations
TOKEN=\
"$(curl \
--silent \
--header 'GET' \
"https://auth.docker.io/token?service=registry.docker.io&scope=repository:${ENDPOINT}:pull" \
| awk -F'"' '{print $4}' \
)"
# Determine first and only layer of image
SHALAYER=\
"$(curl \
--silent \
--location \
--request GET \
--header "Authorization: Bearer ${TOKEN}" \
https://registry-1.docker.io/v2/${ENDPOINT}/manifests/${TAG} \
|grep -m1 "blobSum" \
| awk -F'"' '{print $4}' \
)"
# Check if we have allready applied this layer
if [ -f "/${FILENAME}" ] && [ "${SHALAYER}" == "$(cat /${FILENAME})" ]; then
echo "[mod-init] ${DOCKER_MOD} at ${SHALAYER} has been previously applied skipping"
else
# Download and extract layer to /
curl \
--silent \
--location \
--request GET \
--header "Authorization: Bearer ${TOKEN}" \
"https://registry-1.docker.io/v2/${ENDPOINT}/blobs/${SHALAYER}" \
| tar xz -C /
echo ${SHALAYER} > "/${FILENAME}"
fi
done

Wyświetl plik

@ -0,0 +1,15 @@
#!/usr/bin/with-contenv bash
# Make sure custom script directory exists and has files in it
SCRIPTS_DIR="/config/custom-init-scripts"
if [ -e "${SCRIPTS_DIR}" ] && \
[ -n "$(/bin/ls -A ${SCRIPTS_DIR} 2>/dev/null)" ]; then
echo "[custom-init] files found in ${SCRIPTS_DIR} executing"
for SCRIPT in ${SCRIPTS_DIR}/*; do
echo "[custom-init] ${SCRIPT}: executing..."
/bin/bash ${SCRIPT}
echo "[custom-init] ${SCRIPT}: exited $?"
done
else
echo "[custom-init] no custom scripts found exiting..."
fi

Wyświetl plik

@ -0,0 +1,226 @@
#!/bin/execlineb -S0
# This file is executed (not as process 1!) as soon as s6-svscan
# starts, with the original stdin/out/err, but NOT the original
# environment.
# Purpose of this file: to perform all the one-time initialization tasks.
# Merge environments from our custom stage into current context
s6-envdir -I /var/run/s6/env-stage2
# This env decides what to do if stage2 fails
backtick -D 0 -n S6_BEHAVIOUR_IF_STAGE2_FAILS { printcontenv S6_BEHAVIOUR_IF_STAGE2_FAILS }
importas -u S6_BEHAVIOUR_IF_STAGE2_FAILS S6_BEHAVIOUR_IF_STAGE2_FAILS
# This env determines whether user provided files in /etc should be linked
# or copied into /var/run/s6
backtick -D 0 -n S6_READ_ONLY_ROOT { printcontenv S6_READ_ONLY_ROOT }
importas -u S6_READ_ONLY_ROOT S6_READ_ONLY_ROOT
# Docker Mods run logic
foreground
{
/docker-mods
}
foreground
{
if
{
/etc/s6/init/init-stage2-redirfd
foreground
{
##
## copy user provided files to /var/run/s6/etc, depending on S6_RUNTIME_PROFILE env,
## /etc (if not defined) or /etc/cont-profile.d/${S6_RUNTIME_PROFILE} will be used
## as copying source.
##
if
{
if { s6-echo -n -- "[s6-init] making user provided files available at /var/run/s6/etc..." }
foreground
{
backtick -n S6_RUNTIME_PROFILE { printcontenv S6_RUNTIME_PROFILE }
importas -u S6_RUNTIME_PROFILE S6_RUNTIME_PROFILE
backtick -n S6_RUNTIME_PROFILE_SRC {
ifte { s6-echo "/etc/cont-profile.d/${S6_RUNTIME_PROFILE}" } { s6-echo "/etc" }
s6-test -n ${S6_RUNTIME_PROFILE}
}
importas -u S6_RUNTIME_PROFILE_SRC S6_RUNTIME_PROFILE_SRC
if { s6-rmrf /var/run/s6/etc }
if { s6-mkdir -pm 0755 /var/run/s6/etc }
forx i { "fix-attrs.d" "cont-init.d" "cont-finish.d" "services.d" }
importas -u i i
if { s6-test -d ${S6_RUNTIME_PROFILE_SRC}/${i} }
# although s6-hiercopy is prefered, and until it doesn't support 'follow symlinks'
# option, there is no clean way to allow symlinks between user provided runcoms.
ifelse { s6-test ${S6_READ_ONLY_ROOT} -eq 0 } {
s6-ln -s ${S6_RUNTIME_PROFILE_SRC}/${i} /var/run/s6/etc/${i}
}
if { s6-hiercopy ${S6_RUNTIME_PROFILE_SRC}/${i} /var/run/s6/etc/${i} }
}
importas -u ? ?
if { s6-echo -- "exited ${?}." }
ifelse { s6-test ${S6_BEHAVIOUR_IF_STAGE2_FAILS} -eq 0 } { exit 0 }
exit ${?}
}
##
## fix-attrs: ensure user-provided files have correct ownership & perms
##
if
{
if { s6-echo -n -- "[s6-init] ensuring user provided files have correct perms..." }
foreground { redirfd -r 0 /etc/s6/init/init-stage2-fixattrs.txt fix-attrs }
importas -u ? ?
if { s6-echo -- "exited ${?}." }
ifelse { s6-test ${S6_BEHAVIOUR_IF_STAGE2_FAILS} -eq 0 } { exit 0 }
exit ${?}
}
##
## fix-attrs.d: apply user-provided ownership & permission fixes
##
if
{
if -t { s6-test -d /var/run/s6/etc/fix-attrs.d }
if { s6-echo "[fix-attrs.d] applying ownership & permissions fixes..." }
if
{
pipeline { s6-ls -0 -- /var/run/s6/etc/fix-attrs.d }
pipeline { s6-sort -0 -- }
forstdin -0 -- i
importas -u i i
if { s6-echo -- "[fix-attrs.d] ${i}: applying... " }
foreground { redirfd -r 0 /var/run/s6/etc/fix-attrs.d/${i} fix-attrs }
importas -u ? ?
if { s6-echo -- "[fix-attrs.d] ${i}: exited ${?}." }
ifelse { s6-test ${S6_BEHAVIOUR_IF_STAGE2_FAILS} -eq 0 } { exit 0 }
exit ${?}
}
if { s6-echo -- "[fix-attrs.d] done." }
}
##
## cont-init.d: one-time init scripts
##
if
{
if -t { s6-test -d /var/run/s6/etc/cont-init.d }
if { s6-echo "[cont-init.d] executing container initialization scripts..." }
if
{
pipeline { s6-ls -0 -- /var/run/s6/etc/cont-init.d }
pipeline { s6-sort -0 -- }
forstdin -o 0 -0 -- i
importas -u i i
if { s6-echo -- "[cont-init.d] ${i}: executing... " }
foreground { /var/run/s6/etc/cont-init.d/${i} }
importas -u ? ?
if { s6-echo -- "[cont-init.d] ${i}: exited ${?}." }
ifelse { s6-test ${S6_BEHAVIOUR_IF_STAGE2_FAILS} -eq 0 } { exit 0 }
exit ${?}
}
if { s6-echo -- "[cont-init.d] done." }
}
##
## services.d: long-lived processes to be supervised
##
if
{
if -t { s6-test -d /var/run/s6/etc/services.d }
if { s6-echo "[services.d] starting services" }
if
{
pipeline { s6-ls -0 -- /var/run/s6/etc/services.d }
forstdin -0 -p -- i
importas -u i i
if { s6-test -d /var/run/s6/etc/services.d/${i} }
s6-hiercopy /var/run/s6/etc/services.d/${i} /var/run/s6/services/${i}
}
if { s6-svscanctl -a /var/run/s6/services }
if
{
# This envs decide if CMD should wait until services are up
backtick -D 0 -n S6_CMD_WAIT_FOR_SERVICES { printcontenv S6_CMD_WAIT_FOR_SERVICES }
importas -u S6_CMD_WAIT_FOR_SERVICES S6_CMD_WAIT_FOR_SERVICES
backtick -D 5000 -n S6_CMD_WAIT_FOR_SERVICES_MAXTIME { printcontenv S6_CMD_WAIT_FOR_SERVICES_MAXTIME }
importas -u S6_CMD_WAIT_FOR_SERVICES_MAXTIME S6_CMD_WAIT_FOR_SERVICES_MAXTIME
if -t { if { s6-test ${S6_CMD_WAIT_FOR_SERVICES} -ne 0 } s6-test $# -ne 0 }
s6-maximumtime -t ${S6_CMD_WAIT_FOR_SERVICES_MAXTIME}
pipeline { s6-ls -0 -- /var/run/s6/etc/services.d }
forstdin -0 -o 0 -- i
importas -u i i
ifelse { s6-test -f /var/run/s6/services/${i}/down } { exit 0 }
ifelse { s6-test -f /var/run/s6/services/${i}/notification-fd }
{
s6-svwait -t ${S6_CMD_WAIT_FOR_SERVICES_MAXTIME} -U /var/run/s6/services/${i}
}
s6-svwait -t ${S6_CMD_WAIT_FOR_SERVICES_MAXTIME} -u /var/run/s6/services/${i}
}
if { s6-echo -- "[services.d] done." }
}
}
importas -u ? ?
ifelse { s6-test ${S6_BEHAVIOUR_IF_STAGE2_FAILS} -eq 0 } { exit 0 }
# Make stage2 exit code available in stage3
foreground { redirfd -w 1 /var/run/s6/env-stage3/S6_STAGE2_EXITED s6-echo -n -- "${?}" }
exit ${?}
}
##
## The init is complete, If the user has a given CMD, run it now, then
## kill everything when it exits.
##
if -t { s6-test $# -ne 0 }
foreground {
s6-setsid -gq -- with-contenv
backtick -D 0 -n S6_LOGGING { printcontenv S6_LOGGING }
importas S6_LOGGING S6_LOGGING
ifelse { s6-test ${S6_LOGGING} -eq 2 }
{
redirfd -w 1 /var/run/s6/uncaught-logs-fifo
fdmove -c 2 1
$@
}
$@
}
importas -u ? ?
foreground {
/etc/s6/init/init-stage2-redirfd
s6-echo -- "[cmd] ${1} exited ${?}"
}
# Make CMD exit code available in stage3
foreground { redirfd -w 1 /var/run/s6/env-stage3/S6_STAGE2_EXITED s6-echo -n -- "${?}" }
# Stop supervision tree
foreground { s6-svscanctl -t /var/run/s6/services }
# Wait to be nuked
s6-pause -th
}
importas -u ? ?
if { s6-test ${?} -ne 0 }
if { s6-test ${S6_BEHAVIOUR_IF_STAGE2_FAILS} -ne 0 }
ifelse { s6-test ${S6_BEHAVIOUR_IF_STAGE2_FAILS} -ne 1 }
{
s6-svscanctl -t /var/run/s6/services
}
s6-echo -- "\n!!!!!\n init-stage2 failed.\n!!!!!"