This commit is contained in:
Richard Goodwin
2018-10-16 14:43:15 -05:00
6 changed files with 261 additions and 79 deletions

View File

@@ -146,3 +146,17 @@ If you set up the Pi with a keyboard and a monitor disconnect it and connect it
1. Eject the drives.
1. Unplug the Pi from the PC.
1. Plug the Pi into your Tesla.
## Making changes to the system after setup
The setup process configures the Pi with read-only file systems for the operating system but with read-write access through the USB
interface. This means that you'll be able to record dashcam video and add and remove music files but you won't be able to make changes
to files on / or on /boot. This is to protect against corruption of the operating system when the Tesla cuts power to the Pi.
To make changes to the system partitions:
```
ssh pi@teslausb.
sudo -i
mount / -o remount,rw
mount /boot -o remount,rw
```
Then make whatever changes you need to. The next time the system boots the partitions will once again be read-only.

View File

@@ -0,0 +1,22 @@
#!/bin/bash -eu
BACKINGFILES_MOUNTPOINT="$1"
PARTITION_TABLE=$(parted -m /dev/mmcblk0 unit s print)
ROOT_PARTITION_LINE=$(echo "$PARTITION_TABLE" | grep -e "^2:")
LAST_ROOT_PARTITION_SECTOR=$(echo "$ROOT_PARTITION_LINE" | sed 's/s//g' | cut -d ":" -f 3)
FIRST_BACKINGFILES_PARTITION_SECTOR=$(( $LAST_ROOT_PARTITION_SECTOR + 1 ))
ORIGINAL_DISK_IDENTIFIER=$( fdisk -l /dev/mmcblk0 | grep -e "^Disk identifier" | sed "s/Disk identifier: 0x//" )
parted -m /dev/mmcblk0 u s mkpart primary ext4 "$FIRST_BACKINGFILES_PARTITION_SECTOR" 100%
NEW_DISK_IDENTIFIER=$( fdisk -l /dev/mmcblk0 | grep -e "^Disk identifier" | sed "s/Disk identifier: 0x//" )
sed -i "s/${ORIGINAL_DISK_IDENTIFIER}/${NEW_DISK_IDENTIFIER}/g" /etc/fstab
sed -i "s/${ORIGINAL_DISK_IDENTIFIER}/${NEW_DISK_IDENTIFIER}/" /boot/cmdline.txt
mkfs.ext4 -F /dev/mmcblk0p3
echo "/dev/mmcblk0p3 $BACKINGFILES_MOUNTPOINT ext4 auto,rw,noatime 0 2" >> /etc/fstab

View File

@@ -0,0 +1,38 @@
#!/bin/bash -eu
CAM_PERCENT="$1"
BACKINGFILES_MOUNTPOINT="$2"
G_MASS_STORAGE_CONF_FILE_NAME=/etc/modprobe.d/g_mass_storage.conf
function add_drive () {
local name="$1"
local label="$2"
local size="$3"
local filename="$4"
echo "Allocating ${size}K for $filename..."
fallocate -l "$size"K "$filename"
mkfs.vfat "$filename" -F 32 -n "$label"
local mountpoint=/mnt/"$name"
mkdir "$mountpoint"
echo "$filename $mountpoint vfat noauto,users,umask=000 0 0" >> /etc/fstab
}
FREE_1K_BLOCKS="$(df --output=avail --block-size=1K /backingfiles/ | tail -n 1)"
CAM_DISK_SIZE="$(( $FREE_1K_BLOCKS * $CAM_PERCENT / 100 ))"
CAM_DISK_FILE_NAME="$BACKINGFILES_MOUNTPOINT/cam_disk.bin"
add_drive "cam" "CAM" "$CAM_DISK_SIZE" "$CAM_DISK_FILE_NAME"
if [ "$CAM_PERCENT" -lt 100 ]
then
MUSIC_DISK_SIZE="$(df --output=avail --block-size=1K /backingfiles/ | tail -n 1)"
MUSIC_DISK_FILE_NAME="$BACKINGFILES_MOUNTPOINT/music_disk.bin"
add_drive "music" "MUSIC" "$MUSIC_DISK_SIZE" "$MUSIC_DISK_FILE_NAME"
echo "options g_mass_storage file=$CAM_DISK_FILE_NAME,$MUSIC_DISK_FILE_NAME removable=1,1 ro=0,0 stall=0 iSerialNumber=123456" > "$G_MASS_STORAGE_CONF_FILE_NAME"
else
echo "options g_mass_storage file=$CAM_DISK_FILE_NAME removable=1 ro=0 stall=0 iSerialNumber=123456" > "$G_MASS_STORAGE_CONF_FILE_NAME"
fi

