diff --git a/custom/testing/entrypoint.py b/custom/testing/entrypoint.py index b853264..676c314 100644 --- a/custom/testing/entrypoint.py +++ b/custom/testing/entrypoint.py @@ -1,4 +1,4 @@ -#! env python3 +#!/usr/bin/python3 """ Systemd entrypoint hack. diff --git a/custom/testing/systemd-ubuntu-22.04.Dockerfile b/custom/testing/systemd-ubuntu-22.04.Dockerfile index 228ef98..e5cdb69 100644 --- a/custom/testing/systemd-ubuntu-22.04.Dockerfile +++ b/custom/testing/systemd-ubuntu-22.04.Dockerfile @@ -1,5 +1,8 @@ FROM ubuntu:22.04 +COPY 01_nodoc /etc/dpkg/dpkg.cfg.d/01_nodoc +COPY entrypoint.py entrypoint.py + # init and systemd are the only real requirements for systemd. # # tar wget x-utils can be used to fetch and extract a salt onedir. @@ -8,18 +11,23 @@ FROM ubuntu:22.04 # states. # # tree is used by workflows for debugging +# +# coreutils provides tail RUN apt update -y \ && echo 'tzdata tzdata/Areas select America' | debconf-set-selections \ && echo 'tzdata tzdata/Zones/America select Phoenix' | debconf-set-selections \ && DEBIAN_FRONTEND="noninteractive" apt install -y \ - tree tar wget xz-utils apt-utils systemd python3 python3-pip python3-venv git + coreutils tree tar wget xz-utils apt-utils systemd python3 python3-pip python3-venv git \ + && chmod +x entrypoint.py \ + && mv /usr/bin/tail /usr/bin/tail.real -COPY 01_nodoc /etc/dpkg/dpkg.cfg.d/01_nodoc -COPY entrypoint.py entrypoint.py # Set the root password, this was done before single user mode worked. # RUN echo "root\nroot" | passwd -q root # RUN echo "systemd.debug_shell=tty1" >> /etc/sysctl.conf COPY rescue.service /etc/systemd/system/rescue.service.d/override.conf +COPY tail /usr/bin/tail + +RUN chmod +x /usr/bin/tail -ENTRYPOINT [ "/usr/bin/python3", "entrypoint.py" ] +ENTRYPOINT [ "/entrypoint.py" ] CMD [ "/bin/bash" ] diff --git a/custom/testing/tail b/custom/testing/tail new file mode 100755 index 0000000..f16011c --- /dev/null +++ b/custom/testing/tail @@ -0,0 +1,39 @@ +#!/usr/bin/python3 +""" +Systemd entrypoint hack. + +Writes /cmd.sh from the arguments passed to the script. Then execve systemd so +systemd will be process 1. The target rescue will execute /cmd.sh using /bin/sh. +This is needed so our ENTRYPOINT can be systemd with a target and CMD can be +customized at runtime as expected. +""" +from __future__ import annotations + +import os +import sys + + +def run_execve(cmd, args=None): + if args is None: + args = [] + args = [cmd] + args + os.environ["PYTHONPATH"] = os.pathsep.join(sys.path) + if os.execve in os.supports_fd: + with open(cmd, "rb") as fp: + os.execve(fp.fileno(), args, os.environ) + else: + args = [cmd] + args + os.execve(cmd, args, os.environ) + + +pid = os.getpid() +if pid != 0: + cmd = "/usr/bin/tail.real" + run_execve(cmd, sys.argv[1:]) +else: + with open("/cmd.sh", "w") as fp: + if sys.argv[1:]: + fp.write(f"tail.real", sys.argv[1:]) + else: + fp.write(f"tail.real") + run_execve("/usr/lib/systemd/systemd", ["--systemd", "--unit=rescue.target"])