-
Notifications
You must be signed in to change notification settings - Fork 0
/
build-fabmo-image.sh
356 lines (309 loc) · 14.4 KB
/
build-fabmo-image.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
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
#!/bin/bash -e
# Variables
RESOURCE_DIR="/home/pi/Scripts/resources"
FABMO_RESOURCE_DIR="/fabmo/files"
# Clean any existing install
clean() {
rm -rf /fabmo
rm -rf /fabmo-updater
rm -rf /opt/fabmo
}
# Function to wait for the dpkg lock to be released
wait_for_dpkg_lock() {
while sudo fuser /var/lib/dpkg/lock >/dev/null 2>&1 || sudo fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; do
echo "Waiting for dpkg lock to be released..."
sleep 5
done
}
copy_files() {
echo "Copying files from $1 to $2..."
mkdir -p "$2"
cp -r "$1"/* "$2"
echo "Files copied from $1 to $2"
}
# Function to handle simple file operations
install_file() {
echo "Installing $1 to $2..."
mkdir -p "$(dirname "$2")"
cp $1 $2
echo "Installed $1 to $2"
}
# Install required packages and configure system
install_packages_and_configure() {
wait_for_dpkg_lock
echo "Updating package lists..."
apt-get update
apt-get install -y bossa-cli hostapd dnsmasq xserver-xorg-input-libinput pi-package jackd2 python3-pyudev python3-tornado wvkbd
# Preconfigure jackd2 (audio) to allow real-time process priority
debconf-set-selections <<< "jackd2 jackd/tweak_rt_limits boolean true"
echo "Packages installed."
echo ""
}
# Setup System Configuration (country also done is basic first start of OS download)
setup_system() {
wait_for_dpkg_lock
echo "Setting up system configurations..."
raspi-config nonint do_blanking 1
raspi-config nonint do_wifi_country US
raspi-config nonint do_rgpio 0
raspi-config nonint do_i2c 0
raspi-config nonint do_ssh 0
raspi-config nonint do_hostname shopbot
# Set up node.js
echo "Installing node.js..."
apt-get install -y ca-certificates curl gnupg
mkdir -p /etc/apt/keyrings
curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor --yes --batch -o /etc/apt/keyrings/nodesource.gpg
echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_16.x nodistro main" > /etc/apt/sources.list.d/nodesource.list
wait_for_dpkg_lock
apt-get update
apt-get install -y nodejs
echo "Installing npm..."
wait_for_dpkg_lock
apt-get install -y npm
echo "npm installed."
# Bookworm version ... dealing with initialization screens
echo "Setting up screens ..."
if ! grep -q "^disable_splash=1" /boot/firmware/config.txt; then
echo "disable_splash=1" >> /boot/firmware/config.txt
fi
if ! grep -q "quiet" /boot/firmware/cmdline.txt; then
sed -i '1 s/$/ quiet/' /boot/firmware/cmdline.txt
fi
if ! grep -q "splash" /boot/firmware/cmdline.txt; then
sed -i '1 s/$/ splash/' /boot/firmware/cmdline.txt
fi
# to get the firstboot expansion to run on the next boot; also a line in the config.txt for this that must be in place
if ! grep -q "init=/usr/lib/raspberrypi-sys-mods/firstboot" /boot/firmware/cmdline.txt; then
sed -i'' -e '1 s/$/ init=\/usr\/lib\/raspberrypi-sys-mods\/firstboot/' /boot/firmware/cmdline.txt
fi
echo "System Configurations set."
echo ""
}
# Copy all network, user utility, and system files
copy_all_files() {
echo "Copying network, user utility, and system files..."
# NetworkManager Configurations (will not be updated with fabmo update)
install_file "$RESOURCE_DIR/NetworkManager/NetworkManager.conf" "/etc/NetworkManager/NetworkManager.conf"
# NetworkManager system-connections (will not be updated with fabmo update)
copy_files "$RESOURCE_DIR/NetworkManager/system-connections" "/etc/NetworkManager/system-connections"
# NetworkManager make sure we have the right permissions on these files, they are sensitive
chmod 600 /etc/NetworkManager/system-connections/*
# hostapd configuration file (will not be updated with fabmo update)
mkdir -p /etc/hostapd
install_file "$RESOURCE_DIR/hostapd/hostapd.conf" "/etc/hostapd/hostapd.conf"
install_file "$RESOURCE_DIR/hostapd/hostapd.service" "/lib/systemd/system/hostapd.service"
chmod 644 /lib/systemd/system/hostapd.service
# User Utilities
mkdir -p /home/pi/Scripts
install_file "$RESOURCE_DIR/fabmo.bashrc" "/home/pi/.bashrc"
install_file "$RESOURCE_DIR/dev-build.sh" "/home/pi/Scripts"
# Key USB symlink file for FabMo and VFD
install_file "$RESOURCE_DIR/99-fabmo-usb.rules" "/etc/udev/rules.d/"
chmod 644 /etc/udev/rules.d/99-fabmo-usb.rules
# Boot and User Interface Resources
install_file "$RESOURCE_DIR/FabMo-Icon-03-left.png" "/usr/share/plymouth/themes/pix/splash.png"
install_file "$RESOURCE_DIR/shopbot-pi-bkgnd.png" "/home/pi/Pictures/shopbot-pi-bkgnd.png"
install_file "$RESOURCE_DIR/FabMo-Icon-03.png" "/home/pi/Pictures/FabMo-Icon-03.png"
install_file "$RESOURCE_DIR/icon.png" "/home/pi/Pictures/icon.png"
install_file "$RESOURCE_DIR/xShopBot4.ico" "/home/pi/Pictures/xShopBot4.ico"
plymouth-set-default-theme --rebuild-initrd pix
install_file "$RESOURCE_DIR/fabmo-release.txt" "/boot"
install_file "$RESOURCE_DIR/fabmo-release.txt" "/etc"
# Install the wf-panel-pi.ini to get some panel items in the menu
install_file "$RESOURCE_DIR/wf-panel-pi.ini" "/home/pi/.config/wf-panel-pi.ini"
# New virtual keyboard for Bookworm and toggling it on and off
install_file "$RESOURCE_DIR/toggle-wvkbd.sh" "/usr/bin/toggle-wvkbd.sh"
install_file "$RESOURCE_DIR/virtual-keyboard.desktop" "/home/pi/.local/share/applications/virtual-keyboard.desktop"
chmod +x /usr/bin/toggle-wvkbd.sh
chmod +x /home/pi/.local/share/applications/virtual-keyboard.desktop
echo "Network, user utility, and system files copied."
echo ""
}
# Set up desktop for FabMo users
setup_desktop_environment() {
echo "Setting up desktop environment..."
mkdir -p /home/pi/.config/pcmanfm/LXDE-pi
mkdir -p /home/pi/Desktop
mkdir -p /etc/X11/xorg.conf.d
# Copy configuration files
cp $RESOURCE_DIR/desktop-items-0.conf /etc/xdg/pcmanfm/LXDE-pi/
cp $RESOURCE_DIR/panel /etc/xdg/lxpanel/LXDE-pi/panels/
cp $RESOURCE_DIR/40-libinput.conf /etc/X11/xorg.conf.d/
echo "Desktop environment set up."
echo ""
}
# Setup FabMo // Note that many resource files are in the fabmo/files directory; so this needs to be installed before copying
# ... this is partly done to keep changes in the fabmo update rather than the image and to prevent changes to permissions from copying between systems
setup_fabmo() {
echo "cloning fabmo-engine"
git clone https://github.com/FabMo/FabMo-Engine.git /fabmo
cd /fabmo
echo "installing fabmo-engine"
npm install
echo "building fabmo-engine"
npm run build
echo "cloning fabmo-updater"
git clone https://github.com/FabMo/FabMo-Updater.git /fabmo-updater
cd /fabmo-updater
npm install
# The updater needs to be started twice to create config files and run
npm run start
# Delay to allow the updater to create the config files
sleep 15
#npm run start
echo "installed fabmo-updater"
echo "FabMo and Updater done ..."
echo ""
}
# Move files from fabmo/files to the correct locations and set permissions **BUT CURRENT VERSIONS NEED TO BE IN PLACE FIRST in fabmo/files !
# ... this is done to keep changes in the fabmo update rather than the image
# ... this is done after fabmo is installed to prevent changes to the fabmo update from being copied to the image
# install hostapd service file and other symlinks
make_misc_tool_symlinks () {
install_file "$RESOURCE_DIR/hostapd/hostapd.service" "/lib/systemd/system/hostapd.service"
chmod -x /lib/systemd/system/hostapd.service
# Create the directory for hostapd PID file
mkdir -p /run/hostapd
chown root:root /run/hostapd
chmod 755 /run/hostapd
systemctl unmask hostapd
systemctl daemon-reload
systemctl enable hostapd
# Install setup-wlan0_ap service file, shell file now in network_conf_fabmo
install_file "$FABMO_RESOURCE_DIR/network_conf_fabmo/setup-wlan0_ap.service" "/lib/systemd/system/setup-wlan0_ap.service"
# Key dnsmasq configuration file (will not be updated with fabmo update)
install_file "$RESOURCE_DIR/dnsmasq/dnsmasq.conf" "/etc/dnsmasq.conf"
# Make sure we have the right permissions on this file, it is sensitive
chmod 755 /etc/dnsmasq.conf
# enabled them
systemctl daemon-reload
systemctl enable setup-wlan0_ap
systemctl enable dnsmasq
# Create Sym-links for External FabMo Tools services
sudo ln -sf $FABMO_RESOURCE_DIR/tools/ck_heat_volts.sh /usr/local/bin/ck_heat_volts
sudo ln -sf $FABMO_RESOURCE_DIR/tools/ck_network.sh /usr/local/bin/ck_network
sudo ln -sf $FABMO_RESOURCE_DIR/tools/ck_services.sh /usr/local/bin/ck_services
}
# SystemD
load_and_initialize_systemd_services() {
echo "Setting up systemd services..."
# FabMo and Updater SystemD Service symlinks to files
cd /etc/systemd/system
echo "Creating systemd sym-links from fabmo/files ..."
SERVICES=("fabmo.service" "camera-server-1.service" "camera-server-2.service")
# Loop through the services and create symlinks
for SERVICE in "${SERVICES[@]}"; do
if [ -f "/fabmo/files/$SERVICE" ]; then
if [ ! -L "/etc/systemd/system/$SERVICE" ]; then
ln -s "/fabmo/files/$SERVICE" .
echo "Created symlink for /fabmo/files/$SERVICE"
else
echo "Symlink for /fabmo/files/$SERVICE already exists"
fi
else
echo "Source file /fabmo/files/$SERVICE does not exist"
fi
done
echo "Creating systemd sym-links from fabmo/files/network_conf_fabmo ..."
SERVICES=("network-monitor.service" "export-netcfg-thumbdrive.service" "export-netcfg-thumbdrive.path")
for SERVICE in "${SERVICES[@]}"; do
if [ -f "/fabmo/files/network_conf_fabmo/$SERVICE" ]; then
if [ ! -L "/etc/systemd/system/$SERVICE" ]; then
ln -s "/fabmo/files/network_conf_fabmo/$SERVICE" .
echo "Created symlink for /fabmo/files/network_conf_fabmo/$SERVICE"
else
echo "Symlink for /fabmo/files/network_conf_fabmo/$SERVICE already exists"
fi
else
echo "Source file /fabmo/files/network_conf_fabmo/$SERVICE does not exist"
fi
done
echo "Copy the recent_wifi.json from resources/network_conf_fabmo to /etc/network_conf_fabmo"
mkdir -p /etc/network_conf_fabmo
install_file "$RESOURCE_DIR/network_conf_fabmo/recent_wifi.json" "/etc/network_conf_fabmo/recent_wifi.json"
echo "... done created /etc/network_conf_fabmo/recent_wifi.json"
echo "Creating systemd sym-links from fabmo-updater ..."
SERVICES=("fabmo-updater.service")
for SERVICE in "${SERVICES[@]}"; do
if [ -f "/fabmo-updater/files/$SERVICE" ]; then
if [ ! -L "/etc/systemd/system/$SERVICE" ]; then
ln -s "/fabmo-updater/files/$SERVICE" .
echo "Created symlink for /fabmo-updater/files/$SERVICE"
else
echo "Symlink for /fabmo-updater/files/$SERVICE already exists"
fi
else
echo "Source file /fabmo-updater/files/$SERVICE does not exist"
fi
done
# Create or edit the systemd override for dnsmasq
mkdir -p /etc/systemd/system/dnsmasq.service.d
sudo tee /etc/systemd/system/dnsmasq.service.d/override.conf > /dev/null <<EOF
[Unit]
After=network-online.target
Wants=network-online.target
EOF
# Install autostart for ip-reporting, method should work for generic user in bookworm
install_file "/fabmo/files/network_conf_fabmo/fabmo-ip-reporting.desktop" "/etc/xdg/autostart/fabmo-ip-reporting.desktop"
chmod -x /etc/xdg/autostart/fabmo-ip-reporting.desktop
# Make sure that all files in /fabmo/files and subdirectories that end in .service or .path are not executable
find /fabmo/files -type f -name "*.service" -exec chmod -x {} \;
find /fabmo-updater/files -type f -name "*.service" -exec chmod -x {} \;
find /fabmo/files/network_conf_fabmo -type f -name "*.service" -exec chmod -x {} \;
find /fabmo/files/network_conf_fabmo -type f -name "*.path" -exec chmod -x {} \;
# Make sure that all files in /fabmo/files and subdirectories that end in .sh or .py are executable
find /fabmo/files -type f -name "*.sh" -exec chmod +x {} \;
find /fabmo/files/network_conf_fabmo -type f -name "*.sh" -exec chmod +x {} \;
find /fabmo/files/tools -type f -name "*.sh" -exec chmod +x {} \;
find /fabmo/files -type f -name "*.py" -exec chmod +x {} \;
find /fabmo/files/network_conf_fabmo -type f -name "*.py" -exec chmod +x {} \;
find /fabmo/files/tools -type f -name "*.py" -exec chmod +x {} \;
echo "Enabling systemd services..."
systemctl daemon-reload
systemctl enable fabmo.service
systemctl enable fabmo-updater.service
systemctl enable network-monitor.service
systemctl enable camera-server-1.service
systemctl enable camera-server-2.service
systemctl enable export-netcfg-thumbdrive.service
systemctl enable export-netcfg-thumbdrive.path
echo "Systemd services setup complete."
echo ""
}
some_extras () {
# Install a ShopBot starter on Desktop; may work, still needs run setting File Manager to not ask options on launch executable file.
install_file "$RESOURCE_DIR/shopbot-starter.desktop" "/home/pi/Desktop/shopbot-starter.desktop"
chmod +x /home/pi/Desktop/shopbot-starter.desktop
}
# Main installation
main_installation() {
echo ""
echo "BUILDING FabMo SD-Card IMAGE ==========================================================="
echo ""
clean
install_packages_and_configure
setup_system
copy_all_files
setup_desktop_environment
setup_fabmo
cd /home/pi
load_and_initialize_systemd_services
make_misc_tool_symlinks
some_extras
echo ""
echo "BUILD, Installation, and Configuration Complete. ==============(remove BUILD files?)===="
echo ""
echo ""
echo "MANUAL STEPS NOW REQUIRED:"
echo "-Check to make sure expansion call is in /boot/firmware/cmdline.txt; last line should have init=/usr/lib/raspberrypi-sys-mods/firstboot"
echo "-Enable running from desktop in FileManager > Edit > Prefs (Don't ask options ...)."
echo "-Delete this script and /resources from Scripts folder."
echo "-? Set up rotation for small screen."
echo ""
echo "-MAKE 8G COPY NOW, BEFORE FIRST BOOT"
echo ""
echo ""
}
# Execute main installation function
main_installation