View File

@@ -0,0 +1,49 @@
#!/bin/bash
# Adapted from https://github.com/adafruit/Raspberry-Pi-Installer-Scripts/blob/master/read-only-fs.sh
function append_cmdline_txt_param() {
local toAppend="$1"
sed -i "s/\'/ ${toAppend}/g" /boot/cmdline.txt >/dev/null
}
echo "Updating package index files..."
apt-get update
echo "Removing unwanted packages..."
apt-get remove -y --force-yes --purge triggerhappy logrotate dphys-swapfile fake-hwclock
apt-get -y --force-yes autoremove --purge
# Replace log management with busybox (use logread if needed)
echo "Installing ntp and busybox-syslogd..."
apt-get -y --force-yes install ntp busybox-syslogd; dpkg --purge rsyslog
echo "Configuring system..."
# Add fastboot, noswap and/or ro to end of /boot/cmdline.txt
append_cmdline_txt_param fastboot
append_cmdline_txt_param noswap
append_cmdline_txt_param ro
# Move /var/spool to /tmp
rm -rf /var/spool
ln -s /tmp /var/spool
# Change spool permissions in var.conf (rondie/Margaret fix)
sed -i "s/spool\s*0755/spool 1777/g" /usr/lib/tmpfiles.d/var.conf >/dev/null
# Move dhcpd.resolv.conf to tmpfs
touch /tmp/dhcpcd.resolv.conf
rm /etc/resolv.conf
ln -s /tmp/dhcpcd.resolv.conf /etc/resolv.conf
# Update /etc/fstab
# make /boot read-only
# make / read-only
# tmpfs /var/log tmpfs nodev,nosuid 0 0
# tmpfs /var/tmp tmpfs nodev,nosuid 0 0
# tmpfs /tmp tmpfs nodev,nosuid 0 0
sed -i -r "s@(/boot\s+vfat\s+\S+)@\1,ro@" /etc/fstab
sed -i -r "s@(/\s+ext4\s+\S+)@\1,ro@" /etc/fstab
echo "" >> /etc/fstab
echo "tmpfs /var/log tmpfs nodev,nosuid 0 0" >> /etc/fstab
echo "tmpfs /var/tmp tmpfs nodev,nosuid 0 0" >> /etc/fstab
echo "tmpfs /tmp tmpfs nodev,nosuid 0 0" >> /etc/fstab

View File

@@ -23,7 +23,7 @@ Write-Verbose "Updating $configPath ..."
Write-Verbose "Updating $cmdlinePath ..."
$cmdlinetxtContent = gc -Raw $cmdlinePath
$cmdlinetxtContent.Replace("rootwait", "rootwait modules-load=dwc2,g_ether") | Out-File -FilePath $cmdlinePath -Encoding utf8
$cmdlinetxtContent.Replace("rootwait", "rootwait modules-load=dwc2,g_ether").Replace(" init=/usr/lib/raspi-config/init_resize.sh", "") | Out-File -FilePath $cmdlinePath -Encoding utf8
Write-Verbose "Enabling SSH ..."
[System.IO.File]::CreateText($sshPath).Dispose()

View File

