263 lines
6.8 KiB
Bash
Executable File
263 lines
6.8 KiB
Bash
Executable File
#! /bin/bash
|
|
set -ex
|
|
|
|
# runs setup commands inside the image, under qemu arm64.
|
|
|
|
sudo tee mnt/root/tmp/image-build.sh >/dev/null <<'EOF'
|
|
#! /bin/bash
|
|
set -ex
|
|
|
|
export DEBIAN_FRONTEND=noninteractive
|
|
|
|
mkdir -p /etc/apt/apt.conf.d/disabled
|
|
|
|
for f in \
|
|
/etc/apt/apt.conf.d/*command-not-found* \
|
|
/etc/apt/apt.conf.d/*appstream* \
|
|
/etc/apt/apt.conf.d/*packagekit*
|
|
do
|
|
[ -e "$f" ] && mv "$f" /etc/apt/apt.conf.d/disabled/
|
|
done
|
|
|
|
rm -rf /var/lib/apt/lists/*
|
|
mkdir -p /var/lib/apt/lists/partial
|
|
|
|
# The preinstalled image may contain packages from noble-updates while only
|
|
# noble and noble-security are enabled. Enable noble-updates before installing
|
|
# -dev packages so apt can resolve exact-version dependencies.
|
|
if grep -q '^Suites: noble$' /etc/apt/sources.list.d/ubuntu.sources; then
|
|
sed -i 's/^Suites: noble$/Suites: noble noble-updates/' /etc/apt/sources.list.d/ubuntu.sources
|
|
fi
|
|
|
|
echo "====> updating apt"
|
|
apt-get update
|
|
|
|
echo "====> installing apt packages"
|
|
apt-get install -y \
|
|
ca-certificates \
|
|
curl \
|
|
jq \
|
|
git \
|
|
locales \
|
|
wpasupplicant \
|
|
iproute2 \
|
|
isc-dhcp-client \
|
|
libcap2-bin \
|
|
pkg-config \
|
|
libdbus-1-dev \
|
|
avahi-daemon \
|
|
avahi-utils \
|
|
libavahi-client-dev \
|
|
bluez \
|
|
python3-pip \
|
|
sox \
|
|
alsa-utils \
|
|
libasound2-plugins \
|
|
swh-plugins \
|
|
i2c-tools \
|
|
device-tree-compiler \
|
|
unzip \
|
|
openssh-server \
|
|
sudo
|
|
|
|
# setup locale
|
|
locale-gen en_US.UTF-8
|
|
update-locale LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8
|
|
|
|
echo "====> setting hostname"
|
|
printf 'toes\n' >/etc/hostname
|
|
if grep -q '^127\.0\.1\.1' /etc/hosts; then
|
|
sed -i 's/^127\.0\.1\.1.*/127.0.1.1 toes/' /etc/hosts
|
|
else
|
|
printf '127.0.1.1 toes\n' >>/etc/hosts
|
|
fi
|
|
mkdir -p /etc/cloud/cloud.cfg.d
|
|
printf 'preserve_hostname: true\n' >/etc/cloud/cloud.cfg.d/99-preserve-hostname.cfg
|
|
|
|
echo "====> enabling mdns hostname advertisement"
|
|
systemctl enable avahi-daemon.service
|
|
|
|
echo "====> configuring bluetooth for Matter commissioning"
|
|
mkdir -p /etc/systemd/system/bluetooth.service.d
|
|
cat >/etc/systemd/system/bluetooth.service.d/10-matter.conf <<'EOBT'
|
|
[Service]
|
|
ExecStart=
|
|
ExecStart=/usr/libexec/bluetooth/bluetoothd -E -P battery
|
|
EOBT
|
|
systemctl enable bluetooth.service
|
|
|
|
echo "====> configuring wlan0 for wpa_supplicant + systemd-networkd"
|
|
apt-get purge -y network-manager || true
|
|
systemctl disable NetworkManager.service NetworkManager-wait-online.service NetworkManager-dispatcher.service || true
|
|
systemctl mask NetworkManager.service NetworkManager-wait-online.service NetworkManager-dispatcher.service || true
|
|
|
|
mkdir -p /etc/wpa_supplicant
|
|
cat >/etc/wpa_supplicant/wpa_supplicant-wlan0.conf <<'EOWPA'
|
|
ctrl_interface=DIR=/run/wpa_supplicant GROUP=netdev
|
|
update_config=1
|
|
EOWPA
|
|
chmod 0600 /etc/wpa_supplicant/wpa_supplicant-wlan0.conf
|
|
|
|
mkdir -p /etc/systemd/system/wpa_supplicant.service.d
|
|
cat >/etc/systemd/system/wpa_supplicant.service.d/10-wlan0.conf <<'EOSD'
|
|
[Unit]
|
|
Requires=sys-subsystem-net-devices-wlan0.device
|
|
After=sys-subsystem-net-devices-wlan0.device
|
|
|
|
[Service]
|
|
ExecStart=
|
|
ExecStart=/usr/sbin/wpa_supplicant -u -s -i wlan0 -c /etc/wpa_supplicant/wpa_supplicant-wlan0.conf -O "DIR=/run/wpa_supplicant GROUP=netdev"
|
|
Restart=on-failure
|
|
RestartSec=2s
|
|
EOSD
|
|
|
|
mkdir -p /etc/systemd/network
|
|
cat >/etc/systemd/network/00-wlan0.network <<'EONET'
|
|
[Match]
|
|
Name=wlan0
|
|
|
|
[Link]
|
|
RequiredForOnline=no
|
|
|
|
[Network]
|
|
DHCP=yes
|
|
IPv6AcceptRA=yes
|
|
|
|
[DHCPv4]
|
|
RouteMetric=600
|
|
EONET
|
|
|
|
systemctl enable wpa_supplicant.service
|
|
systemctl enable systemd-networkd.service
|
|
systemctl enable systemd-resolved.service
|
|
|
|
echo "====> creating toes user"
|
|
groupadd -f audio
|
|
if id -u toes >/dev/null 2>&1; then
|
|
usermod -aG sudo,audio toes
|
|
else
|
|
useradd -m -s /bin/bash -G sudo,audio toes
|
|
fi
|
|
|
|
echo 'toes:nicetrywiseguy' | chpasswd
|
|
|
|
printf 'toes ALL=(ALL) NOPASSWD:ALL\n' >/etc/sudoers.d/90-toes
|
|
chmod 0440 /etc/sudoers.d/90-toes
|
|
visudo -cf /etc/sudoers.d/90-toes
|
|
|
|
echo "====> configuring ssh password login"
|
|
mkdir -p /etc/ssh/sshd_config.d
|
|
cat >/etc/ssh/sshd_config.d/10-toes-password-login.conf <<'EOSSH'
|
|
PasswordAuthentication yes
|
|
EOSSH
|
|
printf 'ssh_pwauth: true\n' >/etc/cloud/cloud.cfg.d/99-ssh-password-auth.cfg
|
|
mkdir -p /run/sshd
|
|
sshd -t
|
|
sshd -T | grep -qx 'passwordauthentication yes'
|
|
systemctl enable ssh.service
|
|
|
|
# enable serial over usb
|
|
echo 'g_serial' >/etc/modules-load.d/usb-serial-gadget.conf
|
|
systemctl enable serial-getty@ttyGS0.service
|
|
|
|
echo "====> building audio overlay"
|
|
/tmp/build-audio.sh
|
|
systemctl enable init-audio.service
|
|
|
|
echo "====> installing rgbled"
|
|
curl -fsSL https://git.nose.space/nakajima/rgbled/releases/download/v0.1.1/install.sh | bash
|
|
|
|
echo "====> installing matter stack"
|
|
curl -fsSL https://git.nose.space/nakajima/toes-matter/releases/download/latest/install.sh | sh
|
|
if [ ! -x /usr/local/bin/toes-matter ]; then
|
|
echo "missing /usr/local/bin/toes-matter after install" >&2
|
|
exit 1
|
|
fi
|
|
systemctl enable toes-matter.service
|
|
|
|
TOES_HOME="$(getent passwd toes | cut -d: -f6)"
|
|
mkdir -p "$TOES_HOME"
|
|
chown toes:toes "$TOES_HOME"
|
|
|
|
echo "====> installing bun"
|
|
runuser -u toes -- env HOME="$TOES_HOME" USER=toes LOGNAME=toes bash -c \
|
|
'curl -fsSL https://bun.sh/install | bash >/dev/null 2>&1'
|
|
|
|
BUN="$TOES_HOME/.bun/bin/bun"
|
|
if [ ! -x "$BUN" ]; then
|
|
echo "missing bun after install: $BUN" >&2
|
|
exit 1
|
|
fi
|
|
ln -sf "$BUN" /usr/local/bin/bun
|
|
setcap 'cap_net_bind_service=+ep' "$BUN"
|
|
|
|
echo "====> installing toes app as toes"
|
|
runuser -u toes -- env HOME="$TOES_HOME" USER=toes LOGNAME=toes bash <<'EOSU'
|
|
set -ex
|
|
|
|
export PATH="$HOME/.bun/bin:/usr/local/bin:/usr/bin:/bin:$PATH"
|
|
|
|
quiet() {
|
|
"$@"
|
|
}
|
|
|
|
REPO="https://git.nose.space/defunkt/toes"
|
|
DEST="$HOME/toes"
|
|
APPS_DIR="$HOME/apps"
|
|
DATA_DIR="$HOME/data"
|
|
|
|
echo "====> installing baudy"
|
|
if [ ! -d "$HOME/baudy" ]; then
|
|
git clone https://git.nose.space/nakajima/baudy "$HOME/baudy"
|
|
fi
|
|
|
|
if [ -d "$DEST/.git" ]; then
|
|
echo "====> Pulling latest toes"
|
|
git -C "$DEST" fetch origin main
|
|
git -C "$DEST" reset --hard origin/main
|
|
else
|
|
echo "====> Cloning toes"
|
|
git clone "$REPO" "$DEST"
|
|
fi
|
|
|
|
mkdir -p "$APPS_DIR" "$DATA_DIR" "$DATA_DIR/toes"
|
|
|
|
cd "$DEST"
|
|
|
|
echo "====> Installing dependencies"
|
|
bun install
|
|
|
|
echo "====> Building"
|
|
bun run build
|
|
|
|
for app in $BUNDLED_APPS; do
|
|
[ -d "$DEST/apps/$app" ] || continue
|
|
echo " $app"
|
|
cp -r "$DEST/apps/$app" "$APPS_DIR/"
|
|
if [ -f "$APPS_DIR/$app/package.json" ]; then
|
|
quiet bun install --frozen-lockfile --cwd "$APPS_DIR/$app" || quiet bun install --cwd "$APPS_DIR/$app"
|
|
fi
|
|
done
|
|
EOSU
|
|
|
|
echo "====> Installing toes service"
|
|
install -m 644 "$TOES_HOME/toes/scripts/toes.service" /etc/systemd/system/toes.service
|
|
systemctl enable toes.service
|
|
|
|
echo "====> setting initial volume"
|
|
amixer -c toesaudio sset 'Speaker Analog' 80%
|
|
amixer -c toesaudio sset 'DAC' 50%
|
|
amixer -c toesaudio sset 'Speaker Driver' 0
|
|
alsactl store
|
|
|
|
EOF
|
|
|
|
sudo chmod +x mnt/root/tmp/image-build.sh
|
|
sudo chroot mnt/root /bin/bash /tmp/image-build.sh
|
|
sudo rm -f mnt/root/tmp/image-build.sh
|
|
|
|
if [ ! -s mnt/boot/overlays/toesaudio.dtbo ]; then
|
|
echo "missing mnt/boot/overlays/toesaudio.dtbo after chroot build" >&2
|
|
exit 1
|
|
fi
|