forked from Goldzxcbug/Droidspaces-rootfs-Desktop-builder
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathArch.Dockerfile
More file actions
391 lines (354 loc) · 16.3 KB
/
Copy pathArch.Dockerfile
File metadata and controls
391 lines (354 loc) · 16.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
FROM ogarcia/archlinux AS customizer
#######################################################
ARG DESKTOP
ARG DESKTOP_AUTOSTART
ARG PulseAudio
ARG ENABLE_zh_tz_ARG
ARG ENABLE_binfmt_ARG
ARG ENABLE_yj_ARG
ARG ENABLE_mesa_ARG
ARG DISPLAY_BACKEND
ARG ENABLE_8gen2_wayland_ARG
ARG ENABLE_kfgj_ARG
ARG ENABLE_zip_ARG
ARG ENABLE_docker_ARG
ARG ENABLE_srf_ARG
ARG ENABLE_tmoe_ARG
ARG ENABLE_systemd257_ARG
ARG USERNAME
ARG ANLAND_RELEASE_REPOSITORY=Goldzxcbug/droidspaces-package
ARG ANLAND_PACKAGE_REVISION=unknown
######################################################
COPY scripts/install-usb-manager.sh /usr/local/sbin/install-droidspaces-usb-manager
COPY scripts/systemd257.sh /usr/local/sbin/systemd257
COPY scripts/install-anland-kde.sh /usr/local/sbin/install-anland-kde
COPY scripts/install-mesa.sh /usr/local/sbin/install-mesa
COPY scripts/install-desktop.sh /usr/local/sbin/install-desktop
COPY scripts/configure-desktop.sh /usr/local/sbin/configure-desktop
COPY scripts/start-desktop-session.sh /usr/local/bin/start-desktop-session
COPY scripts/desktops/ /usr/local/lib/droidspaces/desktops/
RUN chmod +x /usr/local/sbin/install-anland-* /usr/local/sbin/install-mesa /usr/local/sbin/install-desktop /usr/local/sbin/configure-desktop /usr/local/bin/start-desktop-session /usr/local/lib/droidspaces/desktops/*.sh && \
sed -i '/^#ParallelDownloads/s/^#//' /etc/pacman.conf && \
sed -i '/NoExtract.*locale/d' /etc/pacman.conf && \
sed -i '/NoExtract.*i18n/d' /etc/pacman.conf && \
pacman -Sy --noconfirm archlinux-keyring glibc && \
pacman -Su --noconfirm && \
pacman -S --noconfirm --needed \
# 核心工具组件
bash jq dialog coreutils file findutils grep sed gawk curl wget ca-certificates bash-completion dbus systemd pam fastfetch logrotate \
# 用户请求的基础开发/编辑工具
git nano sudo \
# 网络与 SSH 工具
openssh net-tools iptables iputils iproute2 bind \
# 用于系统监控的 procps 进程工具
procps-ng \
# 核心内核模块支持
kmod tzdata tar && \
/usr/local/sbin/install-desktop "$DESKTOP" && \
#输入法 fcitx5 (可选)
if [ "$ENABLE_srf_ARG" = "true" ]; then \
pacman -S --noconfirm --needed fcitx5-im; \
fi && \
if [ "$ENABLE_srf_ARG" = "true" ] && [ "$ENABLE_zh_tz_ARG" = "true" ]; then \
pacman -S --noconfirm --needed fcitx5-chinese-addons; \
fi && \
## 开发工具集成 (可选)
if [ "$ENABLE_kfgj_ARG" = "true" ]; then \
pacman -S --noconfirm --needed \
base-devel cmake clang llvm python python-pip; \
fi && \
## 压缩工具扩展 (可选)
if [ "$ENABLE_zip_ARG" = "true" ]; then \
pacman -S --noconfirm --needed \
zip unzip p7zip bzip2 xz tar gzip; \
fi && \
## docker (可选)
if [ "$ENABLE_docker_ARG" = "true" ]; then \
pacman -S --noconfirm --needed \
docker docker-compose; \
fi && \
## 集成tmoe (可选)
if [ "$ENABLE_tmoe_ARG" = "true" ]; then \
git clone --depth=1 https://github.com/2moe/tmoe-linux.git /usr/local/etc/tmoe-linux/git && \
ln -sf /usr/local/etc/tmoe-linux/git/debian.sh /usr/local/bin/tmoe && \
chmod -R 755 /usr/local/etc/tmoe-linux; \
fi
# 启用 Anland 时从固定滚动 GitHub Release 安装对应桌面的 ARM64 包。
RUN if [ "$DISPLAY_BACKEND" = "anland-wayland" ]; then \
echo "--> [enabled] Installing Anland $DESKTOP packages (${ANLAND_PACKAGE_REVISION})..." && \
ANLAND_RELEASE_REPOSITORY="$ANLAND_RELEASE_REPOSITORY" \
/usr/local/sbin/install-anland-kde --1 && \
echo "--> [enabled] Anland $DESKTOP support installed"; \
fi
# 配置 Locale 与 SSH
RUN echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && \
if [ "$ENABLE_zh_tz_ARG" = "true" ]; then \
ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
echo "zh_CN.UTF-8 UTF-8" >> /etc/locale.gen && \
locale-gen && \
echo "LANG=zh_CN.UTF-8" > /etc/locale.conf && \
echo "LC_ALL=zh_CN.UTF-8" >> /etc/locale.conf; \
else \
locale-gen && \
echo "LANG=en_US.UTF-8" > /etc/locale.conf && \
echo "LC_ALL=en_US.UTF-8" >> /etc/locale.conf; \
fi && \
# 配置 SSH 服务(禁用 root 密码登录,但允许常规密码认证)
mkdir -p /var/run/sshd && \
ssh-keygen -A && \
sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin no/' /etc/ssh/sshd_config && \
sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/' /etc/ssh/sshd_config && \
# 如果容器内存在默认的 alarm 或 arch 用户,则清理
(userdel -r alarm 2>/dev/null || true) && \
useradd -m -s /bin/bash ${USERNAME} && echo "${USERNAME}:1234" | chpasswd && \
systemctl enable sshd
# 为所有 Arch RootFS 安装 Droidspaces USB Manager
RUN /usr/local/sbin/install-droidspaces-usb-manager --user "${USERNAME}"
# 为 droidspaces 的 su/su -l 入口建立完整的 systemd 用户会话。
RUN for pam_file in /etc/pam.d/su /etc/pam.d/su-l; do \
if ! grep -qE '^[[:space:]-]*session[[:space:]].*pam_systemd\.so' "$pam_file"; then \
sed -i '/^[[:space:]]*session[[:space:]].*pam_unix\.so/a\session optional pam_systemd.so' "$pam_file"; \
fi; \
done && \
grep -qE '^[[:space:]]*session[[:space:]].*pam_env\.so' /etc/pam.d/su-l || \
echo 'session required pam_env.so' >> /etc/pam.d/su-l
# 初始化环境变量文件;桌面专属变量由对应 profile 管理。
RUN : > /etc/environment
# 音频选择
RUN if [ "$PulseAudio" = "socket" ]; then \
echo "PULSE_SERVER=unix:/tmp/.pulse-socket" >> /etc/environment; \
elif [ "$PulseAudio" = "tcp" ]; then \
echo "PULSE_SERVER=tcp:127.0.0.1:4713" >> /etc/environment; \
fi
RUN if [ "$ENABLE_mesa_ARG" = "true" ] && [ "$DISPLAY_BACKEND" = "anland-wayland" ]; then \
echo 'MESA_LOADER_DRIVER_OVERRIDE=kgsl' >> /etc/environment; \
echo 'GALLIUM_DRIVER=kgsl' >> /etc/environment; \
echo 'FD_FORCE_KGSL=1' >> /etc/environment; \
fi
RUN if [ "$ENABLE_8gen2_wayland_ARG" = "true" ]; then \
echo 'FD_DEV_FEATURES=enable_tp_ubwc_flag_hint=1' >> /etc/environment; \
fi
# 输入法与桌面会话配置
COPY scripts/start/ /tmp/droidspaces-start/
RUN <<'EOF_RUN'
if [ "$ENABLE_srf_ARG" = "true" ]; then
mkdir -p /home/${USERNAME}/.config/autostart
cat <<'EOF' > /home/${USERNAME}/.config/autostart/fcitx5.desktop
[Desktop Entry]
Name=Fcitx5
GenericName=Input Method
Comment=Start Input Method
Exec=fcitx5 -d
Icon=fcitx
Terminal=false
Type=Application
Categories=System;Utility;
StartupNotify=false
NoDisplay=true
EOF
cat <<'EOF' >> /etc/environment
XMODIFIERS=@im=fcitx5
GTK_IM_MODULE=fcitx5
QT_IM_MODULE=fcitx5
SDL_IM_MODULE=fcitx5
GLFW_IM_MODULE=fcitx
EOF
fi
if [ "$ENABLE_mesa_ARG" = "true" ] && [ "$DISPLAY_BACKEND" != "anland-wayland" ] ; then
cat <<'EOF' >> /etc/environment
MESA_LOADER_DRIVER_OVERRIDE=kgsl
TU_DEBUG=noconform
EOF
fi
echo 'export XDG_RUNTIME_DIR=/run/user/$(id -u)' >> /home/${USERNAME}/.bashrc
/usr/local/sbin/configure-desktop "$DESKTOP" "$DISPLAY_BACKEND" "$DESKTOP_AUTOSTART" "$USERNAME"
rm -rf /tmp/droidspaces-start
EOF_RUN
# 下载并安装 Mesa
RUN if [ "$ENABLE_mesa_ARG" = "true" ]; then \
/usr/local/sbin/install-mesa --1; \
else \
echo "--> [跳过] 未开启 Mesa 驱动安装"; \
fi
# 通过 AUR 安装原生 ARM64 Google Chrome,替换 Chromium。
RUN if [ "$DESKTOP" != "none" ]; then \
: > /tmp/chrome-build-packages && \
for package in $(pacman -Sgq base-devel); do \
if ! pacman -Qq "$package" >/dev/null 2>&1; then \
printf '%s\n' "$package" >> /tmp/chrome-build-packages; \
fi; \
done && \
pacman -S --noconfirm --needed base-devel git && \
useradd --system --create-home --home-dir /tmp/chrome-build --shell /bin/bash chrome-build && \
runuser -u chrome-build -- git clone --depth=1 https://aur.archlinux.org/google-chrome.git /tmp/chrome-build/google-chrome && \
grep -Eq '^[[:space:]]*arch = aarch64$' /tmp/chrome-build/google-chrome/.SRCINFO && \
grep -Eq '^[[:space:]]*source_aarch64 = https://dl\.google\.com/linux/chrome/deb/.+_arm64\.deb$' /tmp/chrome-build/google-chrome/.SRCINFO && \
grep -Eq '^[[:space:]]*sha512sums_aarch64 = [0-9a-fA-F]{128}$' /tmp/chrome-build/google-chrome/.SRCINFO && \
CHROME_DEPENDENCIES="$(sed -n 's/^[[:space:]]*depends = //p' /tmp/chrome-build/google-chrome/.SRCINFO | sed 's/[<>=].*$//' | sort -u)" && \
[ -n "$CHROME_DEPENDENCIES" ] && \
if printf '%s\n' "$CHROME_DEPENDENCIES" | grep -Eqv '^[A-Za-z0-9@._+][A-Za-z0-9@._+:-]*$'; then \
echo "AUR 配方包含无效的 Chrome 依赖" >&2; \
exit 1; \
fi && \
pacman -S --noconfirm --needed --asdeps $CHROME_DEPENDENCIES && \
runuser -u chrome-build -- bash -c 'cd "$1" && makepkg --cleanbuild --clean --noconfirm' _ /tmp/chrome-build/google-chrome && \
CHROME_PACKAGE="$(find /tmp/chrome-build/google-chrome -maxdepth 1 -type f -name 'google-chrome-*.pkg.tar.*' ! -name '*.sig' -print -quit)" && \
[ -n "$CHROME_PACKAGE" ] && \
[ "$(find /tmp/chrome-build/google-chrome -maxdepth 1 -type f -name 'google-chrome-*.pkg.tar.*' ! -name '*.sig' -print | wc -l)" -eq 1 ] && \
sed -e '/^[[:space:]]*LocalFileSigLevel[[:space:]]*=/d' \
-e '/^\[options\][[:space:]]*$/a LocalFileSigLevel = Optional' \
/etc/pacman.conf > /tmp/pacman-chrome.conf && \
[ "$(pacman --config /tmp/pacman-chrome.conf -Qqp "$CHROME_PACKAGE")" = "google-chrome" ] && \
LC_ALL=C pacman --config /tmp/pacman-chrome.conf -Qip "$CHROME_PACKAGE" | grep -Eq '^Architecture[[:space:]]*: aarch64$' && \
pacman --config /tmp/pacman-chrome.conf -U --noconfirm "$CHROME_PACKAGE" && \
userdel -r chrome-build && \
if [ -s /tmp/chrome-build-packages ]; then \
pacman -Rns --noconfirm $(cat /tmp/chrome-build-packages); \
fi && \
rm -f /tmp/chrome-build-packages /tmp/pacman-chrome.conf; \
else \
echo "--> [跳过] 命令行 RootFS 不安装 Google Chrome"; \
fi
# 修复容器内的 DHCP 网络服务配置
RUN mkdir -p /etc/systemd/network && \
cat <<'EOF' > /etc/systemd/network/10-eth-dhcp.network
[Match]
Name=eth*
[Network]
DHCP=yes
IPv6AcceptRA=yes
[DHCPv4]
UseDNS=yes
UseDomains=yes
RouteMetric=100
EOF
# 应用 Android 运行环境兼容性修复(重点针对 Systemd 和 Udev)
RUN <<'EOF_RUN'
# --- 1. 常规兼容性修复 ---
# 建立 Android 网络权限组
grep -q '^aid_inet:' /etc/group || echo 'aid_inet:x:3003:' >> /etc/group
grep -q '^aid_net_raw:' /etc/group || echo 'aid_net_raw:x:3004:' >> /etc/group
grep -q '^aid_net_admin:' /etc/group || echo 'aid_net_admin:x:3005:' >> /etc/group
# 检查并创建 droidspaces-gpu 组
getent group droidspaces-gpu >/dev/null || groupadd -g 786 -r droidspaces-gpu
# 为 root 用户赋予访问 Android 硬件及网络的权限组
usermod -a -G aid_inet,aid_net_raw,input,video,tty,droidspaces-gpu root || true
usermod -a -G aid_inet,aid_net_raw,input,video,tty,wheel,droidspaces-gpu ${USERNAME} || true
# 确保 Arch 赋予 sudo 权限给 wheel 组
sed -i 's/^# %wheel ALL=(ALL:ALL) ALL/%wheel ALL=(ALL:ALL) ALL/' /etc/sudoers
# --- 2. 针对 Systemd 的特定修复 ---
ln -sf /dev/null /etc/systemd/system/systemd-networkd-wait-online.service
ln -sf /dev/null /etc/systemd/system/systemd-journald-audit.socket
# 优化 Journald 日志配置
cat >> /etc/systemd/journald.conf << 'EOT'
[Journal]
ReadKMsg=no
Audit=no
Storage=volatile
EOT
mkdir -p /etc/systemd/journald.conf.d
cat > /etc/systemd/journald.conf.d/ds-logging.conf << 'EOT'
[Journal]
SystemMaxUse=200M
RuntimeMaxUse=200M
MaxRetentionSec=7day
MaxLevelStore=info
EOT
mkdir -p /etc/systemd/system/multi-user.target.wants
GUEST_SYSTEMD_PATH="/usr/lib/systemd/system"
if [ -f "$GUEST_SYSTEMD_PATH/dbus.service" ]; then
ln -sf "$GUEST_SYSTEMD_PATH/dbus.service" "/etc/systemd/system/multi-user.target.wants/dbus.service"
fi
if [ "$ENABLE_yj_ARG" = "true" ]; then
for service in systemd-udevd.service systemd-resolved.service systemd-networkd.service NetworkManager.service; do
if [ -f "$GUEST_SYSTEMD_PATH/$service" ]; then
ln -sf "$GUEST_SYSTEMD_PATH/$service" "/etc/systemd/system/multi-user.target.wants/$service"
fi
done
else
for service in systemd-udevd.service systemd-resolved.service systemd-networkd.service NetworkManager.service; do
ln -sf /dev/null "/etc/systemd/system/$service"
done
fi
# 在 systemd-logind 中禁用电源键行为处理
mkdir -p /etc/systemd/logind.conf.d
cat > /etc/systemd/logind.conf.d/99-power-key.conf << 'EOF'
[Login]
HandlePowerKey=ignore
HandleSuspendKey=ignore
HandleHibernateKey=ignore
HandlePowerKeyLongPress=ignore
HandlePowerKeyLongPressHibernate=ignore
EOF
# 应用 udev 覆盖配置
mkdir -p /etc/systemd/system/systemd-udev-trigger.service.d
cat > /etc/systemd/system/systemd-udev-trigger.service.d/override.conf << 'EOF'
[Service]
ExecStart=
ExecStart=-/usr/bin/udevadm trigger --subsystem-match=usb --subsystem-match=block --subsystem-match=input --subsystem-match=tty --subsystem-match=net
EOF
# 针对只读文件系统路径覆盖
for unit in systemd-udevd.service systemd-udev-trigger.service systemd-udev-settle.service systemd-udevd-kernel.socket systemd-udevd-control.socket; do
mkdir -p "/etc/systemd/system/${unit}.d"
printf "[Unit]\nConditionPathIsReadWrite=\n" > "/etc/systemd/system/${unit}.d/99-readonly-fix.conf"
done
# 限制特定的网络服务
for unit in NetworkManager.service dhcpcd.service systemd-resolved.service systemd-networkd.service; do
if [ -f "$GUEST_SYSTEMD_PATH/$unit" ] || [ -f "/etc/systemd/system/multi-user.target.wants/$unit" ]; then
mkdir -p "/etc/systemd/system/${unit}.d"
cat > "/etc/systemd/system/${unit}.d/99-netmode-limit.conf" << 'EOF'
[Service]
ExecCondition=
ExecCondition=/bin/sh -c "grep -qE 'net_mode=(nat|gateway)' /run/droidspaces/container.config"
EOF
fi
done
# 仅在启用硬件访问时限制 udev 服务启动
for unit in systemd-udevd.service systemd-udev-trigger.service systemd-udev-settle.service; do
if [ -f "$GUEST_SYSTEMD_PATH/$unit" ] || [ -f "/etc/systemd/system/multi-user.target.wants/$unit" ]; then
mkdir -p "/etc/systemd/system/${unit}.d"
cat > "/etc/systemd/system/${unit}.d/99-hwaccess-limit.conf" << 'EOF'
[Service]
ExecCondition=
ExecCondition=/bin/sh -c "grep -q 'enable_hw_access=1' /run/droidspaces/container.config"
EOF
fi
done
# 针对 Android 环境微调日志轮转
if [ -f /etc/logrotate.conf ]; then
sed -i 's/^#maxsize.*/maxsize 50M/' /etc/logrotate.conf
if ! grep -q "maxsize 50M" /etc/logrotate.conf; then
echo "maxsize 50M" >> /etc/logrotate.conf
fi
fi
echo "Post-extraction fixes applied on $(date)" > /etc/droidspaces
EOF_RUN
# 注入 binfmt 服务脚本
COPY scripts/binfmt/qemu-binfmt-register.sh /usr/local/bin/
COPY scripts/binfmt/qemu-binfmt-register.service /etc/systemd/system/
RUN if [ "$ENABLE_binfmt_ARG" = "false" ]; then \
rm -rf /usr/local/bin/qemu-binfmt-register.sh && \
rm -rf /etc/systemd/system/qemu-binfmt-register.service ; \
fi
RUN if [ "$ENABLE_binfmt_ARG" = "true" ]; then \
chmod +x /usr/local/bin/qemu-binfmt-register.sh && \
chmod 644 /etc/systemd/system/qemu-binfmt-register.service && \
mkdir -p /etc/systemd/system/multi-user.target.wants && \
ln -sf /etc/systemd/system/qemu-binfmt-register.service /etc/systemd/system/multi-user.target.wants/qemu-binfmt-register.service && \
pacman -S --noconfirm --needed qemu-user qemu-user-binfmt && \
rm -rf /var/cache/pacman/pkg/* /var/lib/pacman/sync/* ; \
else \
rm -f /usr/local/bin/qemu-binfmt-register.sh /etc/systemd/system/qemu-binfmt-register.service; \
fi
# 可选:为 systemd 258+ 发行版构建 systemd 257 旧内核兼容运行时。
RUN if [ "$ENABLE_systemd257_ARG" = "true" ]; then \
bash /usr/local/sbin/systemd257; \
else \
echo "--> [跳过] 未启用 systemd 257 旧内核兼容"; \
fi && \
rm -f /usr/local/sbin/systemd257
# 彻底清理 pacman 缓存
RUN rm -rf /var/cache/pacman/pkg/* /var/lib/pacman/sync/*
# 阶段 2:将完整的根文件系统导出到 scratch(空白层),以便外部直接提取或打包成 tarfs
FROM scratch AS export
COPY --from=customizer / /