Skip to content

Commit baf1842

Browse files
committed
deblobbify, replacing the system folder with several other components
1 parent e3c861f commit baf1842

File tree

99 files changed

+812
-2460
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

99 files changed

+812
-2460
lines changed

.github/workflows/docker_build.yml

Lines changed: 71 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -13,39 +13,79 @@ env:
1313
CI: true
1414
DOCKER_BUILDKIT: 1
1515

16+
# The GitHub ARM runner is capable of running
17+
# $PREFIX/bin/apt-get upgrade from within the Dockerfile
18+
# natively during the update process for both aarch64
19+
# and arm, demonstrating that it is compatible with
20+
# 32-bit binaries and capable of completely
21+
# replacing QEMU, but using it in the same workflow
22+
# as the x86 runner appears to require two separate jobs.
1623
jobs:
17-
main:
18-
runs-on: ubuntu-latest
24+
ARM:
25+
runs-on: ubuntu-24.04-arm
1926
strategy:
2027
matrix:
21-
CPU_ARCH:
28+
ARCHITECTURE:
2229
- aarch64
2330
- arm
24-
- i686
25-
- x86_64
2631
steps:
2732

2833
- name: Clone repository
2934
uses: actions/checkout@v4
3035

31-
- name: Setup binfmt_misc
32-
if: (matrix.CPU_ARCH == 'aarch64') || (matrix.CPU_ARCH == 'arm')
33-
run: docker run --rm --privileged aptman/qus -s -- -p aarch64 arm
36+
- name: Set architecture variable
37+
run: echo "ARCHITECTURE=${{ matrix.ARCHITECTURE }}" >> $GITHUB_ENV
38+
39+
- name: Build image
40+
run: ./generate.sh
41+
42+
- name: Login to Docker Hub
43+
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'termux/termux-docker'
44+
uses: docker/login-action@v3
45+
with:
46+
username: grimler
47+
password: ${{ secrets.GRIMLER_DOCKER_TOKEN }}
48+
49+
- name: Push to Docker Hub
50+
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'termux/termux-docker'
51+
run: docker push termux/termux-docker:${{ env.ARCHITECTURE }}
3452

35-
- name: Build images
53+
- name: Export container as tar archive
54+
if: always()
3655
run: |
37-
case '${{ matrix.CPU_ARCH }}' in
38-
arm) SYSTEM_TYPE=arm; PLATFORM_TAG="linux/arm/v7";;
39-
aarch64) SYSTEM_TYPE=arm; PLATFORM_TAG="linux/arm64";;
40-
i686) SYSTEM_TYPE=x86; PLATFORM_TAG="linux/386";;
41-
*) SYSTEM_TYPE=x86; PLATFORM_TAG="linux/amd64";;
42-
esac
43-
docker buildx build -t \
44-
termux/termux-docker:${{ matrix.CPU_ARCH }} \
45-
--platform "$PLATFORM_TAG" \
46-
--build-arg BOOTSTRAP_ARCH=${{ matrix.CPU_ARCH }} \
47-
--build-arg SYSTEM_TYPE="${SYSTEM_TYPE}" \
48-
.
56+
docker run \
57+
--name termux-docker-${{ env.ARCHITECTURE }} \
58+
termux/termux-docker:${{ env.ARCHITECTURE }} \
59+
uname -a
60+
docker stop termux-docker-${{ env.ARCHITECTURE }}
61+
docker export -o termux-docker-${{ env.ARCHITECTURE }}.tar \
62+
termux-docker-${{ env.ARCHITECTURE }}
63+
sha256sum termux-docker-${{ env.ARCHITECTURE }}.tar
64+
65+
- name: Store tar archive
66+
if: always()
67+
uses: actions/upload-artifact@v4
68+
with:
69+
name: termux-docker-${{ env.ARCHITECTURE }}-${{ github.sha }}
70+
path: termux-docker-${{ env.ARCHITECTURE }}.tar
71+
72+
x86:
73+
runs-on: ubuntu-latest
74+
strategy:
75+
matrix:
76+
ARCHITECTURE:
77+
- x86_64
78+
- i686
79+
steps:
80+
81+
- name: Clone repository
82+
uses: actions/checkout@v4
83+
84+
- name: Set architecture variable
85+
run: echo "ARCHITECTURE=${{ matrix.ARCHITECTURE }}" >> $GITHUB_ENV
86+
87+
- name: Build image
88+
run: ./generate.sh
4989