@@ -1,6 +1,8 @@
#!/bin/bash -eu
if [ "$(whoami)" != "root" ]
BRANCH=master
if ! [ $(id -u) = 0 ]
then
echo "STOP: Run sudo -i."
exit 1
@@ -15,13 +17,9 @@ function check_variable () {
fi
}
check_variable "archiveserver"
check_variable "sharename"
check_variable "shareuser"
check_variable "sharepassword"
check_variable "campercent"
serverunreachable=false
function check_archive_server_reachable () {
echo "Verifying that the archive server $archiveserver is reachable..."
local serverunreachable=false
ping -c 1 -w 1 "$archiveserver" 1>/dev/null 2>&1 || serverunreachable=true
if [ "$serverunreachable" = true ]
@@ -30,57 +28,87 @@ then
exit 1
fi
archiveserverip="$(getent hosts $archiveserver | cut -d' ' -f1)"
echo "The archive server is reachable."
}
available_space="$(($(df --output=avail / | tail -1) - 1000000))"
function check_available_space () {
echo "Verifying that there is sufficient space available on the MicroSD card..."
if [ "$available_space" -lt 0 ]
local available_space="$( parted -m /dev/mmcblk0 u b print free | tail -1 | cut -d ":" -f 4 | sed 's/B//g' )"
if [ "$available_space" -lt 4294967296 ]
then
echo "STOP: The MicroSD card is too small."
exit 1
fi
function add_drive () {
local name="$1"
local label="$2"
local size="$3"
local filename="$4"
fallocate -l "$size"K "$filename"
mkfs.vfat "$filename" -F 32 -n "$label"
local mountpoint=/mnt/"$name"
mkdir "$mountpoint"
echo "$filename $mountpoint vfat noauto,users,umask=000 0 0" >> /etc/fstab
echo "There is sufficient space available."
}
pushd ~
function get_ancillary_setup_scripts () {
pushd /tmp
wget https://raw.githubusercontent.com/cimryan/teslausb/"$BRANCH"/windows_archive/create-backingfiles-partition.sh
chmod +x ./create-backingfiles-partition.sh
wget https://raw.githubusercontent.com/cimryan/teslausb/"$BRANCH"/windows_archive/create-backingfiles.sh
chmod +x ./create-backingfiles.sh
wget https://raw.githubusercontent.com/cimryan/teslausb/"$BRANCH"/windows_archive/make-root-fs-readonly.sh
chmod +x ./make-root-fs-readonly.sh
popd
}
function fix_cmdline_txt_modules_load ()
{
echo "Fixing the modules-load parameter in /boot/cmdline.txt..."
cp /boot/cmdline.txt ~
cat ~/cmdline.txt | sed 's/[[:space:]]\+modules-load=[^ [:space:]]\+//' | sed 's/rootwait/rootwait modules-load=dwc2/' > /boot/cmdline.txt
rm ~/cmdline.txt
echo "Fixed cmdline.txt."
}
BACKINGFILES_MOUNTPOINT=/backingfiles
function create_usb_drive_backing_files () {
mkdir "$BACKINGFILES_MOUNTPOINT"
/tmp/create-backingfiles-partition.sh "$BACKINGFILES_MOUNTPOINT"
echo "Mounting the partition for the backing files..."
mount /backingfiles
echo "Mounted the partition for the backing files."
/tmp/create-backingfiles.sh "$campercent" "$BACKINGFILES_MOUNTPOINT"
}
function configure_archive () {
echo "Configuring the archive..."
mkdir /mnt/archive
echo "" >> /etc/fstab
echo "//$archiveserverip/$sharename /mnt/archive cifs vers=3,credentials=/root/.teslaCamArchiveCredentials,iocharset=utf8,file_mode=0777,dir_mode=0777 0" >> /etc/fstab
local archive_server_ip_address="$(getent hosts $archiveserver | cut -d' ' -f1)"
echo "//$archive_server_ip_address/$sharename /mnt/archive cifs vers=3,credentials=/root/.teslaCamArchiveCredentials,iocharset=utf8,file_mode=0777,dir_mode=0777 0" >> /etc/fstab
echo "username=$shareuser" > /root/.teslaCamArchiveCredentials
echo "password=$sharepassword" >> /root/.teslaCamArchiveCredentials
echo "Configured the archive."
}
function configure_archive_scripts () {
echo "Configuring the archive scripts..."
mkdir /root/bin
wget https://raw.githubusercontent.com/cimryan/teslausb/master/windows_archive/archiveloop
pushd ~
wget https://raw.githubusercontent.com/cimryan/teslausb/"$BRANCH"/windows_archive/archiveloop
sed s/ARCHIVE_HOST_NAME=archiveserver/ARCHIVE_HOST_NAME=$archiveserver/ ~/archiveloop > /root/bin/archiveloop
rm ~/archiveloop
chmod +x /root/bin/archiveloop
pushd /root/bin
wget https://raw.githubusercontent.com/cimryan/teslausb/master/windows_archive/archive-teslacam-clips
chmod +x archive-teslacam-clips
popd
pushd /root/bin
wget https://raw.githubusercontent.com/cimryan/teslausb/"$BRANCH"/windows_archive/archive-teslacam-clips
chmod +x archive-teslacam-clips
popd
echo "Configured the archive scripts."
}
function configure_rc_local () {
echo "Configuring /etc/rc.local to run the archive scripts at startup..."
echo "#!/bin/bash -eu" > ~/rc.local
tail -n +2 /etc/rc.local | sed '$d' >> ~/rc.local
cat << 'EOF' >> ~/rc.local
@@ -99,24 +127,55 @@ EOF
cat ~/rc.local > /etc/rc.local
rm ~/rc.local
echo "Configured rc.local."
}
cam_disk_size="$(( $available_space * $campercent / 100 ))"
cam_disk_file_name="/cam_disk.bin"
add_drive "cam" "CAM" "$cam_disk_size" "$cam_disk_file_name"
if [ "$campercent" -lt 100 ]
then
musicpercent="$(( 100 - $campercent ))"
music_disk_size="$(( $available_space * $musicpercent / 100 ))"
music_disk_file_name="/music_disk.bin"
add_drive "music" "MUSIC" "$music_disk_size" "$music_disk_file_name"
echo "options g_mass_storage file=$cam_disk_file_name,$music_disk_file_name removable=1,1 ro=0,0 stall=0 iSerialNumber=123456" > /etc/modprobe.d/g_mass_storage.conf
else
echo "options g_mass_storage file=$cam_disk_file_name removable=1 ro=0 stall=0 iSerialNumber=123456" > /etc/modprobe.d/g_mass_storage.conf
fi
function configure_hostname () {
echo "Configuring the hostname..."
local new_host_name="teslausb"
cp /etc/hosts ~
sed s/raspberrypi/teslausb/g ~/hosts > /etc/hosts
sed "s/raspberrypi/$new_host_name/g" ~/hosts > /etc/hosts
cp /etc/hostname ~
sed s/raspberrypi/teslausb/g ~/hostname > /etc/hostname
sed "s/raspberrypi/$new_host_name/g" ~/hostname > /etc/hostname
echo "Configured the hostname."
}
function make_root_fs_readonly () {
/tmp/make-root-fs-readonly.sh
}
echo "Verifying environment variables..."
check_variable "archiveserver"
check_variable "sharename"
check_variable "shareuser"
check_variable "sharepassword"
check_variable "campercent"
check_archive_server_reachable
check_available_space
get_ancillary_setup_scripts
pushd ~
configure_archive_scripts
fix_cmdline_txt_modules_load
echo "" >> /etc/fstab
create_usb_drive_backing_files
configure_archive
configure_rc_local
configure_hostname
make_root_fs_readonly
echo "All done."