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. Eject the drives.
1. Unplug the Pi from the PC. 1. Unplug the Pi from the PC.
1. Plug the Pi into your Tesla. 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 ..." Write-Verbose "Updating $cmdlinePath ..."
$cmdlinetxtContent = gc -Raw $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 ..." Write-Verbose "Enabling SSH ..."
[System.IO.File]::CreateText($sshPath).Dispose() [System.IO.File]::CreateText($sshPath).Dispose()

View File

@@ -1,6 +1,8 @@
#!/bin/bash -eu #!/bin/bash -eu
if [ "$(whoami)" != "root" ] BRANCH=master
if ! [ $(id -u) = 0 ]
then then
echo "STOP: Run sudo -i." echo "STOP: Run sudo -i."
exit 1 exit 1
@@ -15,13 +17,9 @@ function check_variable () {
fi fi
} }
check_variable "archiveserver" function check_archive_server_reachable () {
check_variable "sharename" echo "Verifying that the archive server $archiveserver is reachable..."
check_variable "shareuser" local serverunreachable=false
check_variable "sharepassword"
check_variable "campercent"
serverunreachable=false
ping -c 1 -w 1 "$archiveserver" 1>/dev/null 2>&1 || serverunreachable=true ping -c 1 -w 1 "$archiveserver" 1>/dev/null 2>&1 || serverunreachable=true
if [ "$serverunreachable" = true ] if [ "$serverunreachable" = true ]
@@ -30,57 +28,87 @@ then
exit 1 exit 1
fi 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 then
echo "STOP: The MicroSD card is too small." echo "STOP: The MicroSD card is too small."
exit 1 exit 1
fi fi
function add_drive () { echo "There is sufficient space available."
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
} }
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 ~ cp /boot/cmdline.txt ~
cat ~/cmdline.txt | sed 's/[[:space:]]\+modules-load=[^ [:space:]]\+//' | sed 's/rootwait/rootwait modules-load=dwc2/' > /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 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 mkdir /mnt/archive
local archive_server_ip_address="$(getent hosts $archiveserver | cut -d' ' -f1)"
echo "" >> /etc/fstab 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 "//$archiveserverip/$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 "username=$shareuser" > /root/.teslaCamArchiveCredentials
echo "password=$sharepassword" >> /root/.teslaCamArchiveCredentials echo "password=$sharepassword" >> /root/.teslaCamArchiveCredentials
echo "Configured the archive."
}
function configure_archive_scripts () {
echo "Configuring the archive scripts..."
mkdir /root/bin 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 sed s/ARCHIVE_HOST_NAME=archiveserver/ARCHIVE_HOST_NAME=$archiveserver/ ~/archiveloop > /root/bin/archiveloop
rm ~/archiveloop rm ~/archiveloop
chmod +x /root/bin/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 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 echo "#!/bin/bash -eu" > ~/rc.local
tail -n +2 /etc/rc.local | sed '$d' >> ~/rc.local tail -n +2 /etc/rc.local | sed '$d' >> ~/rc.local
cat << 'EOF' >> ~/rc.local cat << 'EOF' >> ~/rc.local
@@ -99,24 +127,55 @@ EOF
cat ~/rc.local > /etc/rc.local cat ~/rc.local > /etc/rc.local
rm ~/rc.local rm ~/rc.local
echo "Configured rc.local."
}
cam_disk_size="$(( $available_space * $campercent / 100 ))" function configure_hostname () {
cam_disk_file_name="/cam_disk.bin" echo "Configuring the hostname..."
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
local new_host_name="teslausb"
cp /etc/hosts ~ cp /etc/hosts ~
sed s/raspberrypi/teslausb/g ~/hosts > /etc/hosts sed "s/raspberrypi/$new_host_name/g" ~/hosts > /etc/hosts
cp /etc/hostname ~ 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."