Clean merge with master.

This commit is contained in:
Richard Goodwin
2018-10-17 09:52:45 -05:00
9 changed files with 270 additions and 80 deletions

BIN
.DS_Store vendored Normal file

Binary file not shown.

View File

@@ -29,6 +29,7 @@
``` ```
ssh pi@raspberrypi.local ssh pi@raspberrypi.local
``` ```
> Note: If you receive an error indicating that the host id has changed and you can't work around it you'll need to delete the ~\\.ssh\known_hosts file. You're especially likely to encounter this error if you're following these instructions for a second time.
1. If you get an "unknown host" error message install Bonjour: https://support.apple.com/kb/DL999 and go back to step 15. 1. If you get an "unknown host" error message install Bonjour: https://support.apple.com/kb/DL999 and go back to step 15.
1. You should be prompted for the password for the user "pi". Enter 1. You should be prompted for the password for the user "pi". Enter
``` ```

View File

@@ -6,3 +6,5 @@ Here are a few ways to accomplish this
* [Script to setup the Pi for connecting over USB](https://github.com/BigNate1234/rpi-USBSSH) * [Script to setup the Pi for connecting over USB](https://github.com/BigNate1234/rpi-USBSSH)
* (I.e. First write the OS image to the SD card, then this script will make the changes to the card so you can boot it and access it over the USB cable. * (I.e. First write the OS image to the SD card, then this script will make the changes to the card so you can boot it and access it over the USB cable.
* **Assumes the SD card for the Pi is mounted at /Volumes/boot , and that you can use `sh`/`bash`**. This _should_ be the default for a Mac; if using something else, modify the script accordingly. * **Assumes the SD card for the Pi is mounted at /Volumes/boot , and that you can use `sh`/`bash`**. This _should_ be the default for a Mac; if using something else, modify the script accordingly.
Be sure to delete the "init=/usr/lib/raspi-config/init_resize.sh" parameter from cmdline.txt to prevent the os partition from being expanded to fill the drive.

View File

@@ -75,7 +75,7 @@ There are four phases to setting up the Pi:
> Note: you don't need to uncompress the zip file you downloaded. > Note: you don't need to uncompress the zip file you downloaded.
### Get a shell on the Pi ### Get a shell on the Pi
If you have a monitor with an hdmi input, a mini hdmi to hdmi cable, a usb keyboard and a micro usb power cable you can hook up the devices to the Pi and configure it directly. If you have a monitor with an hdmi input, a mini hdmi to hdmi cable, a usb keyboard and a micro usb power cable you can hook up the devices to the Pi and configure it directly. Before you start those steps, ensure that the MicroSD card is in your computer and edit the cmdline.txt file to delete the parameter " init=/usr/lib/raspi-config/init_resize.sh".
1. Insert the MicroSD card into the Pi. 1. Insert the MicroSD card into the Pi.
1. Connect the keyboard, and monitor to the Pi. 1. Connect the keyboard, and monitor to the Pi.
1. Connect the power supply to the Pi using the port labeld "PWR" on the circuitboard. 1. Connect the power supply to the Pi using the port labeld "PWR" on the circuitboard.
@@ -158,3 +158,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,10 +1,11 @@
#!/bin/bash -eu #!/bin/bash -eu
TESLAUSB_REPO=cimryan REPO=cimryan
TESLAUSB_BRANCH=master BRANCH=master
user_enabled_pushover=false user_enabled_pushover=false
if [ "$(whoami)" != "root" ]
if ! [ $(id -u) = 0 ]
then then
echo "STOP: Run sudo -i." echo "STOP: Run sudo -i."
exit 1 exit 1
@@ -19,12 +20,6 @@ function check_variable () {
fi fi
} }
check_variable "archiveserver"
check_variable "sharename"
check_variable "shareuser"
check_variable "sharepassword"
check_variable "campercent"
function check_pushover_enabled () { function check_pushover_enabled () {
if [ ! -z "${pushover_enabled+x}" ] if [ ! -z "${pushover_enabled+x}" ]
then then
@@ -50,66 +45,97 @@ function check_pushover_enabled () {
check_pushover_enabled check_pushover_enabled
serverunreachable=false function check_archive_server_reachable () {
ping -c 1 -w 1 "$archiveserver" 1>/dev/null 2>&1 || serverunreachable=true 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 ] if [ "$serverunreachable" = true ]
then then
echo "STOP: The archive server $archiveserver is unreachable. Try specifying its IP address instead." echo "STOP: The archive server $archiveserver is unreachable. Try specifying its IP address instead."
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))"
if [ "$available_space" -lt 0 ]
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
} }
pushd ~ function check_available_space () {
echo "Verifying that there is sufficient space available on the MicroSD card..."
cp /boot/cmdline.txt ~ local available_space="$( parted -m /dev/mmcblk0 u b print free | tail -1 | cut -d ":" -f 4 | sed 's/B//g' )"
cat ~/cmdline.txt | sed 's/[[:space:]]\+modules-load=[^ [:space:]]\+//' | sed 's/rootwait/rootwait modules-load=dwc2/' > /boot/cmdline.txt
rm ~/cmdline.txt
mkdir /mnt/archive if [ "$available_space" -lt 4294967296 ]
then
echo "STOP: The MicroSD card is too small."
exit 1
fi
echo "" >> /etc/fstab echo "There is sufficient space available."
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 function get_ancillary_setup_scripts () {
echo "password=$sharepassword" >> /root/.teslaCamArchiveCredentials pushd /tmp
wget https://raw.githubusercontent.com/"$REPO"/teslausb/"$BRANCH"/windows_archive/create-backingfiles-partition.sh
chmod +x ./create-backingfiles-partition.sh
wget https://raw.githubusercontent.com/"$REPO"/teslausb/"$BRANCH"/windows_archive/create-backingfiles.sh
chmod +x ./create-backingfiles.sh
wget https://raw.githubusercontent.com/"$REPO"/teslausb/"$BRANCH"/windows_archive/make-root-fs-readonly.sh
chmod +x ./make-root-fs-readonly.sh
popd
}
mkdir /root/bin 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."
}
wget https://raw.githubusercontent.com/"$TESLAUSB_REPO"/teslausb/"$TESLAUSB_BRANCH"/windows_archive/archiveloop BACKINGFILES_MOUNTPOINT=/backingfiles
sed s/ARCHIVE_HOST_NAME=archiveserver/ARCHIVE_HOST_NAME=$archiveserver/ ~/archiveloop > /root/bin/archiveloop
rm ~/archiveloop
chmod +x /root/bin/archiveloop
pushd /root/bin function create_usb_drive_backing_files () {
wget https://raw.githubusercontent.com/"$TESLAUSB_REPO"/teslausb/"$TESLAUSB_BRANCH"/windows_archive/archive-teslacam-clips mkdir "$BACKINGFILES_MOUNTPOINT"
chmod +x archive-teslacam-clips /tmp/create-backingfiles-partition.sh "$BACKINGFILES_MOUNTPOINT"
popd
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
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
pushd ~
wget https://raw.githubusercontent.com/"$REPO"/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
popd
pushd /root/bin
wget https://raw.githubusercontent.com/"$REPO"/teslausb/"$BRANCH"/windows_archive/archive-teslacam-clips
chmod +x archive-teslacam-clips
popd
echo "Configured the archive scripts."
}
function configure_pushover_scripts() {
if [ ${user_enabled_pushover} = "true" ] if [ ${user_enabled_pushover} = "true" ]
then then
pushd /root/bin pushd /root/bin
@@ -117,9 +143,12 @@ then
chmod +x archive-teslacam-clips chmod +x archive-teslacam-clips
popd popd
fi fi
}
echo "#!/bin/bash -eu" > ~/rc.local function configure_rc_local () {
tail -n +2 /etc/rc.local | sed '$d' >> ~/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 cat << 'EOF' >> ~/rc.local
LOGFILE=/tmp/rc.local.log LOGFILE=/tmp/rc.local.log
@@ -134,26 +163,61 @@ log "All done"
exit 0 exit 0
EOF 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 ] local new_host_name="teslausb"
then cp /etc/hosts ~
musicpercent="$(( 100 - $campercent ))" sed "s/raspberrypi/$new_host_name/g" ~/hosts > /etc/hosts
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
cp /etc/hosts ~ cp /etc/hostname ~
sed s/raspberrypi/teslausb/g ~/hosts > /etc/hosts sed "s/raspberrypi/$new_host_name/g" ~/hostname > /etc/hostname
echo "Configured the hostname."
}
cp /etc/hostname ~ function make_root_fs_readonly () {
sed s/raspberrypi/teslausb/g ~/hostname > /etc/hostname /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_pushover_enabled
check_archive_server_reachable
check_available_space
get_ancillary_setup_scripts
pushd ~
configure_archive_scripts
configure_pushover_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."