From 1f872dc8be3292cbac7a55fb1017a7c3375b78f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20L=C3=B6sche?= Date: Fri, 29 Sep 2023 13:42:01 +0200 Subject: [PATCH] Add Dockerfile --- Dockerfile | 68 +++++++++++++++++++ bootstrap | 140 +++++++++++++++++++++++++++++++++++++++ fixca/args.py | 32 +++++++-- fixca/static/favicon.ico | Bin 0 -> 15406 bytes 4 files changed, 235 insertions(+), 5 deletions(-) create mode 100644 Dockerfile create mode 100755 bootstrap create mode 100644 fixca/static/favicon.ico diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..653f119 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,68 @@ +FROM ubuntu:23.04 as build-env +ENV DEBIAN_FRONTEND=noninteractive +ARG TARGETPLATFORM +ARG BUILDPLATFORM +ARG TESTS +ARG SOURCE_COMMIT + +ENV PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +RUN echo "I am running on ${BUILDPLATFORM}, building for ${TARGETPLATFORM}" + +# Prepare whl build env +RUN mkdir -p /usr/local/build + +# Build FIX CA +COPY bootstrap /usr/local/sbin/bootstrap +COPY . /usr/src/fixca +RUN apt-get update +RUN apt-get -y install apt-utils +RUN apt-get -y dist-upgrade +RUN apt-get -y install \ + openssl \ + ca-certificates \ + python3 \ + python3-pip \ + python3-setuptools \ + python3-build \ + python3-wheel + +WORKDIR /usr/src/fixca +RUN pip wheel --wheel-dir=/usr/local/build --no-cache-dir . +RUN echo "${SOURCE_COMMIT:-unknown}" > /usr/local/etc/git-commit.HEAD + + +# Setup main image +FROM ubuntu:23.04 +ENV DEBIAN_FRONTEND=noninteractive +ENV LANG="en_US.UTF-8" +ENV TERM="xterm-256color" +ENV COLORTERM="truecolor" +ENV EDITOR="vi" +COPY --from=build-env /usr/local /usr/local +ENV PATH=/usr/local/python/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin +WORKDIR / +RUN groupadd -g "${PGID:-0}" -o fix \ + && useradd -g "${PGID:-0}" -u "${PUID:-0}" -o --create-home fix \ + && apt-get update \ + && apt-get -y --no-install-recommends install apt-utils \ + && apt-get -y dist-upgrade \ + && apt-get -y --no-install-recommends install \ + dumb-init \ + iproute2 \ + dateutils \ + openssl \ + ca-certificates \ + locales \ + python3-minimal \ + python3-pip \ + && ln -s /usr/bin/busybox /usr/local/bin/vi \ + && ln -s /usr/bin/busybox /usr/local/bin/less \ + && echo 'LANG="en_US.UTF-8"' > /etc/default/locale \ + && echo "en_US.UTF-8 UTF-8" >> /etc/locale.gen \ + && locale-gen \ + && pip install --no-cache-dir --break-system-packages /usr/local/build/*.whl \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* /usr/local/build + +ENTRYPOINT ["/bin/dumb-init", "--", "/usr/local/sbin/bootstrap"] +CMD ["/usr/local/bin/fixca"] diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000..a7a2737 --- /dev/null +++ b/bootstrap @@ -0,0 +1,140 @@ +#!/bin/bash +# Bootstraps runit config +set -euo pipefail + +TZ=${TZ:-Etc/UTC} +PUID=${PUID:-0} +PGID=${PGID:-0} + + +main() { + apply_permissions + configure_timezone + setup_etc_hosts || true + exec runuser -u fix -g fix -- "$@" +} + + +# Apply user id and group id +apply_permissions() { + info "Setting uid:gid of fix to $PUID:$PGID" + groupmod -g "${PGID}" -o fix + #usermod -u "${PUID}" -o -g fix fix + sed -i -E "s/^(fix:x):[0-9]+:[0-9]+:(.*)/\\1:$PUID:$PGID:\\2/" /etc/passwd + chown fix:fix /home/fix +} + + +# Configure timezone +configure_timezone() { + export TZ + if [ ! -f "/usr/share/zoneinfo/$TZ" ]; then + warn "Unknown timezone $TZ - defaulting to Etc/UTC" + TZ="Etc/UTC" + fi + ln -snf "/usr/share/zoneinfo/$TZ" /etc/localtime + echo "$TZ" > /etc/timezone + info "Setting timezone $TZ" +} + + +# Enable/disable IP protocols in /etc/hosts +setup_etc_hosts() { + local temp_hosts + temp_hosts="$(mktemp)" + cat /etc/hosts > "$temp_hosts" + + if ipv4_enabled; then + sed -i -E "s/^#(127\.0\.0\.1.*)/\1/" "$temp_hosts" + else + sed -i -E "s/^(127\.0\.0\.1.*)/#\1/" "$temp_hosts" + fi + + if ipv6_enabled; then + sed -i -E "s/^#(::1.*)/\1/" "$temp_hosts" + else + sed -i -E "s/^(::1.*)/#\1/" "$temp_hosts" + fi + + # /etc/hosts is singularly mounted into the container. + # sed -i is not really working in-place but instead + # creates a temp file and then moves it. So would fail + # on /etc/hosts. Instead of atomically moving + # we cat the temp file into the destination. + cat "$temp_hosts" > /etc/hosts + rm -f "$temp_hosts" +} + + +ipv_enabled() { + local ip_version=$1 + # shellcheck disable=SC2086 + if [ "$(ip -$ip_version addr | wc -l)" -gt 0 ]; then + return 0 + fi + return 1 +} + + +ipv4_enabled() { + ipv_enabled 4 +} + + +ipv6_enabled() { + ipv_enabled 6 +} + + +# log levels +debug=50 +info=40 +warn=30 +error=20 +critical=10 +fatal=5 +log_level=${log_level:-$debug} + + +debug() { logstd $debug "DEBUG - [$$] - $*"; } +info() { logstd $info "INFO - $*"; } +warn() { logstd $warn "WARN - $*"; } +error() { logerr $error "ERROR - $*"; } +critical() { logerr $critical "CRITIAL - $*"; } +fatal() { logerr $fatal "FATAL - $*"; exit 1; } + + +logstd() { + local log_at_level + log_at_level="$1"; shift + printline "$log_at_level" "$*" +} + + +logstd() { + local log_at_level + log_at_level="$1"; shift + printline "$log_at_level" "$*" +} + + +logerr() { + local log_at_level + log_at_level="$1"; shift + printline "$log_at_level" "$*" >&2 +} + + +printline() { + local log_at_level + local log_data + log_at_level="$1"; shift + log_data="$*" + + if [ "$log_at_level" -le "$log_level" ]; then + echo "$log_data" + fi +} + + +main "$@" diff --git a/fixca/args.py b/fixca/args.py index 0f31c80..a4a3c61 100644 --- a/fixca/args.py +++ b/fixca/args.py @@ -1,13 +1,35 @@ +import os from argparse import ArgumentParser, Namespace from typing import Callable, List def parse_args(add_args: List[Callable]) -> Namespace: parser = ArgumentParser(prog="fixca", description="FIX Certification Authority") - parser.add_argument("--psk", dest="psk", help="Pre-shared-key", required=True) - parser.add_argument("--port", dest="port", help="HTTPS port to listen on (default: 7900)", default=7900, type=int) - parser.add_argument("--namespace", dest="namespace", help="K8s namespace (default: fix)", default="fix") - parser.add_argument("--secret", dest="secret", help="Secret name (default: fix-ca)", default="fix-ca") + parser.add_argument("--psk", dest="psk", help="Pre-shared-key", default=os.environ.get("FIXCA_PSK")) + parser.add_argument( + "--port", + dest="port", + help="HTTPS port to listen on (default: 7900)", + default=os.environ.get("FIXCA_PORT", 7900), + type=int, + ) + parser.add_argument( + "--namespace", + dest="namespace", + help="K8s namespace (default: fix)", + default=os.environ.get("FIXCA_NAMESPACE", "fix"), + ) + parser.add_argument( + "--secret", + dest="secret", + help="Secret name (default: fix-ca)", + default=os.environ.get("FIXCA_SECRET", "fix-ca"), + ) for add_arg in add_args: add_arg(parser) - return parser.parse_args() + + args = parser.parse_args() + if args.psk is None: + parser.error("Missing --psk argument") + + return args diff --git a/fixca/static/favicon.ico b/fixca/static/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..6f95354ee2fe7b4c49349bb04bcb8b8b0e137e1d GIT binary patch literal 15406 zcmeHN=~EO(6rWV`2bd4}78MhCiscofCMq6LbC@!*N=-Zx z!!9120a*lDMHD<%RM6-OYfuysQ3PcXQI6$?eR;2;huPg3G7DH0lkTdX>FIv2->+Z4 z>3Q?ICFv>YX{kpK3GY7A=g&ye5J{4Jd|ICeJS$0|ST|@;TYG;=I{Ta?4L}-XL5|jX zys4((;m?D}UDts%YC9x+=_~6pX4WvsP7H&@Wqy!z=npWCc>&vcLRReWkh*?>OviO^ zzh;A@KQ5H(6PNlyb?IF&j`9Kf)hx)2{tYafmqS%)G3@qzS*BC+=N^rR^x$=nw)Jb^ z{L~&j<9(=iR6>KJ3e3y=J$Q+R`O=a(>z&*gJbTTs^!OV&{y2o2Qe3 zFpv&uj0aZ+c<}Rn#N9hvR$UalsHAnq2lFt@v_5GiF)!ZDi_n+Qm#~5Vt_{$4E%}>S z5WjGO=C>?*=1@kn|Eoz5GPW-(6A$sa+eWzmV7Waq;2n>4cY5+oC>3O+YSNw$+stT6 zu2>mOp2f_b>na~Yxc?jNd?R{6u`PqORoRPR_e4+sq&wvA@g2x~A`*1_+%X6q(UV~~ zv*SA^+u72B{*7Ndt`2Zh~viPvT_ zFnJ9%)lhchGAozexYFih>U(Fn{HFRkrc?4Yc`nL4&BozA|9lQZ&<`ui&tY=u($r9g z{@O>n$F3Z|+=-%4ek->_`NV%M#Uyi7+`R=MrKyviTM*YAZ$R`fUp5! z1HuM`4gC9UAY|-|5P@+b%3*$k!8qD;4_a*=!zRBj^Rajr#++&Yo%cm|>RXMM>I@@$ zLD;1BK1jAK}pU< zx&GYF4Vrz$%^wX#S?MxuwmD2!eBXT>bS8i&N0}Ys=8w^oDf1$Jifi*kF<)w0D9Y-wr)I{&eATtBui zle8)TY9Bq2@fX|9Vr;lIUhIxd&-3HJPjTAZ)O~HSe6$aYJDYKThhpq^tZ8yR#mMPB z(1TNp=5gRBS*E$8prW`y*7KvH0yrPKNygsXP!Ac#^_^OClw(oiCp}qlEur&BYB_1u z^j2MIyuZqRseBC2JrPcxoGs0~$oBa{as71X@%CAXpZ0D@9_`zy<%0ASukagjJjPO1Nz2c?j(*cWz=@28q&e?W)* z8^`ov-)N4T*7=INh5QjJ?-jzn1>?Fr2TJ^1{r+;Dk#BQi;}U4ZeP~Mb-exC;Li`uw zp|+xJ?Z@%t;n~046JP4m7?k+wy*jjdhRdFOiYoJ@$EI)wRi z7o&fL=Eep#E_yFcZCl-K_?^wo;CNt%s**dZna+DM9d~3u*p`1P374|gvj}vylg^KF z--h0a@`7B3pDwg!o4W7~Q|e#tRHNX)_oE~Hqgw@C5*;G0c!|SO``c}hZjod2J(YKlGNbUTq z8n3dB{Hmzw@9D})Kay~9KJsg*&s`Jxv+okG566EJr7UIHT`v907|`~VG@`8UA42F! i=t0NJ0ah*1+Ep