commit b3e063d79a59fe783b995000dd2f46eb23ca5077 Author: Konstantin Demin Date: Wed Sep 25 07:15:38 2024 +0300 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2136fe --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/.vscode +/artifact-cache diff --git a/Dockerfile.base b/Dockerfile.base new file mode 100644 index 0000000..6fa1132 --- /dev/null +++ b/Dockerfile.base @@ -0,0 +1,236 @@ +# FROM docker.io/debian:bookworm-slim as base-upstream +ARG BASETAG=bookworm-slim +FROM docker.io/debian:${BASETAG} AS base-upstream + +FROM base-upstream AS base-intermediate +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 \ + JRE_CACERTS_PATH=/etc/ssl/certs/java/cacerts + +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 \ + addpart \ + apt-ftparchive \ + agetty \ + badblocks \ + blkdiscard \ + blkid \ + blkzone \ + blockdev \ + bsd-write \ + chage \ + chcpu \ + chmem \ + ctrlaltdel \ + debugfs \ + delpart \ + dmesg \ + dumpe2fs \ + e2freefrag \ + e2fsck \ + e2image \ + e2label \ + e2mmpstatus \ + e2scrub \ + 'e2scrub*' \ + e2undo \ + e4crypt \ + e4defrag \ + faillock \ + fdformat \ + fincore \ + findfs \ + fsck \ + 'fsck.*' \ + fsfreeze \ + fstrim \ + getty \ + hwclock \ + isosize \ + last \ + lastb \ + ldattach \ + losetup \ + lsblk \ + lsirq \ + lslogins \ + mcookie \ + mesg \ + mke2fs \ + mkfs \ + 'mkfs.*' \ + 'mklost+found' \ + mkswap \ + mount \ + pam-auth-update \ + pam_getenv \ + pam_namespace_helper \ + pam_timestamp_check \ + partx \ + pivot_root \ + raw \ + readprofile \ + resize2fs \ + resizepart \ + rtcwake \ + swaplabel \ + swapoff \ + swapon \ + switch_root \ + tune2fs \ + umount \ + 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 \ + e2fsprogs \ + ; \ + apt-install.sh \ + ca-certificates \ + ca-certificates-java \ + fontconfig \ + p11-kit \ + netbase \ + openssl \ + procps \ + psmisc \ + ; \ + apt-clean.sh + +## set up locales! +RUN _lang=en_US.UTF8 ; \ + { \ + echo "locales locales/default_environment_locale select ${LANG}" ; \ + echo "locales locales/locales_to_be_generated multiselect ${LANG} UTF-8" ; \ + } | debconf-set-selections ; \ + f=/etc/dpkg/dpkg.cfg.d/docker ; \ + if [ -f "$f" ] ; then \ + sed -Ei '/\/usr\/share\/locale/d' "$f" ; \ + fi ; \ + echo "LANG=${_lang}" > /etc/default/locale ; \ + apt-install.sh locales ; apt-clean.sh ; \ + grep -Fixq "${_lang} UTF-8" /etc/locale.gen || { \ + echo "${_lang} UTF-8" >> /etc/locale.gen ; \ + locale-gen ; \ + } ; \ + locale -a | grep -Fixq "${_lang}" +ENV LANG='en_US.UTF-8' LANGUAGE='en_US:en' LC_ALL='en_US.UTF-8' + +RUN find /usr/local/sbin/ ! -type d -ls -delete ; \ + find /run/ -mindepth 1 -ls -delete || : ; \ + install -d -m 01777 /run/lock + +## --- + +FROM base-intermediate AS certs +SHELL [ "/bin/sh", "-ec" ] + +COPY /scripts/* /usr/local/sbin/ +COPY /extra-scripts/* /usr/local/sbin/ + +## "2024.08.30" +ENV CERTIFI_COMMIT=325c2fde4f8eec10d682b09f3b0414dc05e69a81 + +# 'https://raw.githubusercontent.com/certifi/python-certifi' +ARG CERTIFI_BASE_URI='https://github.com/certifi/python-certifi/raw' + +ARG CERTIFI_URI="${CERTIFI_BASE_URI}/${CERTIFI_COMMIT}/certifi/cacert.pem" +ADD "${CERTIFI_URI}" /tmp/certifi.crt + +RUN ca_file='/etc/ssl/certs/ca-certificates.crt' ; \ + java_ca_file='/etc/ssl/certs/java/cacerts' ; \ + apt-install.sh default-jre-headless ; \ + apt-clean.sh ; \ + update-ca-certificates --fresh ; \ + echo ; \ + ls -l "${ca_file}" "${java_ca_file}" ; \ + echo ; \ + ## process certifi + certifi-extras.sh /tmp/certifi.crt ; \ + openssl-cert-auto-pem.sh "${ca_file}" "${ca_file}.new" "${ca_file}.fp" ; \ + mv -f "${ca_file}.new" "${ca_file}" ; \ + chmod 0644 "${ca_file}" "${ca_file}.fp" "${java_ca_file}" ; \ + echo ; \ + ls -l "${ca_file}" "${ca_file}.fp" "${java_ca_file}" + +## --- + +FROM base-intermediate AS base + +COPY /scripts/* /usr/local/sbin/ + +COPY --from=certs /etc/ssl/certs/ca-certificates.* /etc/ssl/certs/ +COPY --from=certs /etc/ssl/certs/java/cacerts /etc/ssl/certs/java/ +COPY --from=certs /usr/local/share/ca-certificates/ /usr/local/share/ca-certificates/ + +ENTRYPOINT [ ] +CMD [ "bash" ] diff --git a/Dockerfile.jdk b/Dockerfile.jdk new file mode 100644 index 0000000..12924eb --- /dev/null +++ b/Dockerfile.jdk @@ -0,0 +1,79 @@ +ARG IMAGE_VERSION +FROM docker.io/rockdrilla/graalvm-debian:base-${IMAGE_VERSION} AS base + +## --- + +FROM base as jdk-fetch +SHELL [ "/bin/sh", "-ec" ] + +COPY /scripts/* /usr/local/sbin/ + +# ARG JAVA_VERSION_MAJOR +# ARG GRAALVM_BASE_FILE="graalvm-jdk-${JAVA_VERSION_MAJOR}_linux-x64_bin.tar.gz" +# ARG GRAALVM_BASE_URI="https://download.oracle.com/graalvm/${JAVA_VERSION_MAJOR}/latest" +# ARG GRAALVM_URI="${GRAALVM_BASE_URI}/${GRAALVM_BASE_FILE}" +# ADD "${GRAALVM_URI}" /tmp/graalvm.tar.gz + +ARG GRAALVM_BASE_FILE +COPY "/artifact-cache/${GRAALVM_BASE_FILE}" /tmp/graalvm.tar.gz + +ARG PSL_URI='https://publicsuffix.org/list/public_suffix_list.dat' +ADD "${PSL_URI}" /tmp/public_suffix_list.dat + +WORKDIR /opt/graalvm + +RUN tar --strip-components=1 -xf /tmp/graalvm.tar.gz ; \ + rm -rf \ + GRAALVM-README.md \ + license-information-user-manual.zip \ + lib/security/cacerts \ + lib/security/krb5.conf \ + ; \ + cp -f /tmp/public_suffix_list.dat lib/security/ ; \ + ln -sv /etc/ssl/certs/java/cacerts lib/security/ ; \ + ln -sv /etc/krb5.conf lib/security/ ; \ + find "${PWD}/" -name '*.so' -exec dirname '{}' '+' \ + | sort -uV > ld.so.conf ; \ + chmod -R go-w "${PWD}/" + +## https://github.com/docker-library/openjdk/issues/212#issuecomment-420979840 +## https://openjdk.java.net/jeps/341 +ENV PATH="/opt/graalvm/bin:${PATH}" \ + JAVA_HOME=/opt/graalvm +RUN ln -s "${PWD}/ld.so.conf" /etc/ld.so.conf.d/graalvm.conf ; \ + ldconfig ; \ + java -Xshare:dump + +RUN find /tmp/ -mindepth 1 -ls -delete + +## deduplicate (!) +RUN apt-install.sh jdupes ; \ + apt-clean.sh ; \ + echo ; \ + du -xd1 "${PWD}/" | sort -Vk2 ; \ + echo ; \ + jdupes -1LSpr "${PWD}/" ; \ + echo ; \ + du -xd1 "${PWD}/" | sort -Vk2 ; \ + echo + +## --- + +FROM base AS jdk +SHELL [ "/bin/sh", "-ec" ] + +COPY /Dockerfile.jdk /usr/local/share/ + +ENV JAVA_HOME=/opt/graalvm + +COPY --from=jdk-fetch "${JAVA_HOME}/" "${JAVA_HOME}/" + +RUN ln -s "${JAVA_HOME}/ld.so.conf" /etc/ld.so.conf.d/graalvm.conf ; \ + ldconfig + +ENV PATH="${JAVA_HOME}/bin:${PATH}" \ + MALLOC_ARENA_MAX=4 + +## qa/smoke +RUN set -xv ; java -version ; \ + find /tmp/ -mindepth 1 -ls -delete diff --git a/Dockerfile.jre b/Dockerfile.jre new file mode 100644 index 0000000..d235ab7 --- /dev/null +++ b/Dockerfile.jre @@ -0,0 +1,78 @@ +ARG IMAGE_VERSION +ARG JAVA_VERSION_MAJOR +FROM docker.io/rockdrilla/graalvm-debian:base-${IMAGE_VERSION} AS base +FROM docker.io/rockdrilla/graalvm-debian:jdk-${JAVA_VERSION_MAJOR}-${IMAGE_VERSION} AS jdk + +## --- + +FROM jdk as jdk-to-jre +SHELL [ "/bin/sh", "-ec" ] + +RUN rm -rf /jre ; \ + jlink \ + --add-modules ALL-MODULE-PATH \ + --no-man-pages \ + --no-header-files \ + --compress=1 \ + --output /jre \ + ; \ + cd /jre ; \ + rm -rf \ + lib/security/cacerts \ + lib/security/krb5.conf \ + ; \ + cp -f "${JAVA_HOME}/lib/security/public_suffix_list.dat" lib/security/ ; \ + ln -sv /etc/ssl/certs/java/cacerts lib/security/ ; \ + ln -sv /etc/krb5.conf lib/security/ ; \ + chmod -R go-w /jre + +RUN rm -rf "${JAVA_HOME}" ; \ + mkdir -p "${JAVA_HOME}" ; \ + tar -C /jre -cf - . | tar -C "${JAVA_HOME}" -xf - ; \ + rm -rf /jre ; \ + find "${JAVA_HOME}/" -name '*.so' -exec dirname '{}' '+' \ + | sort -uV > ld.so.conf ; \ + chmod -R go-w "${JAVA_HOME}/" + +WORKDIR ${JAVA_HOME} + +## https://github.com/docker-library/openjdk/issues/212#issuecomment-420979840 +## https://openjdk.java.net/jeps/341 +RUN ldconfig ; \ + java -Xshare:dump + +RUN find /tmp/ -mindepth 1 -ls -delete + +## deduplicate (!) +RUN apt-install.sh jdupes ; \ + apt-clean.sh ; \ + echo ; \ + du -xd1 "${PWD}/" | sort -Vk2 ; \ + echo ; \ + jdupes -1LSpr "${PWD}/" ; \ + echo ; \ + du -xd1 "${PWD}/" | sort -Vk2 ; \ + echo + +## --- + +FROM base AS jre +SHELL [ "/bin/sh", "-ec" ] + +COPY /Dockerfile.jre /usr/local/share/ + +COPY /scripts/* /usr/local/sbin/ + +ENV JAVA_HOME=/opt/graalvm + +COPY --from=jdk-to-jre "${JAVA_HOME}/" "${JAVA_HOME}/" + +RUN ln -s "${JAVA_HOME}/ld.so.conf" /etc/ld.so.conf.d/graalvm.conf ; \ + ldconfig + +ENV PATH="${JAVA_HOME}/bin:${PATH}" \ + MALLOC_ARENA_MAX=4 + +## qa/smoke +RUN set -xv ; java -version ; \ + find /tmp/ -mindepth 1 -ls -delete diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..67db858 --- /dev/null +++ b/LICENSE @@ -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. diff --git a/apt/prefs.backports b/apt/prefs.backports new file mode 100644 index 0000000..8658903 --- /dev/null +++ b/apt/prefs.backports @@ -0,0 +1,4 @@ +## example: +# Package: src:curl +# Pin: release n=bookworm-backports +# Pin-Priority: 600 diff --git a/apt/sources.debian b/apt/sources.debian new file mode 100644 index 0000000..75c083a --- /dev/null +++ b/apt/sources.debian @@ -0,0 +1,11 @@ +Types: deb +URIs: http://deb.debian.org/debian +Suites: bookworm bookworm-updates bookworm-proposed-updates bookworm-backports +Components: main +Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg + +Types: deb +URIs: http://deb.debian.org/debian-security +Suites: bookworm-security +Components: main +Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg diff --git a/build-scripts/image-base.sh b/build-scripts/image-base.sh new file mode 100755 index 0000000..8e0080f --- /dev/null +++ b/build-scripts/image-base.sh @@ -0,0 +1,29 @@ +#!/bin/sh +set -ef +cd "$(dirname "$0")/.." + +IMAGE_VERSION="${IMAGE_VERSION:-bookworm-v0.0.1}" +BASETAG="${BASETAG:-bookworm-slim}" + +set -a +BUILDAH_FORMAT="${BUILDAH_FORMAT:-docker}" +BUILDAH_ISOLATION="${BUILDAH_ISOLATION:-chroot}" +BUILDAH_NETWORK="${BUILDAH_NETWORK:-host}" +set +a + +img="docker.io/rockdrilla/graalvm-debian:base-${IMAGE_VERSION}" + +buildah bud --network="${BUILDAH_NETWORK}" \ + -f ./Dockerfile.base \ + -t "${img}" \ + --pull=missing --no-cache --squash \ + --build-arg "BASETAG=${BASETAG}" \ + + +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}" diff --git a/build-scripts/image-jdk.sh b/build-scripts/image-jdk.sh new file mode 100755 index 0000000..f70a4f0 --- /dev/null +++ b/build-scripts/image-jdk.sh @@ -0,0 +1,51 @@ +#!/bin/sh +set -ef +cd "$(dirname "$0")/.." + +IMAGE_VERSION="${IMAGE_VERSION:-bookworm-v0.0.1}" +JAVA_VERSION_MAJOR="${JAVA_VERSION_MAJOR:-17}" + +set -a +BUILDAH_FORMAT="${BUILDAH_FORMAT:-docker}" +BUILDAH_ISOLATION="${BUILDAH_ISOLATION:-chroot}" +BUILDAH_NETWORK="${BUILDAH_NETWORK:-host}" +set +a + +img="docker.io/rockdrilla/graalvm-debian:jdk-${JAVA_VERSION_MAJOR}" +img_fq="${img}-${IMAGE_VERSION}" + +GRAALVM_BASE_URI="https://download.oracle.com/graalvm/${JAVA_VERSION_MAJOR}/latest" +GRAALVM_BASE_FILE="graalvm-jdk-${JAVA_VERSION_MAJOR}_linux-x64_bin.tar.gz" +GRAALVM_URI="${GRAALVM_BASE_URI}/${GRAALVM_BASE_FILE}" + +mkdir -p artifact-cache +[ -s "artifact-cache/${GRAALVM_BASE_FILE}" ] || { + curl -LR -o "artifact-cache/${GRAALVM_BASE_FILE}" "${GRAALVM_URI}" +} + +w=$(mktemp -d) ; : "${w:?}" + +tar -C "$w" --strip-components=1 -xf "artifact-cache/${GRAALVM_BASE_FILE}" +grep -E '^(GRAALVM_VERSION|JAVA_VERSION|JAVA_RUNTIME_VERSION|JAVA_VERSION_DATE)=' < "$w/release" > "$w/relenv" + +GRAALVM_VERSION=$( . "$w/relenv" ; echo "${GRAALVM_VERSION:?}") +JAVA_VERSION=$( . "$w/relenv" ; echo "${JAVA_VERSION:?}") +JAVA_RUNTIME_VERSION=$( . "$w/relenv" ; echo "${JAVA_RUNTIME_VERSION:?}") +JAVA_VERSION_DATE=$( . "$w/relenv" ; echo "${JAVA_VERSION_DATE:?}") + +rm -rf "$w" ; unset w + +buildah bud \ + -f ./Dockerfile.jdk \ + -t "${img_fq}" \ + --pull=missing --no-cache \ + --build-arg "IMAGE_VERSION=${IMAGE_VERSION}" \ + --build-arg "JAVA_VERSION_MAJOR=${JAVA_VERSION_MAJOR}" \ + --build-arg "GRAALVM_BASE_FILE=${GRAALVM_BASE_FILE}" \ + --env "GRAALVM_VERSION=${GRAALVM_VERSION}" \ + --env "JAVA_VERSION=${JAVA_VERSION}" \ + --env "JAVA_RUNTIME_VERSION=${JAVA_RUNTIME_VERSION}" \ + --env "JAVA_VERSION_DATE=${JAVA_VERSION_DATE}" \ + + +podman tag "${img_fq}" "${img}" diff --git a/build-scripts/image-jre.sh b/build-scripts/image-jre.sh new file mode 100755 index 0000000..e6f3c4d --- /dev/null +++ b/build-scripts/image-jre.sh @@ -0,0 +1,51 @@ +#!/bin/sh +set -ef +cd "$(dirname "$0")/.." + +IMAGE_VERSION="${IMAGE_VERSION:-bookworm-v0.0.1}" +JAVA_VERSION_MAJOR="${JAVA_VERSION_MAJOR:-17}" + +set -a +BUILDAH_FORMAT="${BUILDAH_FORMAT:-docker}" +BUILDAH_ISOLATION="${BUILDAH_ISOLATION:-chroot}" +BUILDAH_NETWORK="${BUILDAH_NETWORK:-host}" +set +a + +img="docker.io/rockdrilla/graalvm-debian:jre-${JAVA_VERSION_MAJOR}" +img_fq="${img}-${IMAGE_VERSION}" + +GRAALVM_BASE_URI="https://download.oracle.com/graalvm/${JAVA_VERSION_MAJOR}/latest" +GRAALVM_BASE_FILE="graalvm-jdk-${JAVA_VERSION_MAJOR}_linux-x64_bin.tar.gz" +GRAALVM_URI="${GRAALVM_BASE_URI}/${GRAALVM_BASE_FILE}" + +mkdir -p artifact-cache +[ -s "artifact-cache/${GRAALVM_BASE_FILE}" ] || { + echo 'build JDK first' >&2 + exit 1 +} + +w=$(mktemp -d) ; : "${w:?}" + +tar -C "$w" --strip-components=1 -xf "artifact-cache/${GRAALVM_BASE_FILE}" +grep -E '^(GRAALVM_VERSION|JAVA_VERSION|JAVA_RUNTIME_VERSION|JAVA_VERSION_DATE)=' < "$w/release" > "$w/relenv" + +GRAALVM_VERSION=$( . "$w/relenv" ; echo "${GRAALVM_VERSION:?}") +JAVA_VERSION=$( . "$w/relenv" ; echo "${JAVA_VERSION:?}") +JAVA_RUNTIME_VERSION=$( . "$w/relenv" ; echo "${JAVA_RUNTIME_VERSION:?}") +JAVA_VERSION_DATE=$( . "$w/relenv" ; echo "${JAVA_VERSION_DATE:?}") + +rm -rf "$w" ; unset w + +buildah bud \ + -f ./Dockerfile.jre \ + -t "${img_fq}" \ + --pull=missing --no-cache \ + --build-arg "IMAGE_VERSION=${IMAGE_VERSION}" \ + --build-arg "JAVA_VERSION_MAJOR=${JAVA_VERSION_MAJOR}" \ + --env "GRAALVM_VERSION=${GRAALVM_VERSION}" \ + --env "JAVA_VERSION=${JAVA_VERSION}" \ + --env "JAVA_RUNTIME_VERSION=${JAVA_RUNTIME_VERSION}" \ + --env "JAVA_VERSION_DATE=${JAVA_VERSION_DATE}" \ + + +podman tag "${img_fq}" "${img}" diff --git a/extra-scripts/certifi-extras.sh b/extra-scripts/certifi-extras.sh new file mode 100755 index 0000000..595f726 --- /dev/null +++ b/extra-scripts/certifi-extras.sh @@ -0,0 +1,43 @@ +#!/bin/sh +set -ef + +dst_dir=/usr/local/share/ca-certificates + +w=$(mktemp -d) ; : "${w:?}" +w_cleanup() { + [ -z "$w" ] || ls -lA "$w/" >&2 + [ -z "$w" ] || rm -rf "$w" + unset w + exit "${1:-0}" +} + +def_bundle='/etc/ssl/certs/ca-certificates.crt' + +openssl-cert-auto-pem.sh "${def_bundle}" "$w/cacert.pem" "$w/cacert.fp" +[ -s "$w/cacert.pem" ] || w_cleanup 1 +[ -s "$w/cacert.fp" ] || w_cleanup 1 + +openssl-cert-auto-pem.sh "$1" "$w/certifi.pem" "$w/certifi.fp" "$w/certifi.off" +[ -s "$w/certifi.pem" ] || w_cleanup 1 +[ -s "$w/certifi.fp" ] || w_cleanup 1 +[ -s "$w/certifi.off" ] || w_cleanup 1 + +set +e +grep -Fxnv -f "$w/cacert.fp" "$w/certifi.fp" | cut -d : -f 1 > "$w/diff.ln" +set -e + +if [ -s "$w/diff.ln" ] ; then + terse_fingerprint() { cut -d = -f 2- | tr -cd '[:alnum:]' ; } + + while read -r n ; do + [ -n "$n" ] || continue + + fp=$(sed -ne "${n}p" "$w/certifi.fp" | terse_fingerprint) + off=$(sed -ne "${n}p" "$w/certifi.off") + sed -ne "${off}p" "$w/certifi.pem" > "${dst_dir}/certifi-${fp}.crt" + done < "$w/diff.ln" +fi + +rm -rf "$w" ; unset w + +exec update-ca-certificates --fresh diff --git a/extra-scripts/divert-rm.sh b/extra-scripts/divert-rm.sh new file mode 100755 index 0000000..c5d8d46 --- /dev/null +++ b/extra-scripts/divert-rm.sh @@ -0,0 +1,7 @@ +#!/bin/sh +set -ef +: "${1:?}" +d=$(printf '%s' "/run/apt-removed/divert/$1" | tr -s '/') +mkdir -p "${d%/*}" +dpkg-divert --divert "$d" --rename "$1" 2>/dev/null +rm -f "$d" diff --git a/scripts/apt-clean.sh b/scripts/apt-clean.sh new file mode 100755 index 0000000..4365a7c --- /dev/null +++ b/scripts/apt-clean.sh @@ -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 </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 "$@" diff --git a/scripts/apt-remove.sh b/scripts/apt-remove.sh new file mode 100755 index 0000000..dc032b6 --- /dev/null +++ b/scripts/apt-remove.sh @@ -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 diff --git a/scripts/openssl-cert-auto-pem.sh b/scripts/openssl-cert-auto-pem.sh new file mode 100755 index 0000000..3487e88 --- /dev/null +++ b/scripts/openssl-cert-auto-pem.sh @@ -0,0 +1,95 @@ +#!/bin/sh +set -f + +[ $# -gt 0 ] || exit 0 +me=${0##*/} + +[ -n "$1" ] || exit 1 +[ -f "$1" ] || { + env printf '%s: not a file or does not exist: %q\n' "${me}" "$1" >&2 + exit 1 +} +[ -s "$1" ] || exit 0 + +w=$(mktemp -d) || exit 1 +w_cleanup() { + [ -z "$w" ] || ls -lA "$w/" >&2 + [ -z "$w" ] || rm -rf "$w" + unset w + exit "${1:-0}" +} + +bundle_offsets() { + awk ' + BEGIN { OFS = "," ; i_begin = 0 ; } + $0 == "-----BEGIN CERTIFICATE-----" { i_begin = NR ; } + $0 == "-----END CERTIFICATE-----" { if (i_begin > 0) { print i_begin,NR ; i_begin = 0 ; } } + ' "$1" +} + +bundle_fingerprints() { + local x f + while read -r x ; do + [ -n "$x" ] || continue + + f=$(sed -ne "${x}p" "$1" | openssl x509 -noout -fingerprint -sha256) + [ -n "$f" ] || f=$(sed -ne "${x}p" "$1" | openssl x509 -noout -fingerprint) + [ -n "$f" ] || continue + + printf '%s\n' "$f" | tr '[:upper:]' '[:lower:]' + done < "$2" +} + +openssl storeutl -certs "$1" > "$w/cert.pem" || w_cleanup 1 +[ -s "$w/cert.pem" ] || w_cleanup 1 +tr -s '\r\n' '\n' < "$w/cert.pem" > "$w/cert.txt" +[ -s "$w/cert.txt" ] || w_cleanup 1 +rm -f "$w/cert.pem" + +bundle_offsets "$w/cert.txt" > "$w/cert.off" +[ -s "$w/cert.off" ] || w_cleanup 1 + +bundle_fingerprints "$w/cert.txt" "$w/cert.off" > "$w/cert.fp.all" +[ -s "$w/cert.fp.all" ] || w_cleanup 1 + +sort -uV < "$w/cert.fp.all" > "$w/cert.fp" +while read -r fp ; do + [ -n "${fp}" ] || continue + + n=$(grep -m1 -Fxn -e "${fp}" "$w/cert.fp.all" | cut -d : -f 1) + [ -n "$n" ] || continue + + off=$(sed -ne "${n}p" "$w/cert.off") + [ -n "${off}" ] || continue + + sed -ne "${off}p" "$w/cert.txt" +done < "$w/cert.fp" > "$w/cert.pem" +[ -s "$w/cert.pem" ] || w_cleanup 1 +rm -f "$w/cert.txt" "$w/cert.off" "$w/cert.fp.all" + +if [ -n "$2" ] ; then + while : ; do + if [ -e "$2" ] ; then + [ -f "$2" ] || break + fi + cat > "$2" + break ; done +else + cat +fi < "$w/cert.pem" + +while [ -n "$3" ] ; do + if [ -e "$3" ] ; then + [ -f "$3" ] || break + fi + cat "$w/cert.fp" > "$3" +break ; done + +while [ -n "$4" ] ; do + if [ -e "$4" ] ; then + [ -f "$4" ] || break + fi + bundle_offsets "$w/cert.pem" > "$4" +break ; done + +rm -rf "$w" ; unset w