5090
- name: Login to Docker Hub
5191
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'termux/termux-docker'
@@ -57,28 +97,26 @@ jobs:
5797
- name: Push to Docker Hub
5898
if: github.ref == 'refs/heads/master' && github.event_name != 'pull_request' && github.repository == 'termux/termux-docker'
5999
run: |
60-
docker push termux/termux-docker:${{ matrix.CPU_ARCH }}
61-
if [ ${{ matrix.CPU_ARCH }} = i686 ]; then
62-
docker tag termux/termux-docker:i686 termux/termux-docker:latest
100+
docker push termux/termux-docker:${{ env.ARCHITECTURE }}
101+
if [ ${{ env.ARCHITECTURE }} = i686 ]; then
63102
docker push termux/termux-docker:latest
64103
fi
65104
66105
- name: Export container as tar archive
67106
if: always()
68107
run: |
69108
docker run \
70-
--privileged \
71-
--name termux-docker-${{ matrix.CPU_ARCH }} \
72-
termux/termux-docker:${{ matrix.CPU_ARCH }} \
109+
--name termux-docker-${{ env.ARCHITECTURE }} \
110+
termux/termux-docker:${{ env.ARCHITECTURE }} \
73111
uname -a
74-
docker stop termux-docker-${{ matrix.CPU_ARCH }}
75-
docker export -o termux-docker-${{ matrix.CPU_ARCH }}.tar \
76-
termux-docker-${{ matrix.CPU_ARCH }}
77-
sha256sum termux-docker-${{ matrix.CPU_ARCH }}.tar
112+
docker stop termux-docker-${{ env.ARCHITECTURE }}
113+
docker export -o termux-docker-${{ env.ARCHITECTURE }}.tar \
114+
termux-docker-${{ env.ARCHITECTURE }}
115+
sha256sum termux-docker-${{ env.ARCHITECTURE }}.tar
78116
79117
- name: Store tar archive
80118
if: always()
81119
uses: actions/upload-artifact@v4
82120
with:
83-
name: termux-docker-${{ matrix.CPU_ARCH }}-${{ github.sha }}
84-
path: termux-docker-${{ matrix.CPU_ARCH }}.tar
121+
name: termux-docker-${{ env.ARCHITECTURE }}-${{ github.sha }}
122+
path: termux-docker-${{ env.ARCHITECTURE }}.tar

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
termux-docker-rootfs

Dockerfile

