initial commit
This commit is contained in:
commit
fb47c39af5
198
Dockerfile
Normal file
198
Dockerfile
Normal file
@ -0,0 +1,198 @@
|
||||
FROM docker.io/rockdrilla/angie-conv:deps-v1 as deps
|
||||
|
||||
## ---
|
||||
|
||||
FROM deps as certs
|
||||
SHELL [ "/bin/sh", "-ec" ]
|
||||
|
||||
COPY /scripts/* /usr/local/sbin/
|
||||
COPY /extra-scripts/* /usr/local/sbin/
|
||||
|
||||
## consult https://github.com/certifi/python-certifi/
|
||||
ENV CERTIFI_COMMIT=bd8153872e9c6fc98f4023df9c2deaffea2fa463
|
||||
|
||||
RUN pkg='curl' ; \
|
||||
apt-install.sh ca-certificates ${pkg} ; \
|
||||
## process certifi
|
||||
ls -l /etc/ssl/certs/ca-certificates.crt ; \
|
||||
certifi-extras.sh ; \
|
||||
ls -l /etc/ssl/certs/ca-certificates.crt
|
||||
|
||||
## ---
|
||||
|
||||
FROM deps as pycache
|
||||
SHELL [ "/bin/sh", "-ec" ]
|
||||
|
||||
COPY /scripts/* /usr/local/sbin/
|
||||
COPY /extra-scripts/* /usr/local/sbin/
|
||||
|
||||
ENV PYTHONDONTWRITEBYTECODE=''
|
||||
|
||||
## Python cache preseed
|
||||
RUN libpython="${PYTHON_SITE_PACKAGES%/*}" ; \
|
||||
find "${libpython}/" -mindepth 1 -maxdepth 1 -printf '%P\0' \
|
||||
| sed -zEn \
|
||||
-e '/^(asyncio|collections|concurrent|encodings|html|importlib|json|logging|multiprocessing|re|urllib|xml)$/p' \
|
||||
| sort -zV \
|
||||
| env -C "${libpython}" xargs -0r \
|
||||
python3 -m compileall -q -j 2 ; \
|
||||
find "${PYTHON_SITE_PACKAGES}/" -mindepth 1 -maxdepth 1 -printf '%P\0' \
|
||||
| sed -zE \
|
||||
-e '/\.(dist-info|pth|txt)$/d' \
|
||||
-e '/^(pip|pkg_resources|setuptools|wheel)$/d' \
|
||||
| sort -zV \
|
||||
| env -C "${PYTHON_SITE_PACKAGES}" xargs -0r \
|
||||
python3 -m compileall -q -j 2
|
||||
|
||||
## Python cache warmup
|
||||
RUN python3 -m site > /dev/null ; \
|
||||
echo > /tmp/f.j2 ; \
|
||||
jinja.py /tmp/f.j2 ; \
|
||||
pip-env.sh pip list -v >/dev/null ; \
|
||||
find "${PYTHON_SITE_PACKAGES}/pip/" -name __pycache__ -exec rm -rf {} +
|
||||
|
||||
## Python cache adjustments
|
||||
RUN d="@$(date '+%s')" ; \
|
||||
libpython="${PYTHON_SITE_PACKAGES%/*}" ; \
|
||||
find "${libpython}/" -name '*.pyc' -exec touch -m -d "$d" {} + ; \
|
||||
find "${libpython}/" -name __pycache__ -exec touch -m -d "$d" {} +
|
||||
|
||||
## ---
|
||||
|
||||
FROM deps
|
||||
SHELL [ "/bin/sh", "-ec" ]
|
||||
|
||||
## NB: NGX_DEBUG is set via build script
|
||||
|
||||
COPY /Dockerfile /usr/local/share/
|
||||
|
||||
COPY --from=certs /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
|
||||
COPY --from=certs /usr/local/share/ca-certificates/ /usr/local/share/ca-certificates/
|
||||
|
||||
## RFC: Python cache
|
||||
## TODO: reduce load by selecting only __pycache__ directories in either way
|
||||
# COPY --from=pycache /usr/local/lib/ /usr/local/lib/
|
||||
|
||||
ENV ANGIE_MODULES_DIR=/usr/lib/angie/modules
|
||||
|
||||
COPY /scripts/* /usr/local/bin/
|
||||
|
||||
RUN _UID=11111 _GID=11111 ; \
|
||||
echo "angie:x:${_UID}:${_GID}:Angie:/etc/angie:/bin/false" >> /etc/passwd ; \
|
||||
echo "angie:x:${_GID}:" >> /etc/group ; \
|
||||
echo 'angie:!:::::::' >> /etc/shadow
|
||||
|
||||
RUN apt-install.sh angie ; \
|
||||
apt-clean.sh ; \
|
||||
## verify Angie layout
|
||||
[ -d "${ANGIE_MODULES_DIR}" ] ; \
|
||||
n='/usr/sbin/angie' ; \
|
||||
[ -x "$n-debug" ] ; \
|
||||
[ -x "$n-nodebug" ] ; \
|
||||
## adjust Angie binaries
|
||||
rm -fv "$n" ; \
|
||||
if [ "${NGX_DEBUG}" = 0 ] ; then \
|
||||
rm -fv "$n-debug" ; \
|
||||
mv -fv "$n-nodebug" "$n" ; \
|
||||
ln -fsv "${n##*/}" "$n-nodebug" ; \
|
||||
ln -fsv /bin/false "$n-debug" ; \
|
||||
else \
|
||||
rm -fv "$n-nodebug" ; \
|
||||
mv -fv "$n-debug" "$n" ; \
|
||||
ln -fsv "${n##*/}" "$n-debug" ; \
|
||||
ln -fsv /bin/false "$n-nodebug" ; \
|
||||
fi
|
||||
|
||||
## preserve snippets from Angie config directory
|
||||
## ref: https://git.angie.software/web-server/angie/src/tag/Angie-1.6.0/conf
|
||||
RUN d=/etc/angie ; t=$(mktemp -d) ; \
|
||||
tar -C "$d" -cf - \
|
||||
fastcgi_params \
|
||||
fastcgi.conf \
|
||||
mime.types \
|
||||
prometheus_all.conf \
|
||||
scgi_params \
|
||||
uwsgi_params \
|
||||
| tar -C "$t" -xf - ; \
|
||||
rm -rf "$d" ; \
|
||||
install -d "$d" "$d/snip.dist" ; \
|
||||
tar -C "$t" -cf - . | tar -C "$d/snip.dist" -xf - ; \
|
||||
rm -rf "$t" ; \
|
||||
chown -hR 0:0 "$d" ; \
|
||||
chmod go-w "$d" ; \
|
||||
find "$d/" -type f -exec chmod 0644 {} +
|
||||
|
||||
## produce own layout for Angie >:)
|
||||
## /angie/ is persistence store
|
||||
RUN install -d -o angie -g angie -m 03777 /angie /run/angie ; \
|
||||
## adjust paths across filesystem
|
||||
rm -rfv /var/cache/angie/ /var/lib/angie/ /var/log/angie/ ; \
|
||||
ln -sv /run/angie/cache /var/cache/angie ; \
|
||||
ln -sv /run/angie/lib /var/lib/angie ; \
|
||||
ln -sv /run/angie/log /var/log/angie ; \
|
||||
## adjust paths in config directory
|
||||
cd /etc/angie/ ; \
|
||||
ln -sv /run/angie run ; \
|
||||
ln -sv /run/angie/lock lock.d ; \
|
||||
ln -sv ${ANGIE_MODULES_DIR} modules.dist ; \
|
||||
## hyper-modular paths:
|
||||
data='conf mod modules njs site snip static' ; \
|
||||
vardata='cache lib log' ; \
|
||||
for n in ${data} ; do \
|
||||
for d in "$n" "$n.dist" ; do \
|
||||
[ -e "$d" ] || install -d "$d" ; \
|
||||
done ; \
|
||||
done ; \
|
||||
for n in ${data} ${vardata} ; do \
|
||||
ln -sv "/run/angie/$n" "$n.d" ; \
|
||||
done
|
||||
|
||||
VOLUME [ "/run/angie" ]
|
||||
|
||||
COPY /angie/ /etc/angie/
|
||||
RUN find /etc/angie/ -name .gitkeep -delete ; \
|
||||
find /etc/angie/ ! -type l -exec chmod go-w {} +
|
||||
|
||||
## misc tools
|
||||
RUN apt-install.sh \
|
||||
brotli \
|
||||
zstd \
|
||||
; \
|
||||
apt-clean.sh
|
||||
|
||||
## relatively lightweight modules
|
||||
RUN apt-install-angie-mod.sh \
|
||||
auth-jwt \
|
||||
auth-spnego \
|
||||
brotli \
|
||||
cache-purge \
|
||||
echo \
|
||||
geoip2 \
|
||||
headers-more \
|
||||
subs \
|
||||
testcookie \
|
||||
upload \
|
||||
zip \
|
||||
zstd \
|
||||
; \
|
||||
apt-clean.sh
|
||||
|
||||
## image-entry.sh is placed into /usr/local/bin/ to allow custom entrypoint/chaining:
|
||||
## - there's no need to change ENTRYPOINT/CMD
|
||||
## - custom entrypoint should be placed in /usr/local/sbin/
|
||||
## - custom entrypoint should "exec" /usr/local/bin/image-entry.sh
|
||||
COPY /image-entry.sh /usr/local/bin/
|
||||
COPY /image-entry.d/ /image-entry.d/
|
||||
|
||||
## must be bind-mounted only for local customization/overrides!
|
||||
# RUN install -d /image-entry
|
||||
|
||||
## misc defaults
|
||||
ENV DUMB_INIT_SETSID=0 \
|
||||
MALLOC_ARENA_MAX=4 \
|
||||
GOMAXPROCS=4
|
||||
|
||||
STOPSIGNAL SIGQUIT
|
||||
|
||||
ENTRYPOINT [ "image-entry.sh" ]
|
||||
CMD [ "angie", "-g", "daemon off;" ]
|
227
Dockerfile.base
Normal file
227
Dockerfile.base
Normal file
@ -0,0 +1,227 @@
|
||||
# FROM docker.io/debian:bookworm-slim as base-upstream
|
||||
ARG PYTHONTAG=3.11.9-slim-bookworm
|
||||
FROM docker.io/python:${PYTHONTAG} as base-upstream
|
||||
|
||||
FROM base-upstream as base
|
||||
SHELL [ "/bin/sh", "-ec" ]
|
||||
|
||||
COPY /Dockerfile.base /usr/local/share/
|
||||
|
||||
COPY /scripts/* /usr/local/sbin/
|
||||
COPY /extra-scripts/* /usr/local/sbin/
|
||||
|
||||
## PATH: remove /sbin and /bin (/usr is merged)
|
||||
ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin \
|
||||
TMPDIR=/tmp \
|
||||
LANG=C.UTF-8 \
|
||||
LC_ALL=C.UTF-8 \
|
||||
TERM=linux \
|
||||
TZ=Etc/UTC \
|
||||
MALLOC_ARENA_MAX=2 \
|
||||
PYTHONUNBUFFERED=1 \
|
||||
PYTHONDONTWRITEBYTECODE=1
|
||||
|
||||
## local development
|
||||
# ENV PIP_INDEX="http://127.0.0.1:8081/repository/proxy_pypi/pypi/" \
|
||||
# PIP_INDEX_URL="http://127.0.0.1:8081/repository/proxy_pypi/simple/" \
|
||||
# PIP_TRUSTED_HOST="localhost"
|
||||
|
||||
COPY /apt/prefs.backports /etc/apt/preferences.d/backports
|
||||
COPY /apt/sources.debian /etc/apt/sources.list.d/debian.sources
|
||||
|
||||
## prevent services from auto-starting, part 1
|
||||
RUN s='/usr/sbin/policy-rc.d' ; b='/usr/bin/policy-rc.d' ; \
|
||||
rm -f "$s" "$b" ; \
|
||||
echo '#!/bin/sh' > "$b" ; \
|
||||
echo 'exit 101' >> "$b" ; \
|
||||
chmod 0755 "$b" ; \
|
||||
ln -s "$b" "$s"
|
||||
|
||||
RUN divert_true() { divert-rm.sh "$1" ; ln -sv /bin/true "$1" ; } ; \
|
||||
## prevent services from auto-starting, part 2
|
||||
divert_true /sbin/start-stop-daemon ; \
|
||||
## always report that we're in chroot
|
||||
divert_true /usr/bin/ischroot ; \
|
||||
## hide systemd helpers
|
||||
divert_true /usr/bin/deb-systemd-helper ; \
|
||||
divert_true /usr/bin/deb-systemd-invoke
|
||||
|
||||
RUN apt-env.sh apt-get update ; \
|
||||
apt-env.sh apt-get upgrade -y ; \
|
||||
apt-clean.sh
|
||||
|
||||
## perl-base: hardlink->symlink
|
||||
RUN d=/usr/bin ; \
|
||||
find $d/ -wholename "$d/perl5*" -exec ln -fsv perl {} ';' ; \
|
||||
ls -li $d/perl*
|
||||
|
||||
## remove unwanted binaries
|
||||
RUN set -f ; \
|
||||
for i in \
|
||||
addgroup \
|
||||
addpart \
|
||||
adduser \
|
||||
apt-ftparchive \
|
||||
agetty \
|
||||
badblocks \
|
||||
blkdiscard \
|
||||
blkid \
|
||||
blkzone \
|
||||
blockdev \
|
||||
bsd-write \
|
||||
chage \
|
||||
chcpu \
|
||||
chfn \
|
||||
chgpasswd \
|
||||
chmem \
|
||||
chpasswd \
|
||||
chsh \
|
||||
cpgr \
|
||||
cppw \
|
||||
ctrlaltdel \
|
||||
debugfs \
|
||||
delgroup \
|
||||
delpart \
|
||||
deluser \
|
||||
dmesg \
|
||||
dumpe2fs \
|
||||
e2freefrag \
|
||||
e2fsck \
|
||||
e2image \
|
||||
e2label \
|
||||
e2mmpstatus \
|
||||
e2scrub \
|
||||
'e2scrub*' \
|
||||
e2undo \
|
||||
e4crypt \
|
||||
e4defrag \
|
||||
expiry \
|
||||
faillock \
|
||||
fdformat \
|
||||
fincore \
|
||||
findfs \
|
||||
fsck \
|
||||
'fsck.*' \
|
||||
fsfreeze \
|
||||
fstrim \
|
||||
getty \
|
||||
gpasswd \
|
||||
groupadd \
|
||||
groupdel \
|
||||
groupmems \
|
||||
groupmod \
|
||||
grpck \
|
||||
grpconv \
|
||||
grpunconv \
|
||||
hwclock \
|
||||
isosize \
|
||||
last \
|
||||
lastb \
|
||||
ldattach \
|
||||
losetup \
|
||||
lsblk \
|
||||
lsirq \
|
||||
lslogins \
|
||||
mcookie \
|
||||
mesg \
|
||||
mke2fs \
|
||||
mkfs \
|
||||
'mkfs.*' \
|
||||
mkhomedir_helper \
|
||||
mklost+found \
|
||||
mkswap \
|
||||
mount \
|
||||
newgrp \
|
||||
newusers \
|
||||
pam-auth-update \
|
||||
pam_getenv \
|
||||
pam_namespace_helper \
|
||||
pam_timestamp_check \
|
||||
partx \
|
||||
passwd \
|
||||
pivot_root \
|
||||
pwck \
|
||||
pwconv \
|
||||
pwhistory_helper \
|
||||
pwunconv \
|
||||
raw \
|
||||
readprofile \
|
||||
resize2fs \
|
||||
resizepart \
|
||||
rtcwake \
|
||||
sg \
|
||||
shadowconfig \
|
||||
su \
|
||||
sulogin \
|
||||
swaplabel \
|
||||
swapoff \
|
||||
swapon \
|
||||
switch_root \
|
||||
tune2fs \
|
||||
umount \
|
||||
unix_chkpwd \
|
||||
unix_update \
|
||||
update-passwd \
|
||||
useradd \
|
||||
userdel \
|
||||
usermod \
|
||||
utmpdump \
|
||||
vigr \
|
||||
vipw \
|
||||
wall \
|
||||
wdctl \
|
||||
wipefs \
|
||||
write \
|
||||
'write.*' \
|
||||
zramctl \
|
||||
; do \
|
||||
for d in /usr/sbin /usr/bin /sbin /bin ; do \
|
||||
find "$d/" ! -type d -wholename "$d/$i" \
|
||||
| while read -r p ; do \
|
||||
[ -n "$p" ] || continue ; \
|
||||
[ -e "$p" ] || continue ; \
|
||||
dpkg -S "$p" >/dev/null 2>&1 || continue ; \
|
||||
divert-rm.sh "$p" ; \
|
||||
done ; \
|
||||
done ; \
|
||||
for d in /usr/sbin /usr/bin /sbin /bin ; do \
|
||||
find "$d/" ! -type d -wholename "$d/$i" \
|
||||
| while read -r p ; do \
|
||||
[ -n "$p" ] || continue ; \
|
||||
[ -e "$p" ] || continue ; \
|
||||
rm -fv "$p" ; \
|
||||
done ; \
|
||||
done ; \
|
||||
done
|
||||
|
||||
RUN apt-remove.sh \
|
||||
ca-certificates \
|
||||
e2fsprogs \
|
||||
; \
|
||||
apt-clean.sh
|
||||
|
||||
## "docker.io/python"-specific cleanup
|
||||
RUN rm -f /root/.wget-hsts
|
||||
|
||||
RUN pip-env.sh pip list --format freeze \
|
||||
| grep -F '==' | awk -F= '{print $1}' \
|
||||
| xargs -r pip-env.sh pip install -U ; \
|
||||
python-rm-cache.sh "${PYTHON_SITE_PACKAGES}"
|
||||
|
||||
RUN libpython="${PYTHON_SITE_PACKAGES%/*}" ; \
|
||||
rm -rfv \
|
||||
/usr/local/bin/idle* \
|
||||
"${libpython}/ensurepip/_bundled" \
|
||||
"${libpython}/idlelib" \
|
||||
"${libpython}/tkinter" \
|
||||
"${libpython}/turtle.py" \
|
||||
"${libpython}/turtledemo" \
|
||||
; \
|
||||
python-rm-cache.sh /usr/local
|
||||
|
||||
RUN find /usr/local/sbin/ ! -type d -ls -delete ; \
|
||||
find /run/ -mindepth 1 -ls -delete || : ; \
|
||||
install -d -m 01777 /run/lock
|
||||
|
||||
ENTRYPOINT [ ]
|
||||
CMD [ "bash" ]
|
96
Dockerfile.deps
Normal file
96
Dockerfile.deps
Normal file
@ -0,0 +1,96 @@
|
||||
FROM docker.io/rockdrilla/angie-conv:base-v1 as base
|
||||
|
||||
## ---
|
||||
|
||||
FROM base as setup
|
||||
SHELL [ "/bin/sh", "-ec" ]
|
||||
|
||||
COPY /scripts/* /usr/local/sbin/
|
||||
COPY /extra-scripts/* /usr/local/sbin/
|
||||
|
||||
ADD https://angie.software/keys/angie-signing.gpg /tmp/angie.gpg.bin
|
||||
COPY /apt/sources.angie /etc/apt/sources.list.d/angie.txt
|
||||
|
||||
RUN pkg='gnupg' ; \
|
||||
apt-install.sh ${pkg} ; \
|
||||
## process Angie GPG keyring / APT sources
|
||||
gpg-export.sh /tmp/angie.gpg.bin /etc/apt/keyrings/angie.gpg.asc ; \
|
||||
rm -f /tmp/angie.gpg.bin ; \
|
||||
env -C /etc/apt/sources.list.d mv angie.txt angie.sources ; \
|
||||
## verify sources!
|
||||
apt-env.sh apt-get update ; \
|
||||
apt-remove.sh ${pkg} ; \
|
||||
apt-clean.sh
|
||||
|
||||
ENV INSTALL_WHEELS='jinja2 netaddr psutil pyyaml wcmatch'
|
||||
ENV DEV_PACKAGES='libyaml-dev'
|
||||
# markupsafe, psutil
|
||||
ENV CIBUILDWHEEL=1
|
||||
# pyyaml
|
||||
ENV PYYAML_FORCE_CYTHON=1
|
||||
|
||||
RUN w=$(mktemp -d) ; \
|
||||
{ apt-mark showauto ; apt-mark showmanual ; } | sort -uV > "$w/t0" ; \
|
||||
printf '%s\n' ${DEV_PACKAGES} | sort -uV > "$w/t1" ; \
|
||||
apt-install.sh ${DEV_PACKAGES} ; \
|
||||
{ apt-mark showauto ; apt-mark showmanual ; } | sort -uV > "$w/t2" ; \
|
||||
set +e ; \
|
||||
grep -Fxv -f "$w/t0" "$w/t2" > "$w/t3" ; \
|
||||
grep -Fxv -f "$w/t1" "$w/t3" > "$w/t4" ; \
|
||||
grep -Ev -e '-(dev|doc)$' "$w/t4" > "${PYTHON_SITE_PACKAGES}/apt-deps.txt" ; \
|
||||
set -e ; \
|
||||
rm -rf "$w/" ; unset w ; \
|
||||
apt-install.sh build-essential ; \
|
||||
pip-env.sh pip install 'cython' ; \
|
||||
pip-env.sh pip install --no-binary :all: ${INSTALL_WHEELS} ; \
|
||||
pip-env.sh pip uninstall -y 'cython' ; \
|
||||
python-rm-cache.sh "${PYTHON_SITE_PACKAGES}" ; \
|
||||
rm -rf \
|
||||
"${PYTHON_SITE_PACKAGES}/psutil/tests" \
|
||||
; \
|
||||
find "${PYTHON_SITE_PACKAGES}/" -type f -name '*.so*' -exec ls -l {} + ; \
|
||||
echo ; \
|
||||
find "${PYTHON_SITE_PACKAGES}/" -type f -name '*.so*' -printf '%p\0' \
|
||||
| sed -zE '/rust/d' \
|
||||
| xargs -0r strip --strip-debug ; \
|
||||
echo ; \
|
||||
find "${PYTHON_SITE_PACKAGES}/" -type f -name '*.so*' -exec ls -l {} + ; \
|
||||
apt-remove.sh build-essential ; \
|
||||
apt-clean.sh
|
||||
|
||||
## ---
|
||||
|
||||
FROM base as deps
|
||||
SHELL [ "/bin/sh", "-ec" ]
|
||||
|
||||
COPY /Dockerfile.deps /usr/local/share/
|
||||
|
||||
COPY --from=setup /etc/apt/keyrings/angie.gpg.asc /etc/apt/keyrings/
|
||||
COPY --from=setup /etc/apt/sources.list.d/angie.sources /etc/apt/sources.list.d/
|
||||
|
||||
## Python: site-packages
|
||||
COPY --from=setup /usr/local/bin/ /usr/local/bin/
|
||||
COPY --from=setup /${PYTHON_SITE_PACKAGES}/ /${PYTHON_SITE_PACKAGES}/
|
||||
|
||||
COPY /scripts/* /usr/local/sbin/
|
||||
|
||||
## install missing dependencies for Python site-packages
|
||||
RUN f="${PYTHON_SITE_PACKAGES}/apt-deps.txt" ; \
|
||||
[ -s "$f" ] || exit 0 ; \
|
||||
xargs -a "$f" apt-install.sh ; \
|
||||
apt-clean.sh
|
||||
|
||||
## common deps
|
||||
RUN apt-install.sh \
|
||||
dumb-init \
|
||||
gettext-base \
|
||||
jq \
|
||||
netbase \
|
||||
netcat-openbsd \
|
||||
openssl \
|
||||
procps \
|
||||
psmisc \
|
||||
; \
|
||||
apt-clean.sh
|
||||
|
||||
RUN find /usr/local/sbin/ ! -type d -ls -delete
|
175
LICENSE
Normal file
175
LICENSE
Normal file
@ -0,0 +1,175 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
22
angie/angie.conf
Normal file
22
angie/angie.conf
Normal file
@ -0,0 +1,22 @@
|
||||
pid run/angie.pid;
|
||||
lock_file lock.d/angie.lock;
|
||||
|
||||
## almost useless
|
||||
include mod.d/core-*.conf;
|
||||
|
||||
# mod-http.conf.in
|
||||
# mod-mail.conf.in
|
||||
# mod-stream.conf.in
|
||||
include run/mod-*.conf;
|
||||
|
||||
events {
|
||||
include conf.d/core_ev-*.conf;
|
||||
include snip.d/core_ev-*.conf;
|
||||
}
|
||||
include conf.d/core-*.conf;
|
||||
include snip.d/core-*.conf;
|
||||
|
||||
# ctx-http.conf.in
|
||||
# ctx-mail.conf.in
|
||||
# ctx-stream.conf.in
|
||||
include run/ctx-*.conf;
|
1
angie/conf.dist/core-error-log.conf
Normal file
1
angie/conf.dist/core-error-log.conf
Normal file
@ -0,0 +1 @@
|
||||
error_log log.d/error.log warn;
|
1
angie/conf.dist/core-pcre-jit.conf
Normal file
1
angie/conf.dist/core-pcre-jit.conf
Normal file
@ -0,0 +1 @@
|
||||
pcre_jit on;
|
3
angie/conf.dist/core-preserve-env.conf.j2
Normal file
3
angie/conf.dist/core-preserve-env.conf.j2
Normal file
@ -0,0 +1,3 @@
|
||||
{% for v in os.getenv('NGX_CORE_ENV', '').split(sep=' ') -%}
|
||||
env {{ v }};
|
||||
{% endfor -%}
|
1
angie/conf.dist/core-user.conf.in
Normal file
1
angie/conf.dist/core-user.conf.in
Normal file
@ -0,0 +1 @@
|
||||
user ${NGX_USER} ${NGX_GROUP};
|
3
angie/conf.dist/core-worker.conf.in
Normal file
3
angie/conf.dist/core-worker.conf.in
Normal file
@ -0,0 +1,3 @@
|
||||
worker_processes ${NGX_WORKER_PROCESSES};
|
||||
worker_priority ${NGX_WORKER_PRIORITY};
|
||||
worker_rlimit_nofile ${NGX_WORKER_RLIMIT_NOFILE};
|
1
angie/conf.dist/core_ev-worker.conf.in
Normal file
1
angie/conf.dist/core_ev-worker.conf.in
Normal file
@ -0,0 +1 @@
|
||||
worker_connections ${NGX_WORKER_CONNECTIONS};
|
12
angie/conf.dist/http-access-log.conf
Normal file
12
angie/conf.dist/http-access-log.conf
Normal file
@ -0,0 +1,12 @@
|
||||
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for"';
|
||||
|
||||
log_format extended '$remote_addr - $remote_user [$time_local] "$request" '
|
||||
'$status $body_bytes_sent "$http_referer" rt="$request_time" '
|
||||
'"$http_user_agent" "$http_x_forwarded_for" '
|
||||
'h="$host" sn="$server_name" ru="$request_uri" u="$uri" '
|
||||
'ucs="$upstream_cache_status" ua="$upstream_addr" us="$upstream_status" '
|
||||
'uct="$upstream_connect_time" urt="$upstream_response_time"';
|
||||
|
||||
access_log log.d/access.log main;
|
1
angie/conf.dist/http-max-ranges.conf.in
Normal file
1
angie/conf.dist/http-max-ranges.conf.in
Normal file
@ -0,0 +1 @@
|
||||
max_ranges ${NGX_HTTP_MAX_RANGES};
|
8
angie/conf.dist/http-mime-types.conf
Normal file
8
angie/conf.dist/http-mime-types.conf
Normal file
@ -0,0 +1,8 @@
|
||||
include snip.d/mime.types;
|
||||
|
||||
types {
|
||||
font/ttf ttf;
|
||||
application/font-sfnt otf;
|
||||
}
|
||||
|
||||
default_type application/octet-stream;
|
5
angie/ctx-http.conf
Normal file
5
angie/ctx-http.conf
Normal file
@ -0,0 +1,5 @@
|
||||
http {
|
||||
include conf.d/http-*.conf;
|
||||
include snip.d/http-*.conf;
|
||||
include site.d/http-*.conf;
|
||||
}
|
5
angie/ctx-mail.conf
Normal file
5
angie/ctx-mail.conf
Normal file
@ -0,0 +1,5 @@
|
||||
mail {
|
||||
include conf.d/mail-*.conf;
|
||||
include snip.d/mail-*.conf;
|
||||
include site.d/mail-*.conf;
|
||||
}
|
5
angie/ctx-stream.conf
Normal file
5
angie/ctx-stream.conf
Normal file
@ -0,0 +1,5 @@
|
||||
stream {
|
||||
include conf.d/stream-*.conf;
|
||||
include snip.d/stream-*.conf;
|
||||
include site.d/stream-*.conf;
|
||||
}
|
1
angie/mod-http.conf
Normal file
1
angie/mod-http.conf
Normal file
@ -0,0 +1 @@
|
||||
include mod.d/http-*.conf;
|
1
angie/mod-mail.conf
Normal file
1
angie/mod-mail.conf
Normal file
@ -0,0 +1 @@
|
||||
include mod.d/mail-*.conf;
|
1
angie/mod-stream.conf
Normal file
1
angie/mod-stream.conf
Normal file
@ -0,0 +1 @@
|
||||
include mod.d/stream-*.conf;
|
0
angie/mod.dist/.brotli.preseed
Normal file
0
angie/mod.dist/.brotli.preseed
Normal file
0
angie/mod.dist/.otel.preseed
Normal file
0
angie/mod.dist/.otel.preseed
Normal file
0
angie/mod.dist/.postgres.preseed
Normal file
0
angie/mod.dist/.postgres.preseed
Normal file
0
angie/mod.dist/.rtmp.preseed
Normal file
0
angie/mod.dist/.rtmp.preseed
Normal file
0
angie/mod.dist/.vts.preseed
Normal file
0
angie/mod.dist/.vts.preseed
Normal file
0
angie/mod.dist/.zstd.preseed
Normal file
0
angie/mod.dist/.zstd.preseed
Normal file
1
angie/mod.dist/http-brotli-filter.conf
Normal file
1
angie/mod.dist/http-brotli-filter.conf
Normal file
@ -0,0 +1 @@
|
||||
load_module modules.d/ngx_http_brotli_filter_module.so;
|
1
angie/mod.dist/http-brotli-static.conf
Normal file
1
angie/mod.dist/http-brotli-static.conf
Normal file
@ -0,0 +1 @@
|
||||
load_module modules.d/ngx_http_brotli_static_module.so;
|
2
angie/mod.dist/http-brotli.conf
Normal file
2
angie/mod.dist/http-brotli.conf
Normal file
@ -0,0 +1,2 @@
|
||||
load_module modules.d/ngx_http_brotli_filter_module.so;
|
||||
load_module modules.d/ngx_http_brotli_static_module.so;
|
1
angie/mod.dist/http-otel.conf
Normal file
1
angie/mod.dist/http-otel.conf
Normal file
@ -0,0 +1 @@
|
||||
load_module modules.d/ngx_otel_module.so;
|
1
angie/mod.dist/http-postgres.conf
Normal file
1
angie/mod.dist/http-postgres.conf
Normal file
@ -0,0 +1 @@
|
||||
load_module modules.d/ngx_postgres_module.so;
|
1
angie/mod.dist/http-rtmp.conf
Normal file
1
angie/mod.dist/http-rtmp.conf
Normal file
@ -0,0 +1 @@
|
||||
load_module modules.d/ngx_rtmp_module.so;
|
1
angie/mod.dist/http-sts.conf
Normal file
1
angie/mod.dist/http-sts.conf
Normal file
@ -0,0 +1 @@
|
||||
load_module modules.d/ngx_http_stream_server_traffic_status_module.so;
|
1
angie/mod.dist/http-vts.conf
Normal file
1
angie/mod.dist/http-vts.conf
Normal file
@ -0,0 +1 @@
|
||||
load_module modules.d/ngx_http_vhost_traffic_status_module.so;
|
1
angie/mod.dist/http-zstd-filter.conf
Normal file
1
angie/mod.dist/http-zstd-filter.conf
Normal file
@ -0,0 +1 @@
|
||||
load_module modules.d/ngx_http_zstd_filter_module.so;
|
1
angie/mod.dist/http-zstd-static.conf
Normal file
1
angie/mod.dist/http-zstd-static.conf
Normal file
@ -0,0 +1 @@
|
||||
load_module modules.d/ngx_http_zstd_static_module.so;
|
2
angie/mod.dist/http-zstd.conf
Normal file
2
angie/mod.dist/http-zstd.conf
Normal file
@ -0,0 +1,2 @@
|
||||
load_module modules.d/ngx_http_zstd_filter_module.so;
|
||||
load_module modules.d/ngx_http_zstd_static_module.so;
|
1
angie/mod.dist/stream-sts.conf
Normal file
1
angie/mod.dist/stream-sts.conf
Normal file
@ -0,0 +1 @@
|
||||
load_module modules.d/ngx_stream_server_traffic_status_module.so;
|
1
angie/snip.dist/core-quic-bpf.conf
Normal file
1
angie/snip.dist/core-quic-bpf.conf
Normal file
@ -0,0 +1 @@
|
||||
quic_bpf on;
|
1
angie/snip.dist/core_ev-accept-mutex-delay.conf
Normal file
1
angie/snip.dist/core_ev-accept-mutex-delay.conf
Normal file
@ -0,0 +1 @@
|
||||
accept_mutex_delay 200ms;
|
1
angie/snip.dist/core_ev-accept-mutex.conf
Normal file
1
angie/snip.dist/core_ev-accept-mutex.conf
Normal file
@ -0,0 +1 @@
|
||||
accept_mutex on;
|
1
angie/snip.dist/core_ev-multi-accept.conf
Normal file
1
angie/snip.dist/core_ev-multi-accept.conf
Normal file
@ -0,0 +1 @@
|
||||
multi_accept on;
|
2
angie/static.dist/robots.txt
Normal file
2
angie/static.dist/robots.txt
Normal file
@ -0,0 +1,2 @@
|
||||
User-agent: *
|
||||
Disallow: /
|
4
apt/prefs.backports
Normal file
4
apt/prefs.backports
Normal file
@ -0,0 +1,4 @@
|
||||
## example:
|
||||
# Package: src:curl
|
||||
# Pin: release n=bookworm-backports
|
||||
# Pin-Priority: 600
|
5
apt/sources.angie
Normal file
5
apt/sources.angie
Normal file
@ -0,0 +1,5 @@
|
||||
Types: deb
|
||||
URIs: http://download.angie.software/angie/debian/12
|
||||
Suites: bookworm
|
||||
Components: main
|
||||
Signed-By: /etc/apt/keyrings/angie.gpg.asc
|
15
apt/sources.debian
Normal file
15
apt/sources.debian
Normal file
@ -0,0 +1,15 @@
|
||||
Types: deb
|
||||
URIs: http://deb.debian.org/debian
|
||||
## local development
|
||||
# URIs: http://127.0.0.1:8081/repository/proxy_apt_debian
|
||||
Suites: bookworm bookworm-updates bookworm-proposed-updates bookworm-backports
|
||||
Components: main
|
||||
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
|
||||
|
||||
Types: deb
|
||||
## local development
|
||||
# URIs: http://127.0.0.1:8081/repository/proxy_apt_debian-security
|
||||
URIs: http://deb.debian.org/debian-security
|
||||
Suites: bookworm-security
|
||||
Components: main
|
||||
Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg
|
51
build-scripts/image-base.sh
Executable file
51
build-scripts/image-base.sh
Executable file
@ -0,0 +1,51 @@
|
||||
#!/bin/sh
|
||||
set -ef
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
PYTHONTAG="${1:-3.11.9-slim-bookworm}"
|
||||
|
||||
grab_site_packages() {
|
||||
podman run \
|
||||
--pull=always --rm \
|
||||
--entrypoint='[]' \
|
||||
--user=nobody:nogroup \
|
||||
-e LANG=C.UTF-8 \
|
||||
-e LC_ALL=C.UTF-8 \
|
||||
-e MALLOC_ARENA_MAX=2 \
|
||||
-e PYTHONUNBUFFERED=1 \
|
||||
-e PYTHONDONTWRITEBYTECODE=1 \
|
||||
"$1" \
|
||||
python3 -c 'import site;print(site.getsitepackages()[0])'
|
||||
}
|
||||
|
||||
PYTHON_SITE_PACKAGES=$(grab_site_packages "docker.io/python:${PYTHONTAG}")
|
||||
[ -n "${PYTHON_SITE_PACKAGES:?}" ]
|
||||
|
||||
set -a
|
||||
BUILDAH_FORMAT="${BUILDAH_FORMAT:-docker}"
|
||||
BUILDAH_ISOLATION="${BUILDAH_ISOLATION:-chroot}"
|
||||
BUILDAH_NETWORK="${BUILDAH_NETWORK:-host}"
|
||||
set +a
|
||||
|
||||
img="docker.io/rockdrilla/angie-conv:base-v1"
|
||||
|
||||
buildah bud --network="${BUILDAH_NETWORK}" \
|
||||
-f ./Dockerfile.base \
|
||||
-t "${img}" \
|
||||
--pull=missing --no-cache --squash \
|
||||
--build-arg "PYTHONTAG=${PYTHONTAG}" \
|
||||
--env "PYTHON_SITE_PACKAGES=${PYTHON_SITE_PACKAGES}" \
|
||||
--unsetenv GPG_KEY \
|
||||
--unsetenv PYTHON_PIP_VERSION \
|
||||
--unsetenv PYTHON_SETUPTOOLS_VERSION \
|
||||
--unsetenv PYTHON_GET_PIP_SHA256 \
|
||||
--unsetenv PYTHON_GET_PIP_URL \
|
||||
|
||||
|
||||
c=$(buildah from --pull=never "${img}") || true
|
||||
if [ -z "$c" ] ; then
|
||||
buildah rmi -f "${img}"
|
||||
exit 1
|
||||
fi
|
||||
buildah config --created-by /usr/local/share/Dockerfile.base "$c"
|
||||
buildah commit --rm --squash "$c" "${img}"
|
16
build-scripts/image-deps.sh
Executable file
16
build-scripts/image-deps.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
set -ef
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
set -a
|
||||
BUILDAH_FORMAT="${BUILDAH_FORMAT:-docker}"
|
||||
BUILDAH_ISOLATION="${BUILDAH_ISOLATION:-chroot}"
|
||||
BUILDAH_NETWORK="${BUILDAH_NETWORK:-host}"
|
||||
set +a
|
||||
|
||||
img="docker.io/rockdrilla/angie-conv:deps-v1"
|
||||
|
||||
exec buildah bud --network="${BUILDAH_NETWORK}" \
|
||||
-f ./Dockerfile.deps \
|
||||
-t "${img}" \
|
||||
--pull=missing --no-cache
|
35
build-scripts/image.sh
Executable file
35
build-scripts/image.sh
Executable file
@ -0,0 +1,35 @@
|
||||
#!/bin/sh
|
||||
set -ef
|
||||
cd "$(dirname "$0")/.."
|
||||
|
||||
set -a
|
||||
BUILDAH_FORMAT="${BUILDAH_FORMAT:-docker}"
|
||||
BUILDAH_ISOLATION="${BUILDAH_ISOLATION:-chroot}"
|
||||
BUILDAH_NETWORK="${BUILDAH_NETWORK:-host}"
|
||||
set +a
|
||||
|
||||
ANGIE_VERSION="${1:-1.6.0}"
|
||||
|
||||
## likely the same as in https://pkg.go.dev/strconv#ParseBool
|
||||
gobool_to_int() {
|
||||
## local value=$1
|
||||
## local default=$2
|
||||
case "${1:-_}" in
|
||||
1 | [Tt] | [Tt][Rr][Uu][Ee] ) echo 1 ;;
|
||||
0 | [Ff] | [Ff][Aa][Ll][Ss][Ee] ) echo 0 ;;
|
||||
* ) echo "${2:-error}" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
NGX_DEBUG=$(gobool_to_int "${2:-0}" 0)
|
||||
case "${NGX_DEBUG}" in
|
||||
0 ) img="docker.io/rockdrilla/angie-conv:${ANGIE_VERSION}-v1" ;;
|
||||
1 ) img="docker.io/rockdrilla/angie-conv:debug-${ANGIE_VERSION}-v1" ;;
|
||||
esac
|
||||
|
||||
exec buildah bud --network="${BUILDAH_NETWORK}" \
|
||||
-f ./Dockerfile \
|
||||
-t "${img}" \
|
||||
--env "ANGIE_VERSION=${ANGIE_VERSION}" \
|
||||
--env "NGX_DEBUG=${NGX_DEBUG}" \
|
||||
--pull=missing --no-cache
|
65
extra-scripts/certifi-extras.sh
Executable file
65
extra-scripts/certifi-extras.sh
Executable file
@ -0,0 +1,65 @@
|
||||
#!/bin/sh
|
||||
set -ef
|
||||
|
||||
certifi_uri="https://raw.githubusercontent.com/certifi/python-certifi/${CERTIFI_COMMIT:?}/certifi/cacert.pem"
|
||||
dst_dir=/usr/local/share/ca-certificates
|
||||
|
||||
w=$(mktemp -d) ; : "${w:?}"
|
||||
curl -sSL "${certifi_uri}" > "$w/cacert.pem"
|
||||
|
||||
def_bundle=/etc/ssl/certs/ca-certificates.crt
|
||||
|
||||
bundle_offsets() {
|
||||
grep -Fhne '-----END CERTIFICATE-----' "$1" | cut -d : -f 1 \
|
||||
| {
|
||||
s=1 ; while read -r e ; do
|
||||
[ -n "$e" ] || continue
|
||||
echo "$s,$e"
|
||||
s=$((e+1))
|
||||
done
|
||||
}
|
||||
}
|
||||
|
||||
set +e
|
||||
bundle_offsets "${def_bundle}" > "$w/offsets.0"
|
||||
bundle_offsets "$w/cacert.pem" > "$w/offsets.1"
|
||||
set -e
|
||||
|
||||
bundle_fingerprints() {
|
||||
while read -r a ; do
|
||||
[ -n "$a" ] || continue
|
||||
sed -ne "${a}p" "$1" | openssl x509 -noout -fingerprint
|
||||
done < "$2"
|
||||
}
|
||||
|
||||
set +e
|
||||
bundle_fingerprints "${def_bundle}" "$w/offsets.0" > "$w/fingerprints.0"
|
||||
bundle_fingerprints "$w/cacert.pem" "$w/offsets.1" > "$w/fingerprints.1"
|
||||
set -e
|
||||
|
||||
set +e
|
||||
grep -Fxv -f "$w/fingerprints.0" "$w/fingerprints.1" > "$w/fingerprints.diff"
|
||||
set -e
|
||||
|
||||
if [ -s "$w/fingerprints.diff" ] ; then
|
||||
set +e
|
||||
grep -Fxn -f "$w/fingerprints.diff" "$w/fingerprints.1" | cut -d : -f 1 > "$w/records.diff"
|
||||
set -e
|
||||
|
||||
terse_fingerprint() {
|
||||
cut -d = -f 2- | tr '[:upper:]' '[:lower:]' | tr -cd '[:alnum:]'
|
||||
}
|
||||
|
||||
mkdir "$w/extras"
|
||||
|
||||
while read -r n ; do
|
||||
[ -n "$n" ] || continue
|
||||
fp=$(sed -ne "${n}p" "$w/fingerprints.1" | terse_fingerprint)
|
||||
off=$(sed -ne "${n}p" "$w/offsets.1")
|
||||
sed -ne "${off}p" "$w/cacert.pem" | openssl x509 > "${dst_dir}/certifi-${fp}.crt"
|
||||
done < "$w/records.diff"
|
||||
fi
|
||||
|
||||
rm -rf "$w"
|
||||
|
||||
update-ca-certificates --fresh
|
45
extra-scripts/gpg-batch.sh
Executable file
45
extra-scripts/gpg-batch.sh
Executable file
@ -0,0 +1,45 @@
|
||||
#!/bin/sh
|
||||
set -ef
|
||||
|
||||
: "${GPG_KEYSERVER:=hkps://keyserver.ubuntu.com}"
|
||||
|
||||
[ $# != 0 ] || exit 1
|
||||
|
||||
case "$1" in
|
||||
1 | start )
|
||||
[ -n "${GNUPGHOME}" ] || exit 1
|
||||
[ -d "${GNUPGHOME}" ] || exit 1
|
||||
|
||||
cd "${GNUPGHOME}"
|
||||
cat > gpg.conf <<-EOF
|
||||
quiet
|
||||
batch
|
||||
trust-model always
|
||||
no-auto-check-trustdb
|
||||
ignore-time-conflict
|
||||
keyid-format 0xlong
|
||||
keyserver ${GPG_KEYSERVER}
|
||||
EOF
|
||||
cat > dirmngr.conf <<-EOF
|
||||
quiet
|
||||
batch
|
||||
keyserver ${GPG_KEYSERVER}
|
||||
EOF
|
||||
gpg --update-trustdb >/dev/null 2>&1
|
||||
gpg --list-keys >/dev/null 2>&1
|
||||
dirmngr >/dev/null 2>&1
|
||||
;;
|
||||
0 | stop )
|
||||
[ -n "${GNUPGHOME}" ] || exit 0
|
||||
[ -d "${GNUPGHOME}" ] || exit 1
|
||||
|
||||
cd "${GNUPGHOME}"
|
||||
gpgconf --kill all
|
||||
cd /
|
||||
rm -rf "${GNUPGHOME}"
|
||||
;;
|
||||
* )
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
exit 0
|
28
extra-scripts/gpg-export.sh
Executable file
28
extra-scripts/gpg-export.sh
Executable file
@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
set -ef
|
||||
|
||||
: "${1:?}" "${2:?}"
|
||||
|
||||
w=$(mktemp -d) ; : "${w:?}"
|
||||
|
||||
gpg_on() { gpg-batch.sh start ; }
|
||||
gpg_off() {
|
||||
cd /
|
||||
gpg-batch.sh stop
|
||||
unset GNUPGHOME
|
||||
rm -rf "$w"
|
||||
exit "${1:-0}"
|
||||
}
|
||||
|
||||
(
|
||||
export GNUPGHOME="$w/.gnupg"
|
||||
mkdir -m 0700 "${GNUPGHOME}"
|
||||
gpg_on
|
||||
|
||||
gpg --import "$1"
|
||||
gpg --armor --export > "$w/export"
|
||||
cat < "$w/export" > "$2"
|
||||
gpg --show-keys "$2"
|
||||
|
||||
gpg_off
|
||||
) || gpg_off 1
|
242
image-entry.d/00-common.envsh
Normal file
242
image-entry.d/00-common.envsh
Normal file
@ -0,0 +1,242 @@
|
||||
#!/bin/sh
|
||||
|
||||
have_envvar() {
|
||||
[ -n "$1" ] || return 1
|
||||
grep -Ezq "^$1=" /proc/self/environ || return
|
||||
}
|
||||
|
||||
## unexporting variable in (POSIX) sh is PITA =/
|
||||
unexport() {
|
||||
unset ___k ___v
|
||||
for ___k ; do
|
||||
[ -n "${___k}" ] || continue
|
||||
have_envvar "${___k}" || continue
|
||||
|
||||
___v=$(eval printf '%s' "\"\${${___k}}\"")
|
||||
eval "unset ${___k}"
|
||||
eval "${___k}=$(env printf '%s' \"\${___v}\")"
|
||||
unset ___v
|
||||
done
|
||||
unset ___k
|
||||
}
|
||||
|
||||
## likely the same as in https://pkg.go.dev/strconv#ParseBool
|
||||
gobool_to_int() {
|
||||
## local value=$1
|
||||
## local default=$2
|
||||
case "${1:-_}" in
|
||||
1 | [Tt] | [Tt][Rr][Uu][Ee] ) echo 1 ;;
|
||||
0 | [Ff] | [Ff][Aa][Ll][Ss][Ee] ) echo 0 ;;
|
||||
* ) echo "${2:-error}" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
[ -n "${__IEP_SRC:-}" ] || __IEP_SRC="$0"
|
||||
|
||||
IEP_TRACE=$(gobool_to_int "${IEP_TRACE:-0}" 0)
|
||||
export IEP_TRACE
|
||||
if [ "${IEP_TRACE}" = 1 ] ; then
|
||||
log_always() { echo "# $(date +'%Y-%m-%d %H:%M:%S.%03N %z'): ${__IEP_SRC}${*:+: $*}" >&2 ; }
|
||||
else
|
||||
log_always() { echo "# ${__IEP_SRC}${*:+: $*}" >&2 ; }
|
||||
fi
|
||||
|
||||
IEP_VERBOSE=$(gobool_to_int "${IEP_VERBOSE:-${IEP_TRACE}}" "${IEP_TRACE}")
|
||||
export IEP_VERBOSE
|
||||
if [ "${IEP_VERBOSE}" = 1 ] ; then
|
||||
log() { log_always "$@" ; }
|
||||
log_file() { sed -E '/^./s,^, ,' < "$1" >&2 ; }
|
||||
else
|
||||
log() { : ;}
|
||||
log_file() { :; }
|
||||
fi
|
||||
|
||||
if [ "${IEP_VERBOSE}" = 0 ] ; then
|
||||
ln_s() { ln -s "$@" || return; }
|
||||
else
|
||||
ln_s() { ln -sv "$@" || return; }
|
||||
fi
|
||||
|
||||
have_cmd() { command -v "$1" >/dev/null 2>&1 || return ; }
|
||||
|
||||
strip_suffix() { printf '%s' "${1%"$2"}" | tr -s '/' ; }
|
||||
|
||||
untemplate_path() {
|
||||
case "$1" in
|
||||
## inplace
|
||||
/run/angie/* | /etc/angie/run/* )
|
||||
strip_suffix "$1" "$2"
|
||||
;;
|
||||
/etc/angie/conf.d/* | /etc/angie/mod.d/* | /etc/angie/modules.d/* | /etc/angie/njs.d/* | /etc/angie/site.d/* | /etc/angie/snip.d/* )
|
||||
strip_suffix "$1" "$2"
|
||||
;;
|
||||
/etc/angie/static.d/* )
|
||||
strip_suffix "$1" "$2"
|
||||
;;
|
||||
## set appropriate location
|
||||
/etc/angie/* )
|
||||
strip_suffix "/run/angie${1#/etc/angie}" "$2"
|
||||
;;
|
||||
/tmp/* )
|
||||
log_always "untemplate_path() shouldn't work with /tmp/: $1"
|
||||
strip_suffix "$1" "$2"
|
||||
;;
|
||||
## last resort - STRONGLY AVOID
|
||||
/* )
|
||||
log_always "untemplate_path() does uncommon/last-resort mapping for: $1"
|
||||
strip_suffix "/run/angie/tmp$1" "$2"
|
||||
;;
|
||||
## misbehavior!
|
||||
* )
|
||||
log_always "untemplate_path() doesn't work with relative paths: $1"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
install_userdir() {
|
||||
if [ "${IEP_ROOT}" = 1 ] ; then
|
||||
install -d -o "${NGX_USER}" -g "${NGX_GROUP}" "$@"
|
||||
else
|
||||
install -d "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
untemplate_file_envsubst() {
|
||||
[ -n "$1" ] || return
|
||||
[ -f "$1" ] || { log_always "file not found: $1" ; return 1 ; }
|
||||
|
||||
[ -n "${NGX_ENVSUBST_SUFFIX:-}" ] || { log "NGX_ENVSUBST_SUFFIX is empty" ; return 1 ; }
|
||||
|
||||
__dest="$2"
|
||||
[ -n "${__dest}" ] || __dest=$(untemplate_path "$1" "${NGX_ENVSUBST_SUFFIX}") || return
|
||||
|
||||
[ -d "${__dest%/*}" ] || install_userdir "${__dest%/*}" || return
|
||||
|
||||
log "Running envsubst: $1 -> ${__dest}"
|
||||
envsubst.sh < "$1" > "${__dest}" || return
|
||||
}
|
||||
|
||||
## notes:
|
||||
## - (OPTIONAL) place own wrapper script as "/usr/local/sbin/jinja.py"
|
||||
## in order to perform different template processing
|
||||
untemplate_file_jinja() {
|
||||
[ -n "$1" ] || return
|
||||
[ -f "$1" ] || { log_always "file not found: $1" ; return 1 ; }
|
||||
|
||||
[ -n "${NGX_JINJA_SUFFIX:-}" ] || { log "NGX_JINJA_SUFFIX is empty" ; return 1 ; }
|
||||
|
||||
__dest="$2"
|
||||
[ -n "${__dest}" ] || __dest=$(untemplate_path "$1" "${NGX_JINJA_SUFFIX}") || return
|
||||
|
||||
[ -d "${__dest%/*}" ] || install_userdir "${__dest%/*}" || return
|
||||
|
||||
log "Running jinja.py: $1 -> ${__dest}"
|
||||
jinja.py "$1" "${__dest}" || return
|
||||
}
|
||||
|
||||
untemplate_dir_envsubst() {
|
||||
[ -n "${NGX_ENVSUBST_SUFFIX:-}" ] || { log "NGX_ENVSUBST_SUFFIX is empty" ; return 1 ; }
|
||||
|
||||
__template_list=$(mktemp) || return
|
||||
|
||||
find "$@" -follow -type f -name "*${NGX_ENVSUBST_SUFFIX}" \
|
||||
| sort -uV > "${__template_list}"
|
||||
|
||||
__have_args="${ENVSUBST_ARGS:+1}"
|
||||
if [ -z "${__have_args}" ] ; then
|
||||
## optimize envsubst.sh invocation by caching argument list
|
||||
## ref: envsubst.sh
|
||||
ENVSUBST_ARGS=$(mktemp) || return
|
||||
envsubst-args.sh > "${ENVSUBST_ARGS}"
|
||||
export ENVSUBST_ARGS
|
||||
fi
|
||||
|
||||
while read -r _orig_file ; do
|
||||
[ -n "${_orig_file}" ] || continue
|
||||
untemplate_file_envsubst "${_orig_file}"
|
||||
done < "${__template_list}"
|
||||
|
||||
if [ -z "${__have_args}" ] ; then
|
||||
rm -f "${ENVSUBST_ARGS}" ; unset ENVSUBST_ARGS
|
||||
fi
|
||||
unset __have_args
|
||||
|
||||
rm -f "${__template_list}" ; unset __template_list
|
||||
}
|
||||
|
||||
untemplate_dir_jinja() {
|
||||
[ -n "${NGX_JINJA_SUFFIX:-}" ] || { log "NGX_JINJA_SUFFIX is empty" ; return 1 ; }
|
||||
|
||||
__template_list=$(mktemp) || return
|
||||
|
||||
find "$@" -follow -type f -name "*${NGX_JINJA_SUFFIX}" \
|
||||
| sort -uV > "${__template_list}"
|
||||
|
||||
while read -r _orig_file ; do
|
||||
[ -n "${_orig_file}" ] || continue
|
||||
untemplate_file_jinja "${_orig_file}"
|
||||
done < "${__template_list}"
|
||||
|
||||
rm -f "${__template_list}" ; unset __template_list
|
||||
}
|
||||
|
||||
remap_path() {
|
||||
[ -n "$1" ] || return
|
||||
|
||||
case "$1" in
|
||||
## conf
|
||||
/etc/angie/conf.dist/* ) echo "${2:-/etc/angie/conf.d}${1#/etc/angie/conf.dist}" ;;
|
||||
/etc/angie/conf/* ) echo "${2:-/etc/angie/conf.d}${1#/etc/angie/conf}" ;;
|
||||
/angie/conf/* ) echo "${2:-/etc/angie/conf.d}${1#/angie/conf}" ;;
|
||||
## mod
|
||||
/etc/angie/mod.dist/* ) echo "${2:-/etc/angie/mod.d}${1#/etc/angie/mod.dist}" ;;
|
||||
/etc/angie/mod/* ) echo "${2:-/etc/angie/mod.d}${1#/etc/angie/mod}" ;;
|
||||
/angie/mod/* ) echo "${2:-/etc/angie/mod.d}${1#/angie/mod}" ;;
|
||||
## modules
|
||||
/etc/angie/modules.dist/* ) echo "${2:-/etc/angie/modules.d}${1#/etc/angie/modules.dist}" ;;
|
||||
/etc/angie/modules/* ) echo "${2:-/etc/angie/modules.d}${1#/etc/angie/modules}" ;;
|
||||
/angie/modules/* ) echo "${2:-/etc/angie/modules.d}${1#/angie/modules}" ;;
|
||||
## njs
|
||||
/etc/angie/njs.dist/* ) echo "${2:-/etc/angie/njs.d}${1#/etc/angie/njs.dist}" ;;
|
||||
/etc/angie/njs/* ) echo "${2:-/etc/angie/njs.d}${1#/etc/angie/njs}" ;;
|
||||
/angie/njs/* ) echo "${2:-/etc/angie/njs.d}${1#/angie/njs}" ;;
|
||||
## site
|
||||
/etc/angie/site.dist/* ) echo "${2:-/etc/angie/site.d}${1#/etc/angie/site.dist}" ;;
|
||||
/etc/angie/site/* ) echo "${2:-/etc/angie/site.d}${1#/etc/angie/site}" ;;
|
||||
/angie/site/* ) echo "${2:-/etc/angie/site.d}${1#/angie/site}" ;;
|
||||
## snip
|
||||
/etc/angie/snip.dist/* ) echo "${2:-/etc/angie/snip.d}${1#/etc/angie/snip.dist}" ;;
|
||||
/etc/angie/snip/* ) echo "${2:-/etc/angie/snip.d}${1#/etc/angie/snip}" ;;
|
||||
/angie/snip/* ) echo "${2:-/etc/angie/snip.d}${1#/angie/snip}" ;;
|
||||
|
||||
## static
|
||||
/etc/angie/static.dist/* ) echo "${2:-/etc/angie/static.d}${1#/etc/angie/static.dist}" ;;
|
||||
/etc/angie/static/* ) echo "${2:-/etc/angie/static.d}${1#/etc/angie/static}" ;;
|
||||
/angie/static/* ) echo "${2:-/etc/angie/static.d}${1#/angie/static}" ;;
|
||||
|
||||
## log
|
||||
/etc/angie/log.dist/* ) echo "${2:-/etc/angie/log.d}${1#/etc/angie/log.dist}" ;;
|
||||
/angie/log/* ) echo "${2:-/etc/angie/log.d}${1#/angie/log}" ;;
|
||||
|
||||
## misbehavior!
|
||||
* )
|
||||
log_always "remap_path() doesn't know how to handle this path: $1"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
merged_root='/run/angie/merged'
|
||||
combine_remap_path() {
|
||||
[ -n "$1" ] || return
|
||||
|
||||
case "$1" in
|
||||
"${merged_root}"/* ) echo "${2:-/run/angie}${1#"${merged_root}"}" ;;
|
||||
## misbehavior!
|
||||
* )
|
||||
log_always "combine_remap_path() doesn't know how to handle this path: $1"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
39
image-entry.d/01-defaults.envsh
Executable file
39
image-entry.d/01-defaults.envsh
Executable file
@ -0,0 +1,39 @@
|
||||
#!/bin/sh
|
||||
|
||||
## NB: NGX_DEBUG is set via image build script
|
||||
|
||||
set -a
|
||||
|
||||
NGX_HTTP=$(gobool_to_int "${NGX_HTTP:-1}" 1)
|
||||
NGX_MAIL=$(gobool_to_int "${NGX_MAIL:-0}" 0)
|
||||
NGX_STREAM=$(gobool_to_int "${NGX_STREAM:-0}" 0)
|
||||
|
||||
NGX_STRICT_LOAD=$(gobool_to_int "${NGX_STRICT_LOAD:-1}" 1)
|
||||
|
||||
NGX_CORE_MODULES="${NGX_CORE_MODULES:-}"
|
||||
NGX_CORE_EVENTS_SNIPPETS="${NGX_CORE_EVENTS_SNIPPETS:-}"
|
||||
NGX_CORE_SNIPPETS="${NGX_CORE_SNIPPETS:-}"
|
||||
|
||||
NGX_CORE_ENV="${NGX_CORE_ENV:-}"
|
||||
|
||||
NGX_PROCESS_STATIC=$(gobool_to_int "${NGX_PROCESS_STATIC:-0}" 0)
|
||||
|
||||
NGX_ENVSUBST_SUFFIX="${NGX_ENVSUBST_SUFFIX:-.in}"
|
||||
case "${NGX_ENVSUBST_SUFFIX}" in
|
||||
.* ) ;;
|
||||
* ) NGX_ENVSUBST_SUFFIX=".${NGX_ENVSUBST_SUFFIX}" ;;
|
||||
esac
|
||||
NGX_JINJA_SUFFIX="${NGX_JINJA_SUFFIX:-.j2}"
|
||||
case "${NGX_JINJA_SUFFIX}" in
|
||||
.* ) ;;
|
||||
* ) NGX_JINJA_SUFFIX=".${NGX_JINJA_SUFFIX}" ;;
|
||||
esac
|
||||
|
||||
set +a
|
||||
|
||||
if [ "${NGX_HTTP}${NGX_MAIL}${NGX_STREAM}" = '000' ] ; then
|
||||
log_always '======================================'
|
||||
log_always 'WARNING!'
|
||||
log_always 'Angie is almost completely TURNED OFF'
|
||||
log_always '======================================'
|
||||
fi
|
6
image-entry.d/02-detect-nonroot.envsh
Executable file
6
image-entry.d/02-detect-nonroot.envsh
Executable file
@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
unset IEP_ROOT
|
||||
IEP_ROOT=1
|
||||
[ "$(stat -c %u /proc/1)" = 0 ] || IEP_ROOT=0
|
||||
export IEP_ROOT
|
17
image-entry.d/03-detect-local-override.envsh
Executable file
17
image-entry.d/03-detect-local-override.envsh
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
unset IEP_LOCAL_OVERRIDE
|
||||
IEP_LOCAL_OVERRIDE=0
|
||||
|
||||
unset _fsspec _fstarget _fstype _fsopts _fsreq _fspass
|
||||
while read -r _fsspec _fstarget _fstype _fsopts _fsreq _fspass ; do
|
||||
case "${_fstarget}" in
|
||||
/angie | /angie/* )
|
||||
IEP_LOCAL_OVERRIDE=1
|
||||
break
|
||||
;;
|
||||
esac
|
||||
done < /proc/mounts
|
||||
unset _fsspec _fstarget _fstype _fsopts _fsreq _fspass
|
||||
|
||||
export IEP_LOCAL_OVERRIDE
|
70
image-entry.d/10-core-user.envsh
Executable file
70
image-entry.d/10-core-user.envsh
Executable file
@ -0,0 +1,70 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "${IEP_ROOT}" = 0 ] ; then
|
||||
log "Running as non-root: user/group configuration may be excessive"
|
||||
fi
|
||||
|
||||
unset _NGX_USER _NGX_GROUP
|
||||
## here should be SANE defaults (!)
|
||||
_NGX_USER=angie
|
||||
_NGX_GROUP=angie
|
||||
|
||||
[ -n "${NGX_USER:-}" ] || NGX_USER=${_NGX_USER}
|
||||
case "${NGX_USER}" in
|
||||
"${_NGX_USER}" ) ;;
|
||||
## numeric id - remap to name
|
||||
[1-9]* )
|
||||
_user_name=$(getent passwd "${NGX_USER}" | cut -d: -f1)
|
||||
if [ -n "${_user_name}" ] ; then
|
||||
NGX_USER=${_user_name}
|
||||
else
|
||||
log_always "NGX_USER: ID is not known in /etc/passwd: ${NGX_USER}"
|
||||
log_always "setting NGX_USER=${_NGX_USER}"
|
||||
NGX_USER=${_NGX_USER}
|
||||
fi
|
||||
unset _user_name
|
||||
;;
|
||||
* )
|
||||
_user_name=$(getent passwd "${NGX_USER}" | cut -d: -f1)
|
||||
if [ -n "${_user_name}" ] ; then
|
||||
NGX_USER=${_user_name}
|
||||
else
|
||||
log_always "NGX_USER: name is not known in /etc/passwd: ${NGX_USER}"
|
||||
log_always "setting NGX_USER=${_NGX_USER}"
|
||||
NGX_USER=${_NGX_USER}
|
||||
fi
|
||||
unset _user_name
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -n "${NGX_GROUP:-}" ] || NGX_GROUP=${_NGX_GROUP}
|
||||
case "${NGX_GROUP}" in
|
||||
"${_NGX_GROUP}" ) ;;
|
||||
## numeric id - remap to name
|
||||
[1-9]* )
|
||||
_group_name=$(getent group "${NGX_GROUP}" | cut -d: -f1)
|
||||
if [ -n "${_group_name}" ] ; then
|
||||
NGX_GROUP=${_group_name}
|
||||
else
|
||||
log_always "NGX_GROUP: ID is not known in /etc/group: ${NGX_GROUP}"
|
||||
log_always "setting NGX_GROUP=${_NGX_GROUP}"
|
||||
NGX_GROUP=${_NGX_GROUP}
|
||||
fi
|
||||
unset _group_name
|
||||
;;
|
||||
* )
|
||||
_group_name=$(getent group "${NGX_GROUP}" | cut -d: -f1)
|
||||
if [ -n "${_group_name}" ] ; then
|
||||
NGX_GROUP=${_group_name}
|
||||
else
|
||||
log_always "NGX_GROUP: name is not known in /etc/group: ${NGX_GROUP}"
|
||||
log_always "setting NGX_GROUP=${_NGX_GROUP}"
|
||||
NGX_GROUP=${_NGX_GROUP}
|
||||
fi
|
||||
unset _group_name
|
||||
;;
|
||||
esac
|
||||
|
||||
export NGX_USER NGX_GROUP
|
||||
|
||||
unset _NGX_USER _NGX_GROUP
|
34
image-entry.d/11-core-env.envsh
Executable file
34
image-entry.d/11-core-env.envsh
Executable file
@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ -z "${NGX_CORE_ENV:-}" ] ; then
|
||||
NGX_CORE_ENV='TZ MALLOC_ARENA_MAX'
|
||||
else
|
||||
unset __set_f
|
||||
__set_f=
|
||||
case "${-}" in
|
||||
*f* ) __set_f=1 ;;
|
||||
esac
|
||||
[ -n "${__set_f}" ] || set -f
|
||||
|
||||
unset __env __have_tz __have_malloc
|
||||
for __env in ${NGX_CORE_ENV} ; do
|
||||
case "${__env}" in
|
||||
TZ | TZ=* )
|
||||
__have_tz=1
|
||||
;;
|
||||
MALLOC_ARENA_MAX | MALLOC_ARENA_MAX=* )
|
||||
__have_malloc=1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
unset __env
|
||||
|
||||
[ -n "${__have_malloc}" ] || NGX_CORE_ENV="MALLOC_ARENA_MAX ${NGX_CORE_ENV}"
|
||||
[ -n "${__have_tz}" ] || NGX_CORE_ENV="TZ ${NGX_CORE_ENV}"
|
||||
unset __have_tz __have_malloc
|
||||
|
||||
[ -n "${__set_f}" ] || set +f
|
||||
unset __set_f
|
||||
fi
|
||||
|
||||
export NGX_CORE_ENV
|
122
image-entry.d/12-core-worker-defaults.envsh
Executable file
122
image-entry.d/12-core-worker-defaults.envsh
Executable file
@ -0,0 +1,122 @@
|
||||
#!/bin/sh
|
||||
|
||||
unset _NGX_WORKER_PROCESSES _NGX_WORKER_PRIORITY _NGX_WORKER_RLIMIT_NOFILE _NGX_WORKER_CONNECTIONS
|
||||
## here should be SANE defaults (!)
|
||||
_NGX_WORKER_PROCESSES=2
|
||||
_NGX_WORKER_PRIORITY=0
|
||||
_NGX_WORKER_RLIMIT_NOFILE=16384
|
||||
_NGX_WORKER_CONNECTIONS=4096
|
||||
|
||||
[ -n "${NGX_WORKER_PROCESSES:-}" ] || NGX_WORKER_PROCESSES=${_NGX_WORKER_PROCESSES}
|
||||
case "${NGX_WORKER_PROCESSES}" in
|
||||
"${_NGX_WORKER_PROCESSES}" ) ;;
|
||||
[1-9] | [1-9][0-9] ) ;;
|
||||
0 | [Aa][Uu][Tt][Oo] )
|
||||
log_always "NGX_WORKER_PROCESSES=${NGX_WORKER_PROCESSES} isn't supported yet"
|
||||
log_always "setting NGX_WORKER_PROCESSES=${_NGX_WORKER_PROCESSES}"
|
||||
NGX_WORKER_PROCESSES=${_NGX_WORKER_PROCESSES}
|
||||
;;
|
||||
* )
|
||||
log_always "NGX_WORKER_PROCESSES: unrecognized value: ${NGX_WORKER_PROCESSES}"
|
||||
log_always "setting NGX_WORKER_PROCESSES=${_NGX_WORKER_PROCESSES}"
|
||||
NGX_WORKER_PROCESSES=${_NGX_WORKER_PROCESSES}
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -n "${NGX_WORKER_PRIORITY:-}" ] || NGX_WORKER_PRIORITY=${_NGX_WORKER_PRIORITY}
|
||||
case "${NGX_WORKER_PRIORITY}" in
|
||||
"${_NGX_WORKER_PRIORITY}" ) ;;
|
||||
-[1-9] | -1[0-9] | -20 ) ;;
|
||||
[0-9] | 1[0-9] | 20 ) ;;
|
||||
* )
|
||||
log_always "NGX_WORKER_PRIORITY: unrecognized value: ${NGX_WORKER_PRIORITY}"
|
||||
log_always "setting NGX_WORKER_PRIORITY=${_NGX_WORKER_PRIORITY}"
|
||||
NGX_WORKER_PRIORITY=${_NGX_WORKER_PRIORITY}
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -n "${NGX_WORKER_RLIMIT_NOFILE:-}" ] || NGX_WORKER_RLIMIT_NOFILE=${_NGX_WORKER_RLIMIT_NOFILE}
|
||||
case "${NGX_WORKER_RLIMIT_NOFILE}" in
|
||||
"${_NGX_WORKER_RLIMIT_NOFILE}" ) ;;
|
||||
[1-9] | [1-9][0-9] )
|
||||
log_always "NGX_WORKER_RLIMIT_NOFILE: too low: ${NGX_WORKER_RLIMIT_NOFILE}"
|
||||
log_always "setting NGX_WORKER_RLIMIT_NOFILE=${_NGX_WORKER_RLIMIT_NOFILE}"
|
||||
NGX_WORKER_RLIMIT_NOFILE=${_NGX_WORKER_RLIMIT_NOFILE}
|
||||
;;
|
||||
## allow values within [100;9999999]
|
||||
[1-9][0-9][0-9] ) ;;
|
||||
[1-9][0-9][0-9][0-9] ) ;;
|
||||
[1-9][0-9][0-9][0-9][0-9] ) ;;
|
||||
[1-9][0-9][0-9][0-9][0-9][0-9] ) ;;
|
||||
[1-9][0-9][0-9][0-9][0-9][0-9][0-9] ) ;;
|
||||
* )
|
||||
log_always "NGX_WORKER_RLIMIT_NOFILE: unrecognized value: ${NGX_WORKER_RLIMIT_NOFILE}"
|
||||
log_always "setting NGX_WORKER_RLIMIT_NOFILE=${_NGX_WORKER_RLIMIT_NOFILE}"
|
||||
NGX_WORKER_RLIMIT_NOFILE=${_NGX_WORKER_RLIMIT_NOFILE}
|
||||
;;
|
||||
esac
|
||||
|
||||
[ -n "${NGX_WORKER_CONNECTIONS:-}" ] || NGX_WORKER_CONNECTIONS=${_NGX_WORKER_CONNECTIONS}
|
||||
case "${NGX_WORKER_CONNECTIONS}" in
|
||||
"${_NGX_WORKER_CONNECTIONS}" ) ;;
|
||||
[1-9] | [1-9][0-9] )
|
||||
log_always "NGX_WORKER_CONNECTIONS: too low: ${NGX_WORKER_CONNECTIONS}"
|
||||
log_always "setting NGX_WORKER_CONNECTIONS=${_NGX_WORKER_CONNECTIONS}"
|
||||
NGX_WORKER_CONNECTIONS=${_NGX_WORKER_CONNECTIONS}
|
||||
;;
|
||||
## allow values within [100;9999999]
|
||||
[1-9][0-9][0-9] ) ;;
|
||||
[1-9][0-9][0-9][0-9] ) ;;
|
||||
[1-9][0-9][0-9][0-9][0-9] ) ;;
|
||||
[1-9][0-9][0-9][0-9][0-9][0-9] ) ;;
|
||||
[1-9][0-9][0-9][0-9][0-9][0-9][0-9] ) ;;
|
||||
* )
|
||||
log_always "NGX_WORKER_CONNECTIONS: unrecognized value: ${NGX_WORKER_CONNECTIONS}"
|
||||
log_always "setting NGX_WORKER_CONNECTIONS=${_NGX_WORKER_CONNECTIONS}"
|
||||
NGX_WORKER_CONNECTIONS=${_NGX_WORKER_CONNECTIONS}
|
||||
;;
|
||||
esac
|
||||
|
||||
nofile_soft=$(ulimit -Sn)
|
||||
nofile_hard=$(ulimit -Hn)
|
||||
|
||||
if [ "${nofile_hard}" = unlimited ] ; then
|
||||
## minor hack (if applicable) :)
|
||||
nofile_hard=${NGX_WORKER_RLIMIT_NOFILE}
|
||||
fi
|
||||
|
||||
nofile_ok=0
|
||||
while : ; do
|
||||
[ ${nofile_hard} -ge ${NGX_WORKER_RLIMIT_NOFILE} ] || break
|
||||
[ ${nofile_soft} -ge ${NGX_WORKER_RLIMIT_NOFILE} ] || break
|
||||
|
||||
nofile_ok=1
|
||||
break ; done
|
||||
|
||||
if [ ${nofile_ok} = 0 ] ; then
|
||||
log_always "adjusting 'nofile' limits"
|
||||
|
||||
log_always "Limits before:"
|
||||
sed -En '1p;/open files/p' < /proc/$$/limits >&2
|
||||
|
||||
if [ ${nofile_hard} -lt ${NGX_WORKER_RLIMIT_NOFILE} ] ; then
|
||||
ulimit -Hn "${NGX_WORKER_RLIMIT_NOFILE}"
|
||||
nofile_hard=$(ulimit -Hn)
|
||||
fi
|
||||
if [ ${nofile_hard} -lt ${NGX_WORKER_RLIMIT_NOFILE} ] ; then
|
||||
log_always "lowering NGX_WORKER_RLIMIT_NOFILE to ${nofile_hard}"
|
||||
NGX_WORKER_RLIMIT_NOFILE=${nofile_hard}
|
||||
fi
|
||||
|
||||
if [ ${nofile_soft} -lt ${NGX_WORKER_RLIMIT_NOFILE} ] ; then
|
||||
ulimit -Sn "${NGX_WORKER_RLIMIT_NOFILE}"
|
||||
fi
|
||||
|
||||
log_always "Limits after:"
|
||||
sed -En '1p;/open files/p' < /proc/$$/limits >&2
|
||||
fi
|
||||
unset nofile_soft nofile_hard nofile_ok
|
||||
|
||||
export NGX_WORKER_PROCESSES NGX_WORKER_PRIORITY NGX_WORKER_RLIMIT_NOFILE NGX_WORKER_CONNECTIONS
|
||||
|
||||
unset _NGX_WORKER_PROCESSES _NGX_WORKER_PRIORITY _NGX_WORKER_RLIMIT_NOFILE _NGX_WORKER_CONNECTIONS
|
10
image-entry.d/20-http.envsh
Executable file
10
image-entry.d/20-http.envsh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "${NGX_HTTP}" = 0 ] ; then
|
||||
unset NGX_HTTP_MODULES NGX_HTTP_SNIPPETS
|
||||
else
|
||||
set -a
|
||||
NGX_HTTP_MODULES="${NGX_HTTP_MODULES:-}"
|
||||
NGX_HTTP_SNIPPETS="${NGX_HTTP_SNIPPETS:-}"
|
||||
set +a
|
||||
fi
|
27
image-entry.d/21-http-max-ranges.envsh
Executable file
27
image-entry.d/21-http-max-ranges.envsh
Executable file
@ -0,0 +1,27 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "${NGX_HTTP}" = 0 ] ; then
|
||||
unset NGX_HTTP_MAX_RANGES
|
||||
else
|
||||
unset _NGX_HTTP_MAX_RANGES
|
||||
## here should be SANE defaults (!)
|
||||
_NGX_HTTP_MAX_RANGES=16
|
||||
|
||||
[ -n "${NGX_HTTP_MAX_RANGES:-}" ] || NGX_HTTP_MAX_RANGES=${_NGX_HTTP_MAX_RANGES}
|
||||
case "${NGX_HTTP_MAX_RANGES}" in
|
||||
"${_NGX_HTTP_MAX_RANGES}" ) ;;
|
||||
[1-9] | [1-9][0-9] | [1-9][0-9][0-9] ) ;;
|
||||
0 )
|
||||
log "HTTP: Range/If-Range/Accept-Ranges support is disabled"
|
||||
;;
|
||||
* )
|
||||
log_always "NGX_HTTP_MAX_RANGES: unrecognized value: ${NGX_HTTP_MAX_RANGES}"
|
||||
log_always "setting NGX_HTTP_MAX_RANGES=${_NGX_HTTP_MAX_RANGES}"
|
||||
NGX_HTTP_MAX_RANGES=${_NGX_HTTP_MAX_RANGES}
|
||||
;;
|
||||
esac
|
||||
|
||||
export NGX_HTTP_MAX_RANGES
|
||||
|
||||
unset _NGX_HTTP_MAX_RANGES
|
||||
fi
|
10
image-entry.d/30-mail.envsh
Executable file
10
image-entry.d/30-mail.envsh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "${NGX_MAIL}" = 0 ] ; then
|
||||
unset NGX_MAIL_MODULES NGX_MAIL_SNIPPETS
|
||||
else
|
||||
set -a
|
||||
NGX_MAIL_MODULES="${NGX_MAIL_MODULES:-}"
|
||||
NGX_MAIL_SNIPPETS="${NGX_MAIL_SNIPPETS:-}"
|
||||
set +a
|
||||
fi
|
10
image-entry.d/40-stream.envsh
Executable file
10
image-entry.d/40-stream.envsh
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/sh
|
||||
|
||||
if [ "${NGX_STREAM}" = 0 ] ; then
|
||||
unset NGX_STREAM_MODULES NGX_STREAM_SNIPPETS
|
||||
else
|
||||
set -a
|
||||
NGX_STREAM_MODULES="${NGX_STREAM_MODULES:-}"
|
||||
NGX_STREAM_SNIPPETS="${NGX_STREAM_SNIPPETS:-}"
|
||||
set +a
|
||||
fi
|
11
image-entry.d/50-flush-run-volume.sh
Executable file
11
image-entry.d/50-flush-run-volume.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
set -f
|
||||
|
||||
. /image-entry.d/00-common.envsh
|
||||
|
||||
find /run/angie/ -mindepth 1 -exec rm -rf {} +
|
||||
|
||||
[ -d /run/angie/tmp ] || install -d -m 03777 /run/angie/tmp
|
||||
[ -d /run/angie/lock ] || install_userdir /run/angie/lock
|
||||
|
||||
exit 0
|
19
image-entry.d/51-topmost-configs.sh
Executable file
19
image-entry.d/51-topmost-configs.sh
Executable file
@ -0,0 +1,19 @@
|
||||
#!/bin/sh
|
||||
set -f
|
||||
|
||||
. /image-entry.d/00-common.envsh
|
||||
|
||||
s=/etc/angie
|
||||
d=/run/angie
|
||||
|
||||
comps=''
|
||||
[ "${NGX_HTTP}" = 0 ] || comps="${comps} http"
|
||||
[ "${NGX_MAIL}" = 0 ] || comps="${comps} mail"
|
||||
[ "${NGX_STREAM}" = 0 ] || comps="${comps} stream"
|
||||
|
||||
for n in ${comps} ; do
|
||||
ln_s "$s/ctx-$n.conf" "$d/"
|
||||
ln_s "$s/mod-$n.conf" "$d/"
|
||||
done
|
||||
|
||||
exit 0
|
28
image-entry.d/52-merge-tree.sh
Executable file
28
image-entry.d/52-merge-tree.sh
Executable file
@ -0,0 +1,28 @@
|
||||
#!/bin/sh
|
||||
set -ef
|
||||
|
||||
. /image-entry.d/00-common.envsh
|
||||
|
||||
[ -d "${merged_root}" ] || install -d "${merged_root}"
|
||||
|
||||
dirs='conf mod modules njs site snip'
|
||||
[ "${NGX_PROCESS_STATIC}" = 0 ] || dirs="${dirs} static"
|
||||
|
||||
for n in ${dirs} ; do
|
||||
merged_dir="${merged_root}/$n"
|
||||
while read -r old_path ; do
|
||||
[ -n "${old_path}" ] || continue
|
||||
|
||||
new_path=$(remap_path "${old_path}" "${merged_dir}")
|
||||
[ -n "${new_path}" ]
|
||||
|
||||
new_dir="${new_path%/*}"
|
||||
[ -d "${new_dir}" ] || mkdir -p "${new_dir}"
|
||||
|
||||
ln_s "${old_path}" "${new_path}"
|
||||
done <<-EOF
|
||||
$(overlay-dir-list.sh "/etc/angie/$n.dist" "/etc/angie/$n" "/angie/$n")
|
||||
EOF
|
||||
done
|
||||
|
||||
exit 0
|
9
image-entry.d/53-expand-templates.sh
Executable file
9
image-entry.d/53-expand-templates.sh
Executable file
@ -0,0 +1,9 @@
|
||||
#!/bin/sh
|
||||
set -ef
|
||||
|
||||
. /image-entry.d/00-common.envsh
|
||||
|
||||
untemplate_dir_envsubst "${merged_root}"
|
||||
untemplate_dir_jinja "${merged_root}"
|
||||
|
||||
exit 0
|
185
image-entry.d/54-combine-tree.sh
Executable file
185
image-entry.d/54-combine-tree.sh
Executable file
@ -0,0 +1,185 @@
|
||||
#!/bin/sh
|
||||
set -f
|
||||
|
||||
. /image-entry.d/00-common.envsh
|
||||
|
||||
[ "${NGX_STRICT_LOAD}" = 0 ] || set -e
|
||||
|
||||
load_error() {
|
||||
[ "${load_error_seen:-}" = 1 ] || log_always 'tree combine has failed'
|
||||
load_error_seen=1
|
||||
if [ "${NGX_STRICT_LOAD}" = 1 ] ; then
|
||||
t=10
|
||||
log_always "injecting delay for $t seconds"
|
||||
sleep $t
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
smart_ln() {
|
||||
if [ -h "$1" ] ; then
|
||||
ln_s "$(readlink -e "$1")" "$2"
|
||||
else
|
||||
cp "$1" "$2"
|
||||
fi
|
||||
}
|
||||
|
||||
dirs='conf modules njs site'
|
||||
[ "${NGX_PROCESS_STATIC}" = 0 ] || dirs="${dirs} static"
|
||||
while read -r old_path ; do
|
||||
[ -n "${old_path}" ] || continue
|
||||
|
||||
new_path=$(combine_remap_path "${old_path}")
|
||||
[ -n "${new_path}" ]
|
||||
|
||||
new_dir="${new_path%/*}"
|
||||
[ -d "${new_dir}" ] || mkdir -p "${new_dir}"
|
||||
|
||||
smart_ln "${old_path}" "${new_path}"
|
||||
done <<-EOF
|
||||
$(
|
||||
for n in ${dirs} ; do
|
||||
[ -d "${merged_root}/$n" ] || continue
|
||||
find "${merged_root}/$n/" ! -type d
|
||||
done | sort -V
|
||||
)
|
||||
EOF
|
||||
|
||||
if [ "${NGX_PROCESS_STATIC}" = 0 ] ; then
|
||||
for d in /angie/static /etc/angie/static /etc/angie/static.dist ; do
|
||||
[ -d "$d" ] || continue
|
||||
ln_s "$d" /run/angie/static
|
||||
break
|
||||
done
|
||||
fi
|
||||
|
||||
dirs='cache lib log'
|
||||
for n in ${dirs} ; do
|
||||
s="/angie/$n"
|
||||
d="/run/angie/$n"
|
||||
|
||||
if [ -d "$s" ] ; then
|
||||
ln_s "$s" "$d"
|
||||
else
|
||||
[ -d "$d" ] || install_userdir "$d"
|
||||
fi
|
||||
done
|
||||
|
||||
## provide same symlinks as upstream (both Angie and nginx) docker images do
|
||||
d=/run/angie/log
|
||||
[ -e "$d/access.log" ] || ln_s /dev/stdout "$d/access.log"
|
||||
[ -e "$d/error.log" ] || ln_s /dev/stderr "$d/error.log"
|
||||
|
||||
## Angie modules are loaded in [strict] order!
|
||||
combine_modules() {
|
||||
[ -n "$1" ] || return 1
|
||||
n="$1" ; shift
|
||||
|
||||
i=0
|
||||
for m ; do
|
||||
[ -n "$m" ] || continue
|
||||
|
||||
old_name="mod/$n-$m.conf"
|
||||
|
||||
old_path="${merged_root}/${old_name}"
|
||||
if ! [ -f "${old_path}" ] ; then
|
||||
log_always "file ${old_name} is not found"
|
||||
load_error
|
||||
log "file ${old_name} is skipped"
|
||||
continue
|
||||
fi
|
||||
|
||||
new_path=$(printf "/run/angie/mod/$n-%02d-%s.conf" "$i" "$m")
|
||||
new_dir="${new_path%/*}"
|
||||
[ -d "${new_dir}" ] || mkdir -p "${new_dir}"
|
||||
|
||||
smart_ln "${old_path}" "${new_path}"
|
||||
|
||||
i=$((i+1))
|
||||
done
|
||||
}
|
||||
|
||||
combine_modules core ${NGX_CORE_MODULES:-}
|
||||
combine_modules http ${NGX_HTTP_MODULES:-}
|
||||
combine_modules mail ${NGX_MAIL_MODULES:-}
|
||||
combine_modules stream ${NGX_STREAM_MODULES:-}
|
||||
|
||||
combine_snippets() {
|
||||
[ -n "$1" ] || return 1
|
||||
n="$1" ; shift
|
||||
|
||||
for s ; do
|
||||
[ -n "$s" ] || continue
|
||||
|
||||
old_name="snip/$n-$s.conf"
|
||||
|
||||
old_path="${merged_root}/${old_name}"
|
||||
if ! [ -f "${old_path}" ] ; then
|
||||
log_always "file ${old_name} is not found"
|
||||
load_error
|
||||
log "file ${old_name} is skipped"
|
||||
continue
|
||||
fi
|
||||
|
||||
new_path="/run/angie/${old_name}"
|
||||
new_dir="${new_path%/*}"
|
||||
[ -d "${new_dir}" ] || mkdir -p "${new_dir}"
|
||||
|
||||
smart_ln "${old_path}" "${new_path}"
|
||||
done
|
||||
}
|
||||
|
||||
combine_snippets core ${NGX_CORE_SNIPPETS:-}
|
||||
combine_snippets core_ev ${NGX_CORE_EVENTS_SNIPPETS:-}
|
||||
combine_snippets http ${NGX_HTTP_SNIPPETS:-}
|
||||
combine_snippets mail ${NGX_MAIL_SNIPPETS:-}
|
||||
combine_snippets stream ${NGX_STREAM_SNIPPETS:-}
|
||||
|
||||
combine_module_snippets() {
|
||||
[ -n "$1" ] || return 1
|
||||
n="$1" ; shift
|
||||
|
||||
for s ; do
|
||||
[ -n "$s" ] || continue
|
||||
|
||||
old_name="snip/$n-$s.conf"
|
||||
|
||||
old_path="${merged_root}/${old_name}"
|
||||
if ! [ -f "${old_path}" ] ; then
|
||||
log "file ${old_name} is not found, skipping"
|
||||
continue
|
||||
fi
|
||||
|
||||
new_path="/run/angie/${old_name}"
|
||||
new_dir="${new_path%/*}"
|
||||
[ -d "${new_dir}" ] || mkdir -p "${new_dir}"
|
||||
|
||||
smart_ln "${old_path}" "${new_path}"
|
||||
done
|
||||
}
|
||||
|
||||
combine_module_snippets core ${NGX_CORE_MODULES:-}
|
||||
combine_module_snippets http ${NGX_HTTP_MODULES:-}
|
||||
combine_module_snippets mail ${NGX_MAIL_MODULES:-}
|
||||
combine_module_snippets stream ${NGX_STREAM_MODULES:-}
|
||||
|
||||
## merge remaining snippets
|
||||
while read -r old_path ; do
|
||||
[ -n "${old_path}" ] || continue
|
||||
|
||||
new_path=$(combine_remap_path "${old_path}")
|
||||
[ -n "${new_path}" ] || exit 1
|
||||
|
||||
new_dir="${new_path%/*}"
|
||||
[ -d "${new_dir}" ] || mkdir -p "${new_dir}"
|
||||
|
||||
smart_ln "${old_path}" "${new_path}"
|
||||
done <<-EOF
|
||||
$(
|
||||
find "${merged_root}/snip/" ! -type d \
|
||||
| grep -Ev -e "^${merged_root}/snip/(core|core_ev|http|mail|stream)-[^/]*\.conf\$" \
|
||||
| sort -V
|
||||
)
|
||||
EOF
|
||||
|
||||
exit 0
|
11
image-entry.d/55-remove-merged-tree.sh
Executable file
11
image-entry.d/55-remove-merged-tree.sh
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
set -f
|
||||
|
||||
. /image-entry.d/00-common.envsh
|
||||
|
||||
if [ "${IEP_TRACE}" = 1 ] ; then
|
||||
log_always "NOT removing merged tree: ${merged_root}/"
|
||||
else
|
||||
log "removing merged tree: ${merged_root}/"
|
||||
rm -rf "${merged_root}"
|
||||
fi
|
16
image-entry.d/56-adjust-core-user.sh
Executable file
16
image-entry.d/56-adjust-core-user.sh
Executable file
@ -0,0 +1,16 @@
|
||||
#!/bin/sh
|
||||
set -f
|
||||
|
||||
. /image-entry.d/00-common.envsh
|
||||
|
||||
conf=/etc/angie/conf.d/core-user.conf
|
||||
|
||||
if [ "${IEP_ROOT}" = 1 ] ; then
|
||||
log "Running as root, no need to adjust configuration"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
log_always "Running as non-root, adjusting configuration"
|
||||
rm -fv "${conf}"
|
||||
|
||||
exit 0
|
25
image-entry.d/90-angie-config-test.sh
Executable file
25
image-entry.d/90-angie-config-test.sh
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
set -f
|
||||
|
||||
. /image-entry.d/00-common.envsh
|
||||
|
||||
## merely debug test
|
||||
log_always 'test Angie configuration:'
|
||||
log_always '========================='
|
||||
angie -t
|
||||
r=$?
|
||||
log_always '========================='
|
||||
|
||||
## cleanup after test
|
||||
rm -f /run/angie/angie.pid
|
||||
|
||||
if [ $r = 0 ] ; then
|
||||
log_always 'ready to run Angie'
|
||||
else
|
||||
log_always 'configuration test has failed, see above'
|
||||
t=15
|
||||
log_always "injecting delay for $t seconds"
|
||||
sleep $t
|
||||
fi
|
||||
|
||||
exit 0
|
95
image-entry.sh
Executable file
95
image-entry.sh
Executable file
@ -0,0 +1,95 @@
|
||||
#!/bin/sh
|
||||
set -f
|
||||
|
||||
iep_preserve_env() {
|
||||
## preserve LD_PRELOAD
|
||||
unset __IEP_LD_PRELOAD
|
||||
__IEP_LD_PRELOAD="${LD_PRELOAD:-}"
|
||||
unset LD_PRELOAD
|
||||
|
||||
## glibc: preserve MALLOC_ARENA_MAX
|
||||
unset __IEP_MALLOC_ARENA_MAX
|
||||
__IEP_MALLOC_ARENA_MAX=${MALLOC_ARENA_MAX:-2}
|
||||
export MALLOC_ARENA_MAX=2
|
||||
}
|
||||
|
||||
iep_restore_env() {
|
||||
unset IEP_VERBOSE IEP_TRACE IEP_ROOT IEP_LOCAL_OVERRIDE
|
||||
|
||||
## restore LD_PRELOAD
|
||||
if [ -n "${__IEP_LD_PRELOAD}" ] ; then
|
||||
export LD_PRELOAD="${__IEP_LD_PRELOAD}"
|
||||
fi
|
||||
unset __IEP_LD_PRELOAD
|
||||
|
||||
## glibc: restore MALLOC_ARENA_MAX
|
||||
if [ "${MALLOC_ARENA_MAX}" = 2 ] ; then
|
||||
export MALLOC_ARENA_MAX="${__IEP_MALLOC_ARENA_MAX}"
|
||||
fi
|
||||
unset __IEP_MALLOC_ARENA_MAX
|
||||
}
|
||||
|
||||
iep_preserve_env
|
||||
|
||||
## early setup TMPDIR (affects "mktemp")
|
||||
export TMPDIR=/run/angie/tmp
|
||||
[ -d "${TMPDIR}" ] || install -d -m 03777 "${TMPDIR}"
|
||||
|
||||
## RFC: no need to run entire entrypoint for custom command
|
||||
# case "$1" in
|
||||
# angie | */angie ) ;;
|
||||
# * )
|
||||
# unset IEP_INIT DUMB_INIT_ARGS
|
||||
# iep_restore_env
|
||||
# exec "$@"
|
||||
# ;;
|
||||
# esac
|
||||
|
||||
unset __IEP_SRC ; __IEP_SRC="${0##*/}"
|
||||
. /image-entry.d/00-common.envsh
|
||||
|
||||
unexport IEP_INIT DUMB_INIT_ARGS
|
||||
|
||||
## run parts (if any)
|
||||
while read -r f ; do
|
||||
[ -n "$f" ] || continue
|
||||
[ -f "$f" ] || continue
|
||||
|
||||
case "$f" in
|
||||
*.envsh )
|
||||
if ! [ -x "$f" ] ; then
|
||||
log "NOT sourcing $f - not executable"
|
||||
continue
|
||||
fi
|
||||
log_always "sourcing $f"
|
||||
__IEP_SRC="$f"
|
||||
. "$f"
|
||||
__IEP_SRC="${0##*/}"
|
||||
;;
|
||||
* )
|
||||
if ! [ -x "$f" ] ; then
|
||||
log "NOT running $f - not executable"
|
||||
continue
|
||||
fi
|
||||
log_always "running $f"
|
||||
"$f"
|
||||
;;
|
||||
esac
|
||||
done <<EOF
|
||||
$(
|
||||
if [ -d /image-entry ] ; then
|
||||
overlay-dir-list.sh /image-entry.d /image-entry
|
||||
else
|
||||
find /image-entry.d/ -follow -type f | sort -V
|
||||
fi
|
||||
)
|
||||
EOF
|
||||
|
||||
iep_restore_env
|
||||
|
||||
IEP_INIT=$(gobool_to_int "${IEP_INIT:-0}" 0)
|
||||
if [ "${IEP_INIT}" = 0 ] ; then
|
||||
exec "$@"
|
||||
else
|
||||
exec dumb-init ${DUMB_INIT_ARGS} "$@"
|
||||
fi
|
52
scripts/apt-clean.sh
Executable file
52
scripts/apt-clean.sh
Executable file
@ -0,0 +1,52 @@
|
||||
#!/bin/sh
|
||||
set -f
|
||||
|
||||
## apt
|
||||
find /var/cache/apt/ ! -type d ! -name 'lock' -delete
|
||||
find /var/lib/apt/ ! -type d -wholename '/var/lib/apt/listchanges*' -delete
|
||||
find /var/lib/apt/lists/ ! -type d ! -name 'lock' -delete
|
||||
find /var/log/ ! -type d -wholename '/var/log/apt/*' -delete
|
||||
find /var/log/ ! -type d -wholename '/var/log/aptitude*' -delete
|
||||
|
||||
## dpkg
|
||||
: "${DPKG_ADMINDIR:=/var/lib/dpkg}"
|
||||
truncate -s 0 "${DPKG_ADMINDIR}/available"
|
||||
find "${DPKG_ADMINDIR}/" ! -type d -wholename "${DPKG_ADMINDIR}/*-old" -delete
|
||||
find /var/log/ ! -type d -wholename '/var/log/alternatives.log' -delete
|
||||
find /var/log/ ! -type d -wholename '/var/log/dpkg.log' -delete
|
||||
|
||||
## DONT DO THIS AT HOME!
|
||||
find "${DPKG_ADMINDIR}/" ! -type d -wholename "${DPKG_ADMINDIR}/info/*.symbols" -delete
|
||||
|
||||
## debconf
|
||||
find /var/cache/debconf/ ! -type d -wholename '/var/cache/debconf/*-old' -delete
|
||||
|
||||
__t=$(mktemp) ; : "${__t:?}"
|
||||
debconf_trim_i18n() {
|
||||
mawk 'BEGIN { m = 0 }
|
||||
$0 == "" { print }
|
||||
/^[^[:space:]]/ {
|
||||
if ($1 ~ "\.[Uu][Tt][Ff]-?8:") { m = 1; next; }
|
||||
m = 0; print $0;
|
||||
}
|
||||
/^[[:space:]]/ {
|
||||
if (m == 1) next;
|
||||
print $0;
|
||||
}' < "$1" > "${__t}"
|
||||
cat < "${__t}" > "$1"
|
||||
}
|
||||
|
||||
debconf_trim_i18n /var/cache/debconf/templates.dat
|
||||
while read -r tmpl ; do
|
||||
[ -n "${tmpl}" ] || continue
|
||||
[ -s "${tmpl}" ] || continue
|
||||
debconf_trim_i18n "${tmpl}"
|
||||
done <<EOF
|
||||
$(find "${DPKG_ADMINDIR}/info/" -type f -name '*.templates' | sort -V)
|
||||
EOF
|
||||
rm -f "${__t}" ; unset __t
|
||||
|
||||
## misc
|
||||
rm -f /var/cache/ldconfig/aux-cache
|
||||
|
||||
exit 0
|
8
scripts/apt-env.sh
Executable file
8
scripts/apt-env.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
set -a
|
||||
DEBCONF_NONINTERACTIVE_SEEN=true
|
||||
DEBIAN_FRONTEND=noninteractive
|
||||
DEBIAN_PRIORITY=critical
|
||||
TERM=linux
|
||||
set +a
|
||||
exec "$@"
|
118
scripts/apt-install-angie-mod.sh
Executable file
118
scripts/apt-install-angie-mod.sh
Executable file
@ -0,0 +1,118 @@
|
||||
#!/bin/sh
|
||||
set -ef
|
||||
|
||||
[ $# -gt 0 ] || exit 1
|
||||
|
||||
if [ -z "${NGX_DEBUG:-}" ] ; then
|
||||
cat >&2 <<-EOF
|
||||
|
||||
$0:
|
||||
NGX_DEBUG is not set - defaulting to NGX_DEBUG=0
|
||||
|
||||
EOF
|
||||
NGX_DEBUG=0
|
||||
fi
|
||||
|
||||
# ANGIE_MODULES_DIR=/usr/lib/angie/modules
|
||||
d=/etc/angie/mod.dist
|
||||
|
||||
## produce package list
|
||||
p=
|
||||
for i ; do
|
||||
[ -n "$i" ] || continue
|
||||
p="$p${p:+ }angie-module-$i"
|
||||
done
|
||||
|
||||
[ -n "$p" ] || exit 0
|
||||
|
||||
apt-install.sh $p
|
||||
|
||||
[ -d "$d" ] || install -d "$d"
|
||||
|
||||
list_ngx_modules() {
|
||||
set +e
|
||||
dpkg-query -L "$1" \
|
||||
| grep -F -e "${ANGIE_MODULES_DIR}/" \
|
||||
| grep -E -e '/[^/]+_module(-debug)?\.so$' \
|
||||
| sort -V \
|
||||
| xargs -r ls -U1d 2>/dev/null
|
||||
set -e
|
||||
}
|
||||
|
||||
gen_mod_config() {
|
||||
if [ -s "$2" ] ; then
|
||||
printf '%s: configuration already exists: %s\n' "$1" "$2" >&2
|
||||
return
|
||||
fi
|
||||
|
||||
[ -n "$3" ] || return
|
||||
|
||||
for __m in $3 ; do
|
||||
echo "load_module ${__m};" >> "$2"
|
||||
done
|
||||
}
|
||||
|
||||
for i ; do
|
||||
[ -n "$i" ] || continue
|
||||
|
||||
p="angie-module-$i"
|
||||
|
||||
## adjust modules:
|
||||
## - remove debug module if not in debug image
|
||||
## - move debug module to usual location otherwise
|
||||
while read -r fmod ; do
|
||||
case "${fmod}" in
|
||||
*-debug.so ) ;;
|
||||
* ) continue ;;
|
||||
esac
|
||||
|
||||
if [ "${NGX_DEBUG}" = 0 ] ; then
|
||||
rm -fv "${fmod}"
|
||||
else
|
||||
fmod_nodebug="${fmod%-debug.so}.so"
|
||||
rm -fv "${fmod_nodebug}"
|
||||
mv -fv "${fmod}" "${fmod_nodebug}"
|
||||
fi
|
||||
done <<-EOF
|
||||
$(list_ngx_modules "$p")
|
||||
EOF
|
||||
|
||||
if [ -e "$d/.$i.preseed" ] ; then
|
||||
printf '%s: skipping generation of attachable module configs\n' "$p" >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
## produce attachable module configs
|
||||
http_modules=
|
||||
mail_modules=
|
||||
stream_modules=
|
||||
while read -r fmod ; do
|
||||
fmod_short="modules.dist/${fmod#"${ANGIE_MODULES_DIR}/"}"
|
||||
fname=${fmod##*/}
|
||||
case "${fname}" in
|
||||
ngx_http_* )
|
||||
http_modules="${http_modules}${http_modules:+ }${fmod_short}"
|
||||
;;
|
||||
ngx_mail_* )
|
||||
mail_modules="${mail_modules}${mail_modules:+ }${fmod_short}"
|
||||
;;
|
||||
ngx_stream_* )
|
||||
stream_modules="${stream_modules}${stream_modules:+ }${fmod_short}"
|
||||
;;
|
||||
## damn NDK
|
||||
ndk_http_* )
|
||||
http_modules="${http_modules}${http_modules:+ }${fmod_short}"
|
||||
;;
|
||||
* )
|
||||
env printf '%s: unable to determine module type for file (skipping): %q\n' "$p" "${fmod}" >&2
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
done <<-EOF
|
||||
$(list_ngx_modules "$p")
|
||||
EOF
|
||||
|
||||
[ -z "${http_modules}" ] || gen_mod_config "$p" "$d/http-$i.conf" "${http_modules}"
|
||||
[ -z "${mail_modules}" ] || gen_mod_config "$p" "$d/mail-$i.conf" "${mail_modules}"
|
||||
[ -z "${stream_modules}" ] || gen_mod_config "$p" "$d/stream-$i.conf" "${stream_modules}"
|
||||
done
|
44
scripts/apt-install.sh
Executable file
44
scripts/apt-install.sh
Executable file
@ -0,0 +1,44 @@
|
||||
#!/bin/sh
|
||||
set -ef
|
||||
|
||||
find_fresh_ts() {
|
||||
{
|
||||
find "$@" -exec stat -c '%Y' '{}' '+' 2>/dev/null || :
|
||||
# duck and cover!
|
||||
echo 1
|
||||
} | sort -rn | head -n 1
|
||||
}
|
||||
|
||||
_apt_update() {
|
||||
# update package lists; may fail sometimes,
|
||||
# e.g. soon-to-release channels like Debian "bullseye" @ 22.04.2021
|
||||
|
||||
# (wannabe) smart package list update
|
||||
ts_sources=$(find_fresh_ts /etc/apt/ -follow -regextype egrep -regex '.+\.(list|sources)$' -type f)
|
||||
ts_lists=$(find_fresh_ts /var/lib/apt/lists/ -maxdepth 1 -regextype egrep -regex '.+_Packages(\.(bz2|gz|lz[4o]|xz|zstd?))?$' -type f)
|
||||
if [ ${ts_sources} -gt ${ts_lists} ] ; then
|
||||
apt-env.sh apt-get update
|
||||
fi
|
||||
}
|
||||
|
||||
_dpkg_avail_hack() {
|
||||
VERSION_CODENAME=$(. /etc/os-release ; printf '%s' "${VERSION_CODENAME}") || :
|
||||
f="${DPKG_ADMINDIR:-/var/lib/dpkg}/available"
|
||||
# if ${VERSION_CODENAME} is empty then we're on Debian sid or so :)
|
||||
case "${VERSION_CODENAME}" in
|
||||
stretch | buster | bionic | focal )
|
||||
# ref: https://unix.stackexchange.com/a/271387/49297
|
||||
if [ -s "$f" ] ; then
|
||||
return
|
||||
fi
|
||||
/usr/lib/dpkg/methods/apt/update "${DPKG_ADMINDIR:-/var/lib/dpkg}" apt apt
|
||||
;;
|
||||
* )
|
||||
touch "$f"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
_apt_update
|
||||
_dpkg_avail_hack
|
||||
exec apt-env.sh apt-get install -y --no-install-recommends --no-install-suggests "$@"
|
5
scripts/apt-remove.sh
Executable file
5
scripts/apt-remove.sh
Executable file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
set -ef
|
||||
|
||||
apt-env.sh apt-get purge -y --allow-remove-essential "$@"
|
||||
exec apt-env.sh apt-get autopurge -y
|
7
scripts/divert-rm.sh
Executable file
7
scripts/divert-rm.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
set -ef
|
||||
: "${1:?}"
|
||||
d=$(printf '%s' "/run/$1" | tr -s '/')
|
||||
mkdir -p "$(dirname "$d")"
|
||||
dpkg-divert --divert "$d" --rename "$1" 2>/dev/null
|
||||
rm -f "$d"
|
21
scripts/envsubst-args.sh
Executable file
21
scripts/envsubst-args.sh
Executable file
@ -0,0 +1,21 @@
|
||||
#!/bin/sh
|
||||
set -f
|
||||
|
||||
sed -znE '/^([^=]+)=.*$/s,,\1,p' /proc/self/environ \
|
||||
| sed -zE \
|
||||
-e '/^_$/d;/^ENVSUBST_/d;' \
|
||||
-e '/^__IEP/d;/^IEP_(INIT|VERBOSE|TRACE)$/d' \
|
||||
| {
|
||||
if [ -n "${ENVSUBST_EXCLUDE_REGEX:-}" ] ; then
|
||||
grep -zEv -e "${ENVSUBST_EXCLUDE_REGEX}"
|
||||
else
|
||||
if [ -n "${ENVSUBST_INCLUDE_REGEX:-}" ] ; then
|
||||
grep -zE -e "${ENVSUBST_INCLUDE_REGEX}"
|
||||
else
|
||||
cat
|
||||
fi
|
||||
fi
|
||||
} \
|
||||
| sort -zV \
|
||||
| xargs -0 -r printf '${%s} ' \
|
||||
| sed -zE 's/ $//'
|
12
scripts/envsubst.sh
Executable file
12
scripts/envsubst.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
set -f
|
||||
|
||||
while [ -n "${ENVSUBST_ARGS}" ] ; do
|
||||
[ -f "${ENVSUBST_ARGS}" ] || break
|
||||
[ -s "${ENVSUBST_ARGS}" ] || break
|
||||
|
||||
exec envsubst "$(cat "${ENVSUBST_ARGS}" </dev/null)" "$@"
|
||||
exit 126
|
||||
done
|
||||
|
||||
exec envsubst "$(envsubst-args.sh </dev/null)" "$@"
|
98
scripts/jinja.py
Executable file
98
scripts/jinja.py
Executable file
@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env python3
|
||||
import importlib
|
||||
import json
|
||||
import os
|
||||
import os.path
|
||||
import sys
|
||||
|
||||
import jinja2
|
||||
import yaml
|
||||
|
||||
NGX_JINJA_MODULES = sorted(set(os.getenv('NGX_JINJA_MODULES', 'os os.path sys netaddr psutil re wcmatch').split(sep=' ')))
|
||||
|
||||
ME = sys.argv[0]
|
||||
|
||||
NGX_JINJA_SUFFIX = os.getenv('NGX_JINJA_SUFFIX', '.j2')
|
||||
if NGX_JINJA_SUFFIX == '':
|
||||
raise ValueError('NGX_JINJA_SUFFIX is empty')
|
||||
if not NGX_JINJA_SUFFIX.startswith('.'):
|
||||
raise ValueError('NGX_JINJA_SUFFIX does not start with dot (".")')
|
||||
|
||||
NGX_JINJA_CONFIG = os.getenv('NGX_JINJA_CONFIG', '')
|
||||
if (NGX_JINJA_CONFIG != '') and (not os.path.exists(NGX_JINJA_CONFIG)):
|
||||
print(f'{ME}: config does not exist, skipping: {NGX_JINJA_CONFIG}', file=sys.stderr)
|
||||
|
||||
NGX_JINJA_CONFIG_NAMES = [
|
||||
'/angie/jinja',
|
||||
'/etc/angie/jinja',
|
||||
]
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
raise ValueError('not enough arguments (needed: 2)')
|
||||
if len(sys.argv) > 3:
|
||||
raise ValueError('too many arguments (needed: 2)')
|
||||
|
||||
if not sys.argv[1]:
|
||||
raise ValueError('specify input file')
|
||||
input_file = sys.argv[1]
|
||||
if not os.path.exists(input_file):
|
||||
raise ValueError('input file does not exist')
|
||||
|
||||
if len(sys.argv) == 3:
|
||||
if not sys.argv[2]:
|
||||
raise ValueError('specify output file')
|
||||
output_file = sys.argv[2]
|
||||
else:
|
||||
output_file, ext = os.path.splitext(input_file)
|
||||
if ext != NGX_JINJA_SUFFIX:
|
||||
raise ValueError(f'input file name extension mismatch (not a "{NGX_JINJA_SUFFIX}")')
|
||||
|
||||
if input_file == output_file:
|
||||
raise ValueError('unable to process template inplace')
|
||||
|
||||
kwargs = {}
|
||||
for m in NGX_JINJA_MODULES:
|
||||
kwargs[m] = importlib.import_module(m)
|
||||
kwargs['env'] = os.environ
|
||||
kwargs['cfg'] = {}
|
||||
|
||||
|
||||
def merge_dict_from_file(filename):
|
||||
if not filename:
|
||||
return False
|
||||
if not isinstance(filename, str):
|
||||
return False
|
||||
if filename == '':
|
||||
return False
|
||||
if not os.path.exists(filename):
|
||||
return False
|
||||
if not os.path.isfile(filename):
|
||||
print(f'{ME}: not a file, skipping: {filename}', file=sys.stderr)
|
||||
return False
|
||||
if filename.endswith('.yml') or filename.endswith('.yaml'):
|
||||
with open(filename, mode='r', encoding='utf-8') as fx:
|
||||
x = yaml.safe_load(fx)
|
||||
kwargs['cfg'] = kwargs['cfg'] | x
|
||||
return True
|
||||
if filename.endswith('.json'):
|
||||
with open(filename, mode='r', encoding='utf-8') as fx:
|
||||
x = json.load(fx)
|
||||
kwargs['cfg'] = kwargs['cfg'] | x
|
||||
return True
|
||||
print(f'{ME}: non-recognized name extension: {filename}', file=sys.stderr)
|
||||
return False
|
||||
|
||||
|
||||
for base_name in NGX_JINJA_CONFIG_NAMES:
|
||||
for file_name in [ base_name + '.' + ext for ext in [ 'yml', 'yaml', 'json' ] ]:
|
||||
if merge_dict_from_file(file_name):
|
||||
break
|
||||
continue
|
||||
merge_dict_from_file(NGX_JINJA_CONFIG)
|
||||
|
||||
with open(input_file, mode='r', encoding='utf-8') as fin:
|
||||
template = jinja2.Template(fin.read())
|
||||
rendered = template.render(**kwargs)
|
||||
|
||||
with open(output_file, mode='w', encoding='utf-8') as fout:
|
||||
fout.write(rendered)
|
278
scripts/overlay-dir-list.sh
Executable file
278
scripts/overlay-dir-list.sh
Executable file
@ -0,0 +1,278 @@
|
||||
#!/bin/sh
|
||||
set -f
|
||||
|
||||
## ephemeral limit, keep in sync with verify_depth()
|
||||
max_depth=99
|
||||
default_depth=20
|
||||
|
||||
me="${0##*/}"
|
||||
usage() {
|
||||
cat >&2 <<-EOF
|
||||
# usage: ${me} [options] <directory> [<directory> ..]
|
||||
# options:
|
||||
# -d <N>, --depth <N>, --depth=<N>
|
||||
# limit search depth to <N> (default: ${default_depth}, max: ${max_depth})
|
||||
# -z, --zero
|
||||
# separate entries with NUL instead of LF
|
||||
# -s, --split-path
|
||||
# separate directory and file name parts with "|" instead of "/"
|
||||
EOF
|
||||
exit "${1:-0}"
|
||||
}
|
||||
[ $# != 0 ] || usage
|
||||
|
||||
msg() { echo ${1:+"# ${me}: $*"} >&2 ; }
|
||||
msgf() {
|
||||
_____fmt="$1" ; shift
|
||||
env printf "# ${me}: ${_____fmt}\\n" ${@+"$@"} >&2
|
||||
unset _____fmt
|
||||
}
|
||||
|
||||
verify_depth() {
|
||||
case "$1" in
|
||||
[1-9] | [1-9][0-9] ) return 0 ;;
|
||||
esac
|
||||
msgf 'error: wrong depth specifier: %q' "$1"
|
||||
usage 1
|
||||
}
|
||||
|
||||
o_depth=
|
||||
f_zero_eol=
|
||||
f_split_path=
|
||||
|
||||
## process options
|
||||
want_value=
|
||||
n_opt=0
|
||||
for i ; do
|
||||
if [ -n "${want_value}" ] ; then
|
||||
case "${want_value}" in
|
||||
depth )
|
||||
o_depth="$i"
|
||||
verify_depth "${o_depth}"
|
||||
;;
|
||||
esac
|
||||
|
||||
want_value=
|
||||
n_opt=$((n_opt+1))
|
||||
continue
|
||||
fi
|
||||
|
||||
case "$i" in
|
||||
-d | --depth | --depth=* )
|
||||
if [ -n "${o_depth}" ] ; then
|
||||
msg 'error: "depth" option already set'
|
||||
usage 1
|
||||
fi
|
||||
case "$i" in
|
||||
*=* )
|
||||
o_depth="${i#*=}"
|
||||
verify_depth "${o_depth}"
|
||||
;;
|
||||
* ) want_value=depth ;;
|
||||
esac
|
||||
;;
|
||||
-z | --zero )
|
||||
if [ -n "${f_zero_eol}" ] ; then
|
||||
msg 'error: "zero" flag already set'
|
||||
usage 1
|
||||
fi
|
||||
f_zero_eol=1
|
||||
;;
|
||||
-s | --split-path )
|
||||
if [ -n "${f_split_path}" ] ; then
|
||||
msg 'error: "split-path" flag already set'
|
||||
usage 1
|
||||
fi
|
||||
f_split_path=1
|
||||
;;
|
||||
-* )
|
||||
msgf 'unknown option: %q' "$i"
|
||||
usage 1
|
||||
;;
|
||||
* ) break ;;
|
||||
esac
|
||||
|
||||
n_opt=$((n_opt+1))
|
||||
done
|
||||
|
||||
[ ${n_opt} = 0 ] || shift ${n_opt}
|
||||
|
||||
[ $# != 0 ] || usage 1
|
||||
|
||||
: "${o_depth:=${default_depth}}"
|
||||
|
||||
path_sep='/'
|
||||
[ -z "${f_split_path}" ] || path_sep='|'
|
||||
|
||||
entry_sep='\n'
|
||||
[ -z "${f_zero_eol}" ] || entry_sep='\0'
|
||||
|
||||
entry_fmt="%s${path_sep}%s${entry_sep}"
|
||||
|
||||
## work directory
|
||||
w=$(mktemp -d) ; : "${w:?}"
|
||||
|
||||
_cleanup() {
|
||||
cd /
|
||||
rm -rf -- "$w"
|
||||
}
|
||||
|
||||
adjust_with_skiplist() {
|
||||
[ -s "$1" ] || return 0
|
||||
[ -s "$2" ] || return 0
|
||||
|
||||
__skiptype="$3"
|
||||
while read -r __skipname ; do
|
||||
[ -n "${__skipname}" ] || continue
|
||||
|
||||
mawk \
|
||||
-v "n=${__skipname}" \
|
||||
-v "t=${__skiptype}" \
|
||||
'
|
||||
BEGIN {
|
||||
RS = ORS = "\0";
|
||||
FS = OFS = "|";
|
||||
}
|
||||
{
|
||||
if ($3 != n) { print; next; }
|
||||
if (t == "") { next; }
|
||||
if ($1 ~ t) { next; }
|
||||
print;
|
||||
}
|
||||
' < "$2" > "$2.t"
|
||||
mv -f "$2.t" "$2"
|
||||
done < "$1"
|
||||
unset __skipname __skiptype
|
||||
}
|
||||
|
||||
: > "$w/all"
|
||||
|
||||
## process arguments
|
||||
for i ; do
|
||||
## arguments with '|' are skipped - try naming paths simplier
|
||||
case "$i" in
|
||||
*\|* )
|
||||
msgf 'argument with "|" is IGNORED: %q' "$i"
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
||||
## non-existent directories are silently skipped
|
||||
[ -d "$i" ] || continue
|
||||
|
||||
## generate directory listing
|
||||
## paths with '\n' and '|' are silently skipped - try naming paths simplier
|
||||
find "$i/" -follow -mindepth 1 -maxdepth 1 ! -name '*|*' -printf '%y|%h|%P\0' \
|
||||
| sed -zE '/\n/d' > "$w/current"
|
||||
|
||||
## filter out uncommon entry types
|
||||
## allowed types:
|
||||
## d - directory
|
||||
## f - file
|
||||
## less common types (but also allowed):
|
||||
## b - block device
|
||||
## c - character device
|
||||
## p - pipe
|
||||
## s - socket
|
||||
sed -i -zE '/^[^bcdfps]/d' "$w/current"
|
||||
|
||||
## empty directory - continue with next argument
|
||||
[ -s "$w/current" ] || continue
|
||||
|
||||
## generate skiplist
|
||||
grep -zE '\.-$' < "$w/current" \
|
||||
| cut -z -d '|' -f 3 \
|
||||
| sed -zE 's/\.-$//' \
|
||||
| tr '\0' '\n' > "$w/skip"
|
||||
## adjust current list: remove entries from skiplist
|
||||
sed -i -zE '/\.-$/d' "$w/current"
|
||||
|
||||
## adjust accumulated list: remove "skip" entries
|
||||
adjust_with_skiplist "$w/skip" "$w/all"
|
||||
rm -f "$w/skip"
|
||||
|
||||
## adjust accumulated list: override all entries with "non-dir" entries from current list
|
||||
## NB: entry type from current list overrides entry from previously accumulated list
|
||||
sed -zEn '/^[^d]/p' < "$w/current" \
|
||||
| cut -z -d '|' -f 3 \
|
||||
| tr '\0' '\n' > "$w/nondir"
|
||||
adjust_with_skiplist "$w/nondir" "$w/all"
|
||||
rm -f "$w/nondir"
|
||||
|
||||
## adjust accumulated list: override "non-dir" entries with "dir" entries from current list
|
||||
## NB: entry type from current list overrides entry from previously accumulated list
|
||||
sed -zEn '/^d/p' < "$w/current" \
|
||||
| cut -z -d '|' -f 3 \
|
||||
| tr '\0' '\n' > "$w/dir"
|
||||
adjust_with_skiplist "$w/dir" "$w/all" '[^d]'
|
||||
rm -f "$w/dir"
|
||||
|
||||
## merge lists
|
||||
sort -zV -t '|' -k 3 < "$w/current" >> "$w/all"
|
||||
rm -f "$w/current"
|
||||
done
|
||||
|
||||
# nothing to do?
|
||||
if ! [ -s "$w/all" ] ; then
|
||||
_cleanup
|
||||
exit 0
|
||||
fi
|
||||
|
||||
cut -z -d '|' -f '3' < "$w/all" \
|
||||
| sort -zuV \
|
||||
| tr '\0' '\n' > "$w/names"
|
||||
|
||||
: > "$w/dirnames"
|
||||
|
||||
sub_depth=$(( o_depth - 1 ))
|
||||
|
||||
while read -r name ; do
|
||||
mawk \
|
||||
-v "n=${name}" \
|
||||
'
|
||||
BEGIN {
|
||||
RS = "\0"; ORS = "\n";
|
||||
FS = OFS = "|";
|
||||
}
|
||||
|
||||
$3 == n { print; }
|
||||
' < "$w/all" > "$w/list"
|
||||
|
||||
while IFS='|' read -r dtype dir _name ; do
|
||||
[ -n "${dtype}" ] || continue
|
||||
|
||||
# ${_name} is unused
|
||||
case "${dtype}" in
|
||||
d )
|
||||
[ "${sub_depth}" != 0 ] || continue
|
||||
|
||||
if grep -Fxq -e "${name}" "$w/dirnames" ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
printf '%s\n' "${name}" >> "$w/dirnames"
|
||||
|
||||
mawk \
|
||||
-v "n=${name}" \
|
||||
'
|
||||
BEGIN {
|
||||
ORS = "\0";
|
||||
FS = "|"; OFS = "/";
|
||||
}
|
||||
|
||||
$3 == n { print $2,$3; }
|
||||
' < "$w/list" > "$w/dir.args"
|
||||
|
||||
xargs -0 -a "$w/dir.args" "$0" ${f_zero_eol:+-z} ${f_split_path:+-s} -d "${sub_depth}"
|
||||
rm -f "$w/dir.args"
|
||||
;;
|
||||
* )
|
||||
printf "${entry_fmt}" "${dir}" "${name}"
|
||||
;;
|
||||
esac
|
||||
done < "$w/list"
|
||||
|
||||
done < "$w/names"
|
||||
|
||||
_cleanup
|
||||
exit 0
|
8
scripts/pip-env.sh
Executable file
8
scripts/pip-env.sh
Executable file
@ -0,0 +1,8 @@
|
||||
#!/bin/sh
|
||||
set -a
|
||||
PIP_DISABLE_PIP_VERSION_CHECK=1
|
||||
PIP_NO_CACHE_DIR=1
|
||||
PIP_ROOT_USER_ACTION=ignore
|
||||
PIP_NO_COMPILE=1
|
||||
set +a
|
||||
exec "$@"
|
7
scripts/python-rm-cache.sh
Executable file
7
scripts/python-rm-cache.sh
Executable file
@ -0,0 +1,7 @@
|
||||
#!/bin/sh
|
||||
set -f
|
||||
for i ; do
|
||||
find "$i/" -name __pycache__ -exec rm -rf {} +
|
||||
find "$i/" ! -type d -name '*.py[co]' -exec rm -f {} +
|
||||
done
|
||||
exit 0
|
65
scripts/static-compress.sh
Executable file
65
scripts/static-compress.sh
Executable file
@ -0,0 +1,65 @@
|
||||
#!/bin/sh
|
||||
set -f
|
||||
|
||||
COMPRESS_MIN_RATIO=90
|
||||
|
||||
if command -V gzip >/dev/null ; then has_gzip=1 ; fi
|
||||
if command -V brotli >/dev/null ; then has_brotli=1 ; fi
|
||||
if command -V zstd >/dev/null ; then has_zstd=1 ; fi
|
||||
|
||||
do_gzip() { [ -s "$1.gz" ] || gzip -1kf "$1" ; comp_fixup "$1" "$1.gz" ; }
|
||||
do_brotli() { [ -s "$1.br" ] || brotli -1kf "$1" ; comp_fixup "$1" "$1.br" ; }
|
||||
do_zstd() { [ -s "$1.zst" ] || zstd -q1kf "$1" ; comp_fixup "$1" "$1.zst" ; }
|
||||
|
||||
comp_fixup() {
|
||||
size1=$(env stat -c '%s' "$1") || return
|
||||
|
||||
[ -f "$2" ] || return
|
||||
[ -s "$2" ] || { rm -f "$2" ; return ; }
|
||||
size2=$(env stat -c '%s' "$2") || return
|
||||
|
||||
pow1=${#size1} ; pow2=${#size2}
|
||||
|
||||
## if size2 is _longer_ than size1 - compression did something wrong (file is bigger)
|
||||
if [ ${pow2} -gt ${pow1} ] ; then
|
||||
rm -f "$2" ; return
|
||||
fi
|
||||
|
||||
## if size1 is _longer_ size2 more than 2 digits - compression was done very successful
|
||||
## doubtful but okay (c) Oleg Tinkov
|
||||
if [ $(( pow1 - pow2 )) -gt 2 ] ; then
|
||||
return
|
||||
fi
|
||||
|
||||
## math hack!
|
||||
if [ ${pow1} -gt 7 ] ; then
|
||||
skew=$(( pow1 - 4 ))
|
||||
pow1=$(( pow1 - skew ))
|
||||
pow2=$(( pow2 - skew ))
|
||||
size1=$(printf '%s' "${size1}" | cut -c 1-${pow1})
|
||||
size2=$(printf '%s' "${size2}" | cut -c 1-${pow2})
|
||||
fi
|
||||
|
||||
ratio=$(( (100 * size2) / size1 ))
|
||||
if [ ${ratio} -ge ${COMPRESS_MIN_RATIO} ] ; then
|
||||
rm -f "$2"
|
||||
else
|
||||
## seems to be excessive
|
||||
: touch -r "$1" -m "$2"
|
||||
fi
|
||||
}
|
||||
|
||||
for i ; do
|
||||
[ -n "$i" ] || continue
|
||||
|
||||
case "$i" in
|
||||
*.br | *.gz | *.zst ) continue ;;
|
||||
esac
|
||||
|
||||
[ -f "$i" ] || continue
|
||||
[ -s "$i" ] || continue
|
||||
|
||||
[ -z "${has_gzip}" ] || do_gzip "$i"
|
||||
[ -z "${has_brotli}" ] || do_brotli "$i"
|
||||
[ -z "${has_zstd}" ] || do_zstd "$i"
|
||||
done
|
Loading…
Reference in New Issue
Block a user