-
Notifications
You must be signed in to change notification settings - Fork 1
/
prepare-debian-userland.sh
320 lines (285 loc) · 7.95 KB
/
prepare-debian-userland.sh
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
#!/bin/sh
# Prepare a Debian userland environment suitable for running Electron and other Linux applications
# Based on https://github.com/mrclksr/linux-browser-installer/blob/main/linux-browser-installer
# TODO: poke holes for /usr/share/icons, /usr/share/fonts, and similar directories?
# TODO: Get D-Bus working?
. /etc/rc.subr
prefix=/usr/local
chroot_path=/compat/debian
debian_version=bullseye
ld_version=2.31
bindir="${prefix}/bin"
appsdir="${prefix}/share/applications"
chroot_bindir="${chroot_path}/bin"
apt_packages="gnupg pulseaudio libnss3 libgl1 curl unzip wget binutils libglib2.0-dev libgbm-dev libgtk-3-0 libgtk2.0-0 \
libxss1 libsecret-1-0 libxkbfile1 libxcb-composite0 libxcb-cursor0 libxcb-damage0 libxcb-doc libxcb-dpms0 libxcb-ewmh2 \
libxcb-icccm4 libxcb-image0 libxcb-imdkit1 libxcb-keysyms1 libxcb-record0 libxcb-render-util0 libxcb-res0 libxcb-screensaver0 \
libxcb-shape0 libxcb-util1 libxcb-xf86dri0 libxcb-xinerama0 libxcb-xinput0 libxcb-xkb1 libxcb-xrm0 libxcb-xtest0 libxcb-xv0 \
libxcb-xvmc0 libfuse2 libegl-* locales mesa-utils libgl1-mesa-glx libpangoxft vdpau-va-driver vdpau-driver-all libgl1-mesa-dri vulkan-tools"
# libsecret-1-0 libxkbfile1 needed by, e.g., Arduino IDE 2.0
# libpangoxft needed by, e.g., PrusaSlicer
# vdpau-va-driver vdpau-driver-all libgl1-mesa-dri vulkan-tools in the hope to improve Linuxulator 3D acceleration capabilities
pkg_list="debootstrap" # pulseaudio would beed to be installed on the target machine, not on the build machine
chroot_mount_points="
/proc
/sys
/dev
/dev/fd
/dev/shm
/tmp
"
unmounted()
{
[ `stat -f "%d" "$1"` == `stat -f "%d" "$1/.."` -a \
`stat -f "%i" "$1"` != `stat -f "%i" "$1/.."` ]
}
debian_start()
{
local _emul_path _tmpdir
load_kld -e 'linux(aout|elf)' linux
case `sysctl -n hw.machine_arch` in
amd64)
load_kld -e 'linux64elf' linux64
;;
esac
if [ -x /compat/debian/sbin/ldconfigDisabled ]; then
_tmpdir=`mktemp -d -t linux-ldconfig`
/compat/debian/sbin/ldconfig -C ${_tmpdir}/ld.so.cache
if ! cmp -s ${_tmpdir}/ld.so.cache /compat/debian/etc/ld.so.cache; then
cat ${_tmpdir}/ld.so.cache > /compat/debian/etc/ld.so.cache
fi
rm -rf ${_tmpdir}
fi
# Linux uses the pre-pts(4) tty naming scheme.
load_kld pty
# Handle unbranded ELF executables by defaulting to ELFOSABI_LINUX.
if [ `sysctl -ni kern.elf64.fallback_brand` -eq "-1" ]; then
sysctl kern.elf64.fallback_brand=3 > /dev/null
fi
if [ `sysctl -ni kern.elf32.fallback_brand` -eq "-1" ]; then
sysctl kern.elf32.fallback_brand=3 > /dev/null
fi
sysctl compat.linux.emul_path="${chroot_path}"
_emul_path="${chroot_path}"
unmounted "${_emul_path}/proc" && (mount -t linprocfs linprocfs "${_emul_path}/proc" || exit 1)
unmounted "${_emul_path}/sys" && (mount -t linsysfs linsysfs "${_emul_path}/sys" || exit 1)
unmounted "${_emul_path}/dev" && (mount -t devfs devfs "${_emul_path}/dev" || exit 1)
unmounted "${_emul_path}/dev/fd" && (mount -o linrdlnk -t fdescfs fdescfs "${_emul_path}/dev/fd" || exit 1)
unmounted "${_emul_path}/dev/shm" && (mount -o mode=1777 -t tmpfs tmpfs "${_emul_path}/dev/shm" || exit 1)
unmounted "${_emul_path}/tmp" && (mount -t nullfs /tmp "${_emul_path}/tmp" || exit 1)
unmounted /dev/fd && (mount -t fdescfs null /dev/fd || exit 1)
unmounted /proc && (mount -t procfs procfs /proc || exit 1)
true
}
bail()
{
if [ $# -gt 0 ]; then
echo "${0##*/}: Error: $*" >&2
fi
exit 1
}
mk_mount_dirs()
{
local dir p
for p in ${chroot_mount_points}; do
dir="${chroot_path}/$p"
[ ! -d "${dir}" ] && mkdir -p "${dir}"
done
}
umount_chroot()
{
local mntpts _chroot_path p _p
_chroot_path=$(realpath "${chroot_path}")
[ $? -ne 0 -o -z "${_chroot_path}" ] && exit 1
mntpts=$(mount -p | awk -F'[ \t]+' -v chroot=${_chroot_path} '
$2 ~ sprintf("^%s/", chroot) {
mp[n++] = $2
}
END {
while (--n >= 0) print mp[n]
}
')
for p in ${mntpts}; do
_p=$(realpath "$p")
[ $? -ne 0 -o -z "${_p}" ] && exit 1
umount "${_p}" || exit 1
if (mount -p | grep -q "${_p}/"); then
bail "Couldn't unmount ${_p}"
fi
done
}
install_steam_utils()
{
pkg info --exists linux-steam-utils && return
pkg fetch -y -o /tmp linux-steam-utils || exit 1
pkgpath=/tmp/All/linux-steam-utils-*.pkg
[ ! -f ${pkgpath} ] && pkgpath=/tmp/All/linux-steam-utils-*.txz
[ ! -f ${pkgpath} ] && exit 1
(cd / && tar -xf ${pkgpath} \
--exclude '^+COMPACT_MANIFEST' \
--exclude '^+MANIFEST')
}
install_packages()
{
for p in ${pkg_list}; do
pkg info --exists $p && continue
pkg install -y $p || bail "'pkg install -y $p' failed"
done
}
fix_ld_path()
{
(cd ${chroot_path}/lib64 && \
(unlink ./ld-linux-x86-64.so.2; \
ln -s ../lib/x86_64-linux-gnu/ld-${ld_version}.so \
ld-linux-x86-64.so.2))
}
install_apt_packages()
{
chroot ${chroot_path} /bin/bash -c 'apt update'
chroot ${chroot_path} /bin/bash -c 'apt remove -y rsyslog'
for p in ${apt_packages}; do
chroot ${chroot_path} /bin/bash -c "apt install -y $p" || \
bail "'apt install -y $p' failed"
done
}
symlink_icons()
{
local name i
[ ! -d ${chroot_path}/usr/share/icons ] && \
mkdir -p ${chroot_path}/usr/share/icons
for i in ${prefix}/share/icons/*; do
[ ! -d $i ] && continue
name=$(basename $i)
[ -e ${chroot_path}/usr/share/icons/${name} ] && continue
ln -s $i ${chroot_path}/usr/share/icons
done
}
symlink_themes()
{
local name i
[ ! -d ${chroot_path}/usr/share/themes ] && \
mkdir -p ${chroot_path}/usr/share/themes
for i in ${prefix}/share/themes/*; do
[ ! -d $i ] && continue
name=$(basename $i)
[ -e ${chroot_path}/usr/share/themes/${name} ] && continue
ln -s $i ${chroot_path}/usr/share/themes
done
}
set_timezone()
{
printf "0.0 0 0.0\n0\nUTC\n" > ${chroot_path}/etc/adjtime
rm -rf "${chroot_path}/etc/localtime"
if [ ! -d "${chroot_path}/etc/localtime" ]; then
mkdir -p "${chroot_path}/etc/localtime"
fi
ln -s "/usr/share/zoneinfo/$(cat /var/db/zoneinfo)" \
${chroot_path}/etc/localtime
chroot ${chroot_path} /bin/bash -c \
"dpkg-reconfigure --frontend noninteractive tzdata"
}
install_chroot_base()
{
[ -f ${chroot_path}/etc/os-release ] && return
mk_mount_dirs
sysrc linux_enable=NO
sysrc debian_enable=YES
debian_start || bail "Failed to start debian service"
install_steam_utils
install_packages
chmod 0755 /usr/local/sbin/debootstrap
/usr/local/sbin/debootstrap --arch=amd64 --no-check-gpg ${debian_version} ${chroot_path} || \
bail "debootstrap failed"
echo "APT::Cache-Start 251658240;" > \
${chroot_path}/etc/apt/apt.conf.d/00aptitude
echo "deb http://deb.debian.org/debian ${debian_version} main" > \
${chroot_path}/etc/apt/sources.list
fix_ld_path
set_timezone
debian_start
install_apt_packages
rm "${chroot_path}"/etc/resolv.conf # Will this be sufficient?
# symlink_icons
# symlink_themes
}
deinstall_chroot_base()
{
local path
path=$(realpath ${chroot_path})
[ $? -ne 0 ] && exit 1
if [ "${path}" = "/" ]; then
echo "chroot_path must not be '/'" >&2
exit 1
fi
umount_chroot
rm -rf "${path}"
}
upgrade_chroot()
{
local flags="-q -y --allow-downgrades"
flags="${flags} --allow-remove-essential --allow-change-held-packages"
chroot ${chroot_path} /bin/bash -c "apt-get update && apt upgrade ${flags}"
}
cleanup()
{
rm -f bin/chrome bin/brave chroot/bin/chrome chroot/bin/brave rc.d/debian
}
image()
{
makefs -o 'label=debian' /tmp/debian.ufs "${chroot_path}"
mkuzip -A zstd -C 15 -d -s 262144 -o /tmp/debian.img /tmp/debian.ufs
readlink -f /tmp/debian.img
ls -lh /tmp/debian.img
}
usage()
{
echo "Usage: $0 chroot <create|upgrade|delete>"
echo " $0 symlink <icons|themes>"
echo " $0 clean"
exit 1
}
if [ $(id -u) -ne 0 ]; then
echo "This script must be run as root" 1>&2
exit 1
fi
[ $# -eq 0 ] && usage
while [ $# -gt 0 ]; do
case "$1" in
chroot|jail)
case $2 in
create)
install_chroot_base
exit 0
;;
delete)
deinstall_chroot_base
exit 0
;;
upgrade)
upgrade_chroot
exit 0
;;
*)
usage
;;
esac
shift
;;
symlink)
case $2 in
icons|themes)
eval symlink_$2
exit 0
;;
*)
usage
;;
esac
shift
;;
*)
usage
;;
esac
shift
done