Lines changed: 47 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,91 +1,50 @@
1-
##############################################################################
2-
# Bootstrap Termux environment.
3-
FROM scratch AS bootstrap
4-
5-
ARG BOOTSTRAP_VERSION=2023.02.19-r1%2Bapt-android-7
6-
ARG BOOTSTRAP_ARCH=i686
7-
ARG SYSTEM_TYPE=x86
8-
9-
# Docker uses /bin/sh by default, but we don't have it currently.
10-
SHELL ["/system/bin/sh", "-c"]
11-
ENV PATH /system/bin
12-
13-
# Copy libc, linker and few utilities.
14-
COPY /system/$SYSTEM_TYPE /system
15-
16-
# Copy entrypoint script.
17-
COPY /entrypoint.sh /entrypoint.sh
18-
COPY /entrypoint_root.sh /entrypoint_root.sh
19-
20-
# Extract bootstrap archive and create symlinks.
21-
ADD https://github.com/termux/termux-packages/releases/download/bootstrap-$BOOTSTRAP_VERSION/bootstrap-$BOOTSTRAP_ARCH.zip /bootstrap.zip
22-
RUN busybox mkdir -p /data/data/com.termux/files && \
23-
cd /data/data/com.termux/files && \
24-
busybox mkdir ../cache ./usr ./home && \
25-
busybox unzip -d usr /bootstrap.zip && \
26-
busybox rm /bootstrap.zip && \
27-
cd ./usr && \
28-
busybox cat SYMLINKS.txt | while read -r line; do \
29-
dest=$(echo "$line" | busybox awk -F '←' '{ print $1 }'); \
30-
link=$(echo "$line" | busybox awk -F '←' '{ print $2 }'); \
31-
busybox ln -s "$dest" "$link"; \
32-
done && \
33-
busybox rm SYMLINKS.txt && \
34-
busybox ln -s /data/data/com.termux/files/usr /usr && \
35-
busybox ln -s /data/data/com.termux/files/usr/bin /bin && \
36-
busybox ln -s /data/data/com.termux/files/usr/tmp /tmp
37-
38-
# Link some utilities to busybox.
39-
# Some utilities in $PREFIX are actually a wrapper of the same binary
40-
# from /system/bin. See termux-tools/build.sh#L29.
41-
RUN for tool in df mount ping ping6 su top umount; do \
42-
busybox ln -s /system/bin/busybox /system/bin/$tool; \
43-
done
44-
45-
# Set ownership and file access modes:
46-
# * User content is owned by 1000:1000.
47-
# * Termux file modes are set only for user.
48-
# * Rest is owned by root and has 755/644 modes.
49-
RUN busybox chown -Rh 0:0 /system && \
50-
busybox chown -Rh 1000:1000 /data/data/com.termux && \
51-
busybox ln -s /system/etc/passwd /etc/passwd && \
52-
busybox ln -s /system/etc/group /etc/group && \
53-
busybox find /system -type d -exec busybox chmod 755 "{}" \; && \
54-
busybox find /system -type f -executable -exec busybox chmod 755 "{}" \; && \
55-
busybox find /system -type f ! -executable -exec busybox chmod 644 "{}" \; && \
56-
busybox find /data -type d -exec busybox chmod 755 "{}" \; && \
57-
busybox find /data/data/com.termux/files -type f -o -type d -exec busybox chmod g-rwx,o-rwx "{}" \; && \
58-
cd /data/data/com.termux/files/usr && \
59-
busybox find ./bin ./lib/apt ./libexec -type f -exec busybox chmod 700 "{}" \;
60-
61-
# Install updates and cleanup when not building for arm.
62-
ENV PATH /data/data/com.termux/files/usr/bin
63-
RUN if [ ${SYSTEM_TYPE} = 'arm' ]; then exit; else \
64-
/system/bin/mksh -T /dev/ptmx -c "/system/bin/dnsmasq -u root -g root --pid-file /dnsmasq.pid" && sleep 1 && \
65-
su - system -c "/data/data/com.termux/files/usr/bin/apt update" && \
66-
su - system -c "/data/data/com.termux/files/usr/bin/apt upgrade -o Dpkg::Options::=--force-confnew -yq" && \
67-
rm -rf /data/data/com.termux/files/usr/var/lib/apt/* && \
68-
rm -rf /data/data/com.termux/files/usr/var/log/apt/* && \
69-
rm -rf /data/data/com.termux/cache/apt/* ;\
70-
fi
71-
72-
##############################################################################
73-
# Create final image.
741
FROM scratch
752

76-
ENV ANDROID_DATA /data
77-
ENV ANDROID_ROOT /system
78-
ENV HOME /data/data/com.termux/files/home
79-
ENV LANG en_US.UTF-8
80-
ENV PATH /data/data/com.termux/files/usr/bin
81-
ENV PREFIX /data/data/com.termux/files/usr
82-
ENV TMPDIR /data/data/com.termux/files/usr/tmp
83-
ENV TZ UTC
84-
85-
COPY --from=bootstrap / /
86-
87-
WORKDIR /data/data/com.termux/files/home
88-
SHELL ["/data/data/com.termux/files/usr/bin/sh", "-c"]
89-
3+
ARG ROOTFS
4+
ARG TERMUX_APP_PACKAGE
5+
ARG TERMUX_BASE_DIR
6+
ARG TERMUX_PREFIX
7+
8+
# Install generated rootfs containing bionic libc,
9+
# toybox, mksh, iputils, dnsmasq, and termux bootstrap
10+
COPY --chown=1000:1000 ${ROOTFS} /
11+
12+
# Docker uses /bin/sh by default, but we don't have it.
13+
# This ENV PATH line selects /system/bin/sh.
14+
# The final ENV PATH line later below then selects
15+
# $TERMUX_PREFIX/bin/sh -> bash without having
16+
# to add an additional SHELL line.
17+
ENV PATH=/system/bin
18+
SHELL ["sh", "-c"]
19+
20+
# Install updates and cleanup
21+
# Start dnsmasq to resolve hostnames, and,
22+
# for some reason the -c argument of toybox-su is not working,
23+
# so this odd-looking script forces the update process
24+
# to work using the -s argument of toybox-su instead, which is working.
25+
RUN sh -T /dev/ptmx -c "$TERMUX_PREFIX/bin/dnsmasq -u root -g root --pid-file=/dnsmasq.pid" && \
26+
sleep 1 && \
27+
echo '#!/system/bin/sh' > /update.sh && \
28+
echo "PATH=$TERMUX_PREFIX/bin" >> /update.sh && \
29+
echo 'pkg update' >> /update.sh && \
30+
echo 'apt-get upgrade -o Dpkg::Options::=--force-confnew -y' >> /update.sh && \
31+
chmod +x /update.sh && \
32+
su system -s /update.sh && \
33+
rm -f /update.sh && \
34+
rm -rf ${TERMUX_PREFIX}/var/lib/apt/* && \
35+
rm -rf ${TERMUX_PREFIX}/var/log/apt/* && \
36+
rm -rf /data/data/${TERMUX_APP_PACKAGE}/cache/apt/*
37+
38+
ENV ANDROID_DATA=/data
39+
ENV ANDROID_ROOT=/system
40+
ENV HOME=${TERMUX_BASE_DIR}/home
41+
ENV LANG=en_US.UTF-8
42+
ENV PATH=${TERMUX_PREFIX}/bin
43+
ENV PREFIX=${TERMUX_PREFIX}
44+
ENV TMPDIR=${TERMUX_PREFIX}/tmp
45+
ENV TZ=UTC
46+
ENV TERM=xterm
47+
48+
WORKDIR ${TERMUX_BASE_DIR}/home
9049
ENTRYPOINT ["/entrypoint.sh"]
91-
CMD ["/data/data/com.termux/files/usr/bin/login"]
50+
CMD ["login"]

README.md

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,12 @@ command:
4949
docker run --rm --privileged aptman/qus -s -- -p aarch64 arm
5050
```
5151

52-
Note that AArch64 and ARM containers work properly only in privileged
52+
Note that AArch64 and ARM containers sometimes work properly only in privileged
5353
mode. If you want your containers to have standard privileges, a custom
54-
seccomp profile is required.
54+
seccomp profile or a custom build of Docker might be required. The custom build
55+
of Docker limits the customizations to purely what is necessary for
56+
the `personality()` system call, leaving the security settings of all other system
57+
calls untouched.
5558

5659
Variant with privileged container:
5760

@@ -65,6 +68,23 @@ Variant with seccomp unconfined profile:
6568
docker run -it --security-opt seccomp:unconfined termux/termux-docker:aarch64
6669
```
6770

71+
Variant with custom build of Docker:
72+
73+
> [!NOTE]
74+
> Example with Debian bookworm `armhf` host and the `docker.io` package. Assumes that [`deb-src` URIs](https://wiki.debian.org/Packaging/SourcePackage?action=show&redirect=SourcePackage#With_apt-get_source) and the [`devscripts` package](https://wiki.debian.org/Packaging#Suggested_tools_to_create_an_environment_for_packaging) are already installed, and that the current user is a member of the `docker` group.
75+
76+
```.sh
77+
sudo apt build-dep docker.io
78+
apt source docker.io
79+
cp /path/to/termux-docker/custom-docker-with-unrestricted-personality.patch docker.io-*/debian/patches/
80+
echo 'custom-docker-with-unrestricted-personality.patch' >> docker.io-*/debian/patches/series
81+
cd docker.io-*/
82+
DEB_BUILD_OPTIONS=nocheck debuild -b -uc -us
83+
rm ../golang*
84+
sudo apt install ../*.deb
85+
docker run -it termux/termux-docker:arm
86+
```
87+
6888
### Non-interactive execution of commands
6989

7090
You can run commands in non-interactive mode. Just append them to Docker
@@ -99,20 +119,20 @@ docker run -it --entrypoint /entrypoint_root.sh termux/termux-docker:latest
99119
Docker:
100120

101121
```.sh
102-
./build-all.sh
122+
./generate.sh
103123
```
104124

105125
Podman:
106126

107127
```.sh
108-
./build-all.sh --podman
128+
./generate.sh --podman
109129
```
110130

111131
## Known issues
112132

113133
There a number of known issues which may not be resolved:
114134

115-
* ARM containers may require a custom seccomp profile to remove restrictions from
135+
* ARM containers might require a custom seccomp profile or custom build of Docker to remove restrictions from the
116136
`personality()` system call.
117137

118138
* When running certain multi threaded program in 32bit containers, the PIDs can

build-all.sh

Lines changed: 0 additions & 46 deletions
This file was deleted.

0 commit comments

Comments
 (0)