mirror of
https://github.com/cimryan/teslausb.git
synced 2026-03-01 04:30:33 +00:00
cleaning up for master merge
This commit is contained in:
@@ -1,43 +0,0 @@
|
|||||||
# Setting up the Pi without a monitor using a Mac or Linux
|
|
||||||
|
|
||||||
You can setup the Pi to connect to your Wifi network, and also provide the option to connect over USB networking (Rasberry Pi Zero W or other recent Pi's).
|
|
||||||
|
|
||||||
|
|
||||||
**What is USB networking?**
|
|
||||||
Basically what you're doing is using the Pi's capability to emulate a network connection over USB. So you need to get the Pi (the guest) set up to load the proper modules to do so, and then connect from your machine (the host) using a shell (like iTerm+SSH on macOS). It's an alternative to Wifi if needed.
|
|
||||||
|
|
||||||
## Use the update script to setup Wifi and USB networking
|
|
||||||
|
|
||||||
A [script](https://raw.githubusercontent.com/cimryan/teslausb/master/mac_linux_archive/setup-piForHeadlessConfig.sh is provided to automatically update your SD card so the first time you boot it on your Pi, USB networking and Wifi will automatically be configured.
|
|
||||||
|
|
||||||
If you prefer not to run the script, it's also a useful reference for the steps you'll need to take.
|
|
||||||
|
|
||||||
> It's important you do these steps **before you boot the Pi the first time with the SD card inserted**.
|
|
||||||
|
|
||||||
1. Ensure you've flashed your Raspbian image to your SD card.
|
|
||||||
1. If the `boot` folder isn't showing on your computer, eject and re-insert the SD card into your computer, **not the Raspberry Pi**.
|
|
||||||
1. Change to the directory where the SD card's `boot` folder (containing `cmdline.txt`) is located. On a Mac, this will be `/Volumes/boot`. On Linux the location may vary.
|
|
||||||
1. Run the following commands:
|
|
||||||
```
|
|
||||||
wget https://raw.githubusercontent.com/cimryan/teslausb/master/mac_linux_archive/setup-piForHeadlessConfig.sh
|
|
||||||
chmod +x update-rpi-mac-linux.sh
|
|
||||||
```
|
|
||||||
1. Set your SSID (Wifi network name) and WIFIPASS environment variables. The script will insert them into the `wpa_supplicant.conf` when creating it:
|
|
||||||
|
|
||||||
```
|
|
||||||
export SSID=your_ssid_here
|
|
||||||
export WIFIPASS=your_wifi_password_here
|
|
||||||
```
|
|
||||||
1. Run the script:
|
|
||||||
`./update-rpi-mac-linux.sh`
|
|
||||||
1. If all goes well, the script will report:
|
|
||||||
`-- Files updated and ready for Wifi and SSH over USB --`
|
|
||||||
1. Eject the SD card safely, insert into your Pi, and reboot. If the Pi is connected over USB to your host, and/or if the Wifi setup went correctly, you should be able to `ssh pi@raspberrypi.local`. The default password is `raspberry`.
|
|
||||||
|
|
||||||
> Note: If you receive an error indicating that the host id has changed, edit your computer's `~/.ssh/known_hosts` file. Find the line with the IP address of your Pi, or labeled "raspberrypi.local" and delete the entire line. You're especially likely to encounter this error if you're following these instructions for a second time.
|
|
||||||
|
|
||||||
## Manual/other resources
|
|
||||||
|
|
||||||
* [Gist (text file) showing example steps to setup USB networking](https://gist.github.com/gbaman/975e2db164b3ca2b51ae11e45e8fd40a)
|
|
||||||
|
|
||||||
If manually configuring the Pi vs using the update script, 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.
|
|
||||||
65
README.md
65
README.md
@@ -50,19 +50,25 @@ Download and install:
|
|||||||
* [Etcher](http://etcher.io)
|
* [Etcher](http://etcher.io)
|
||||||
|
|
||||||
## Create your archive
|
## Create your archive
|
||||||
### Hosting on Windows
|
### Hosting on Windows File Shares, MacOS Sharing, or Samba on Linux
|
||||||
Set up a share on a Windows (or macOS using Sharing, or Linux using Samba) machine to host the archive. These instructions assume that you created a share named "SailfishCam" on the server "Nautilus". It is recommended that you create a new user. Grant the user you'll be using read/write access to the share. These instructions will assume that the user you've created is named "sailfish" and that the password for this user is "pa$$w0rd".
|
Set up a share to host the archive. These instructions assume that you created a share named "SailfishCam" on the server "Nautilus". It is recommended that you create a new user. Grant the user you'll be using read/write access to the share. These instructions will assume that the user you've created is named "sailfish" and that the password for this user is "pa$$w0rd".
|
||||||
|
|
||||||
Get the IP address of the archive machine. You'll need this later, so write it down, somewhere. You can do this by opening a command prompt on the archive machine and typing ipconfig. Get the IP address from the line labeled "IPv4 Address". These instructions will assume that the IP address of the archive server is 192.168.0.41.
|
Get the IP address of the archive machine. You'll need this later, so write it down, somewhere.
|
||||||
|
* On Windows you can do this by opening a command prompt on the archive machine and typing ipconfig. Get the IP address from the line labeled "IPv4 Address". These instructions will assume that the IP address of the archive server is 192.168.0.41.
|
||||||
|
* On MacOS or Linux open a terminal and type ifconfig.
|
||||||
|
|
||||||
### TODO Other hosting solutions
|
### Hosting via SFTP/rsync
|
||||||
|
**EXPERIMENTAL - Hosting the archive on SFTP hasn't been thoroughly tested**
|
||||||
|
|
||||||
|
Since sftp/rsync is accessing a computer through SSH, the only requirement for hosting an SFTP/rsync server is to have a box running Linux. An example can be another Raspberry Pi connected to your local network with a USB storage drive plugged in. The official Raspberry Pi site has a good example on [how to mount an external drive](https://www.raspberrypi.org/documentation/configuration/external-storage.md). You will need the username and host/IP of the storage server, as well as the path for the files to go in, and the storage server will need to allow SSH.
|
||||||
|
|
||||||
|
### ***TODO: Other hosting solutions***
|
||||||
|
|
||||||
## Set up the Raspberry Pi
|
## Set up the Raspberry Pi
|
||||||
There are four phases to setting up the Pi:
|
There are three phases to setting up the Pi:
|
||||||
1. Get the OS onto the micro sd card.
|
1. Get the OS onto the micro sd card.
|
||||||
1. Get a shell on the Pi.
|
1. Get a shell on the Pi.
|
||||||
1. Set up the USB storage functionality.
|
1. Set up the USB storage functionality.
|
||||||
1. Get the Pi set up for your Tesla.
|
|
||||||
|
|
||||||
### Get the OS onto the micro SD card
|
### Get the OS onto the micro SD card
|
||||||
|
|
||||||
@@ -72,14 +78,18 @@ 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 used a Windows computer to flash the OS onto the MicroSD card, follow these [Instructions](GetShellWithoutMonitorOnWindows.md).
|
If you used a Windows computer to flash the OS onto the MicroSD card, follow these [Instructions](doc/GetShellWithoutMonitorOnWindows.md).
|
||||||
If you used a Mac or a Linux computer, follow these [Instructions](GetShellWithoutMonitorOnLinux.md).
|
|
||||||
|
If you used a Mac or a Linux computer, follow these [Instructions](doc/GetShellWithoutMonitorOnLinux.md).
|
||||||
|
|
||||||
### Set up the USB storage functionality
|
### Set up the USB storage functionality
|
||||||
|
|
||||||
Now that you have Wifi up and running, it's time to set up the USB storage and scripts that will manage the dashcam and (optionally) music storage.
|
Now that you have Wifi up and running, it's time to set up the USB storage and scripts that will manage the dashcam and (optionally) music storage.
|
||||||
|
|
||||||
1. SSH to the Pi and run `sudo -i`
|
1. SSH to the Pi and run
|
||||||
|
```
|
||||||
|
sudo -i
|
||||||
|
```
|
||||||
1. Try to ping your archive server from the Pi. In this example the server is named `nautilus`.
|
1. Try to ping your archive server from the Pi. In this example the server is named `nautilus`.
|
||||||
```
|
```
|
||||||
ping -c 3 nautilus
|
ping -c 3 nautilus
|
||||||
@@ -89,47 +99,54 @@ Now that you have Wifi up and running, it's time to set up the USB storage and s
|
|||||||
ping 192.168.0.41
|
ping 192.168.0.41
|
||||||
```
|
```
|
||||||
1. If you can't ping the archive server by IP address from the Pi, you should go do whatever you need to on your network to fix that. If you can't reach the archive server by name, from the Pi but you can by IP address, then use its IP address, below, in place of its name.
|
1. If you can't ping the archive server by IP address from the Pi, you should go do whatever you need to on your network to fix that. If you can't reach the archive server by name, from the Pi but you can by IP address, then use its IP address, below, in place of its name.
|
||||||
1. Run these commands, subsituting your values. The last line is the percent of the drive you want to allocate for dashcam storage. The remaining percentage will be allocated for music.
|
1. Determine how much, as a percentage, of the drive you want to allocate to recording dashcam footage by using:
|
||||||
|
```
|
||||||
|
export campercent=<number>
|
||||||
|
```
|
||||||
|
For example, using `export campercent=100` would allocate 100% of the space to recording footage from your car, and would not create a separate music partition. `export campercent=50` would be only allocate half of the space for a dashcam footage drive, and allocates the other half to be a music storage drive.
|
||||||
|
1. If you are trying to archive on an SFTP/rsync server, then follow these [instructions](doc/SetupRSync.md) and skip step 7. Otherwise, skip this step.
|
||||||
|
1. If you are trying to archive on a shared drive, run these commands, subsituting your values for your shared drive:
|
||||||
```
|
```
|
||||||
export archiveserver=Nautilus
|
export archiveserver=Nautilus
|
||||||
export sharename=SailfishCam
|
export sharename=SailfishCam
|
||||||
export shareuser=sailfish
|
export shareuser=sailfish
|
||||||
export sharepassword=pa$$w0rd
|
export sharepassword=pa$$w0rd
|
||||||
export campercent=100
|
|
||||||
```
|
```
|
||||||
1. If you'd like to receive a text message when your Pi finishes archiving clips follow these [Instructions](ConfigureNotificationsForArchive.md).
|
1. If you'd like to receive a text message when your Pi finishes archiving clips follow these [Instructions](doc/ConfigureNotificationsForArchive.md).
|
||||||
1. Run these commands:
|
1. Run these commands:
|
||||||
```
|
```
|
||||||
wget https://raw.githubusercontent.com/cimryan/teslausb/master/windows_archive/setup-teslausb
|
wget https://raw.githubusercontent.com/cimryan/teslausb/master/setup/pi/setup-teslausb
|
||||||
chmod +x setup-teslausb
|
chmod +x setup-teslausb
|
||||||
./setup-teslausb
|
./setup-teslausb
|
||||||
```
|
```
|
||||||
1. Run this command:
|
1. Run this command:
|
||||||
```
|
```
|
||||||
reboot
|
halt
|
||||||
```
|
```
|
||||||
|
1. Disconnect the Pi from the computer.
|
||||||
|
|
||||||
After reboot, the Pi hostname will become `teslausb`, so future `ssh` sessions will be `ssh pi@teslausb.local`.
|
On the next boot, the Pi hostname will become `teslausb`, so future `ssh` sessions will be `ssh pi@teslausb.local`.
|
||||||
|
|
||||||
### Get the Pi set up for your Tesla.
|
Your Pi is now ready to be plugged into your Tesla. If you want to add music to the Pi, follow the instructions in the next section.
|
||||||
If you set up the Pi with a keyboard and a monitor disconnect it and connect it to a PC. If you're using a cable be sure to use the port labeled "USB" on the circuitboard.
|
|
||||||
1. Wait for the Pi to show up on the PC as a USB drive.
|
## (Optional) Add music to the Pi
|
||||||
1. Create a directory named TeslaCam at the root of the drive labeled CAM.
|
Connect the Pi to a computer. If you're using a cable be sure to use the port labeled "USB" on the circuitboard.
|
||||||
|
1. Wait for the Pi to show up on the computer as a USB drive.
|
||||||
1. Copy any music you'd like to the drive labeled MUSIC.
|
1. Copy any music you'd like to the drive labeled MUSIC.
|
||||||
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
|
## 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
|
The setup process configures the Pi with read-only file systems for the operating system but with read-write
|
||||||
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
|
access through the USB interface. This means that you'll be able to record dashcam video and add and remove
|
||||||
to files on / or on /boot. This is to protect against corruption of the operating system when the Tesla cuts power to the Pi.
|
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:
|
To make changes to the system partitions:
|
||||||
```
|
```
|
||||||
ssh pi@teslausb.
|
ssh pi@teslausb.
|
||||||
sudo -i
|
sudo -i
|
||||||
mount / -o remount,rw
|
/root/bin/remountfs_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.
|
Then make whatever changes you need to. The next time the system boots the partitions will once again be read-only.
|
||||||
|
|||||||
35
doc/GetShellWithoutMonitorOnLinux.md
Normal file
35
doc/GetShellWithoutMonitorOnLinux.md
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
# Getting a shell on the Pi without a monitor using a Mac or Linux
|
||||||
|
|
||||||
|
These instructions will configure a Raspberry Pi so that you can proceed with the next step of setting it up as a smart USB drive for your Tesla. Specifically, these intructions will configure your Pi to join your wireless network and also enable you to ssh to the Pi, either over your wireless network or through a USB connection.
|
||||||
|
|
||||||
|
**Important:** Do these steps before you boot the Pi for the first time.
|
||||||
|
|
||||||
|
1. Ensure you've flashed your Raspbian image to your SD card.
|
||||||
|
1. If the `boot` folder isn't showing on your computer, eject and re-insert the SD card into your computer, **not the Raspberry Pi**.
|
||||||
|
1. Change to the directory where the SD card's `boot` folder (containing `cmdline.txt`) is located. On a Mac, this will be `/Volumes/boot`. On Linux the location may vary; on recent Ubuntu installations it will be /media/$USER/boot
|
||||||
|
1. Run the following commands:
|
||||||
|
```
|
||||||
|
wget https://raw.githubusercontent.com/cimryan/teslausb/master/setup/macos_linux/setup-piForHeadlessConfig.sh
|
||||||
|
chmod +x setup-piForHeadlessConfig.sh
|
||||||
|
```
|
||||||
|
1. Set your SSID (Wifi network name) and WIFIPASS environment variables. The script will insert them into the `wpa_supplicant.conf` when creating it:
|
||||||
|
```
|
||||||
|
export SSID=your_ssid_here
|
||||||
|
export WIFIPASS=your_wifi_password_here
|
||||||
|
```
|
||||||
|
1. If you're using a Mac, run this command
|
||||||
|
```
|
||||||
|
./setup-piForHeadlessConfig.sh /Volumes/boot
|
||||||
|
```
|
||||||
|
1. If you're using Ubuntu, run this command:
|
||||||
|
```
|
||||||
|
./setup-piForHeadlessConfig.sh /media/$USER/boot
|
||||||
|
```
|
||||||
|
> If you're using another Linux distribution figure out the path to where the boot partitio of the SD card is mounted and specify that path, instead.
|
||||||
|
1. If all goes well, the script will report:
|
||||||
|
```
|
||||||
|
-- Files updated and ready for Wifi and SSH over USB --
|
||||||
|
```
|
||||||
|
1. Eject the SD card safely, insert into your Pi, and reboot. If the Pi is connected over USB to your host, and/or if the Wifi setup went correctly, you should be able to `ssh pi@raspberrypi.local`. The default password is `raspberry`.
|
||||||
|
|
||||||
|
> Note: If you receive an error indicating that the host id has changed, edit your computer's `~/.ssh/known_hosts` file. Find the line with the IP address of your Pi, or labeled "raspberrypi.local" and delete the entire line. You're especially likely to encounter this error if you're following these instructions for a second time.
|
||||||
@@ -14,12 +14,18 @@
|
|||||||
1. Run the following commands:
|
1. Run the following commands:
|
||||||
```
|
```
|
||||||
cd ~
|
cd ~
|
||||||
wget https://raw.githubusercontent.com/cimryan/teslausb/master/windows_archive/setup-piForHeadlessConfig.ps1 -OutFile setup-piForHeadlessConfig.ps1
|
wget https://raw.githubusercontent.com/cimryan/teslausb/master/setup/windows/setup-piForHeadlessConfig.ps1 -OutFile setup-piForHeadlessConfig.ps1
|
||||||
./setup-piForHeadlessConfig.ps1 -Verbose
|
./setup-piForHeadlessConfig.ps1 -Verbose
|
||||||
```
|
```
|
||||||
1. Enter the single letter of the "boot" drive and press Enter.
|
1. Enter the single letter of the "boot" drive and press Enter.
|
||||||
1. Enter the SSID of your WiFi network and press Enter.
|
1. Enter the SSID of your WiFi network and press Enter.
|
||||||
1. Enter the Pre-Shared Key of your WiFi network and press Enter.
|
1. Enter the Pre-Shared Key of your WiFi network and press Enter.
|
||||||
|
1. If you want to add additional WiFi networks, execute:
|
||||||
|
```
|
||||||
|
./add-wifi.ps1 -Verbose
|
||||||
|
```
|
||||||
|
1. If you will use any public or insecure networks, be sure to update your password using the instructions at the end of this document.
|
||||||
|
1. Enter the additional SSID and Pre-Shared Key of the WiFi network and repeat as necessary.
|
||||||
1. Eject the sd card.
|
1. Eject the sd card.
|
||||||
1. Move the sd card to the Pi.
|
1. Move the sd card to the Pi.
|
||||||
1. Connect a micro usb cable to the port labeled "USB" on the Raspberry Pi, and to the PC.
|
1. Connect a micro usb cable to the port labeled "USB" on the Raspberry Pi, and to the PC.
|
||||||
@@ -37,3 +43,17 @@
|
|||||||
```
|
```
|
||||||
raspberry
|
raspberry
|
||||||
```
|
```
|
||||||
|
1. Change your password! While not required, it is recommended, especially if you may be using any public or insecure WiFi connections. To do so Enter
|
||||||
|
```
|
||||||
|
passwd
|
||||||
|
```
|
||||||
|
1. Then enter your new password and press Enter
|
||||||
|
1. Confirm your new password and press Enter
|
||||||
|
1. If you want to change your password later, you must set the system partition to writeable with either
|
||||||
|
```
|
||||||
|
/root/bin/remountfs_rw
|
||||||
|
```
|
||||||
|
1. or
|
||||||
|
```
|
||||||
|
mount / -o remount,rw
|
||||||
|
```
|
||||||
43
doc/SetupRSync.md
Normal file
43
doc/SetupRSync.md
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
# Introduction
|
||||||
|
This guide will show you how to utilize [rsync](https://rsync.samba.org/) to archive your saved TeslaCam footage on a remote storage server. In my case, I use this for a networked pi storage server.
|
||||||
|
|
||||||
|
This guide makes the following assumptions:
|
||||||
|
1. You are running your own ftp/rsync server that you have admin rights to, or can at least add a public key to its `~/.ssh/authorized_keys` file
|
||||||
|
1. The ftp/rsync server has rsync installed (raspbian automatically does)
|
||||||
|
2. You have **NOT** run the `setup-teslacam` script yet
|
||||||
|
# Step 1: Authentication
|
||||||
|
Similar to sftp, rsync by default utilizes ssh to connect to a remote server and transfer files. This guide will use a generated ssh keypair, hence the first assumption above.
|
||||||
|
|
||||||
|
1. On your teslausb pi, run `ssh-keygen` to generate an ssh key **for the ROOT user!** If you followed the previous steps, you should have already ran `sudo -i` to become the root user on the telsausb pi. If you didn't, run `sudo -i` and re-run `ssh-keygen`. You can be sure that it is generating for root if it asks to store the key in `/root/.ssh/` (versus something like `/home/pi/.ssh`).
|
||||||
|
|
||||||
|
1. Add the contents of the newly generated `/root/.ssh/id_rsa.pub` file from your teslausb pi to the storage server's `~/.ssh/authorized_keys` file. This will allow a nice and easy connection through rsync, no passwords needed!
|
||||||
|
|
||||||
|
1. Lastly, you will need to authorize the connection to the FTP/Rsync server and test that the key works, so try connecting to the server (through ssh), and **if it asks if you wish to continue connecting, make sure to type `yes`!** If you do not do this, rsync will fail to connect and thus fail to archive your clips.
|
||||||
|
|
||||||
|
# Step 2: Exports
|
||||||
|
To be able to configure the teslausb pi use rsync, you'll need to export a few things. On your teslausb pi, run:
|
||||||
|
|
||||||
|
```
|
||||||
|
export RSYNC_ENABLE=true
|
||||||
|
export RSYNC_USER=<ftp username>
|
||||||
|
export RSYNC_SERVER=<ftp IP/host>
|
||||||
|
export RSYNC_PATH=<destination path to save in>
|
||||||
|
```
|
||||||
|
|
||||||
|
Explanations for each:
|
||||||
|
* `RSYNC_ENABLE`: `true` for enabling rsync
|
||||||
|
* `RSYNC_USER`: The user on the FTP server
|
||||||
|
* `RSYNC_SERVER`: The IP address/hostname of the destination machine
|
||||||
|
* `RSYNC_PATH`: The path on the destination machine where the files will be saved
|
||||||
|
|
||||||
|
An example (of my) config is listed below:
|
||||||
|
|
||||||
|
```
|
||||||
|
export RSYNC_ENABLE=true
|
||||||
|
export RSYNC_USER=pi
|
||||||
|
export RSYNC_SERVER=192.168.1.254
|
||||||
|
export RSYNC_PATH=/mnt/PIHDD/TeslaCam/
|
||||||
|
```
|
||||||
|
***Note: RSYNC_ENABLE=true is going to disable the default archive server. Perhaps future releases will allow both to be defined and function at the same time, for redundancy, but for now just pick one that you'll want the most.***
|
||||||
|
|
||||||
|
You should be ready to run the setup script now, so return back to step 8 of the [Main Instructions](README.md).
|
||||||
262
run/archiveloop
Normal file
262
run/archiveloop
Normal file
@@ -0,0 +1,262 @@
|
|||||||
|
#!/bin/bash -eu
|
||||||
|
ARCHIVE_HOST_NAME="$1"
|
||||||
|
|
||||||
|
export LOG_FILE=/tmp/archiveloop.log
|
||||||
|
|
||||||
|
export CAM_MOUNT=/mnt/cam
|
||||||
|
export MUSIC_MOUNT=/mnt/music
|
||||||
|
export ARCHIVE_MOUNT=/mnt/archive
|
||||||
|
|
||||||
|
function log () {
|
||||||
|
echo "$( date )" >> "$LOG_FILE"
|
||||||
|
echo "$1" >> "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
function fix_errors_in_mount_point () {
|
||||||
|
local mount_point="$1"
|
||||||
|
log "Running fsck on $mount_point..."
|
||||||
|
/sbin/fsck "$mount_point" -- -a >> "$LOG_FILE" 2>&1 || echo ""
|
||||||
|
log "Finished fsck on $mount_point."
|
||||||
|
}
|
||||||
|
|
||||||
|
function fix_errors_in_mounted_files () {
|
||||||
|
fix_errors_in_mount_point "$CAM_MOUNT"
|
||||||
|
fix_errors_in_mount_point "$MUSIC_MOUNT"
|
||||||
|
}
|
||||||
|
|
||||||
|
function archive_is_reachable () {
|
||||||
|
local reachable=true
|
||||||
|
ping -q -w 1 -c 1 "$ARCHIVE_HOST_NAME" > /dev/null 2>&1 || reachable=false
|
||||||
|
if [ "$reachable" = false ]
|
||||||
|
then
|
||||||
|
false
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
function connect_usb_drives_to_host() {
|
||||||
|
log "Connecting usb to host..."
|
||||||
|
modprobe g_mass_storage
|
||||||
|
log "Connected usb to host."
|
||||||
|
}
|
||||||
|
|
||||||
|
function wait_for_archive_to_be_reachable () {
|
||||||
|
log "Waiting for archive to be reachable..."
|
||||||
|
while [ true ]
|
||||||
|
do
|
||||||
|
if archive_is_reachable
|
||||||
|
then
|
||||||
|
log "Archive is reachable."
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if [ -e /tmp/archive_is_reachable ]
|
||||||
|
then
|
||||||
|
log "Simulating archive is reachable"
|
||||||
|
rm /tmp/archive_is_reachable
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function retry () {
|
||||||
|
local attempts=0
|
||||||
|
while [ true ]
|
||||||
|
do
|
||||||
|
if eval "$@"
|
||||||
|
then
|
||||||
|
true
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
if [ "$attempts" -ge 10 ]
|
||||||
|
then
|
||||||
|
log "Attempts exhausted."
|
||||||
|
false
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
log "Sleeping before retry..."
|
||||||
|
/bin/sleep 1
|
||||||
|
attempts=$((attempts + 1))
|
||||||
|
log "Retrying..."
|
||||||
|
done
|
||||||
|
false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
function mount_mountpoint () {
|
||||||
|
local mount_point="$1"
|
||||||
|
log "Mounting $mount_point..."
|
||||||
|
|
||||||
|
local mounted=true
|
||||||
|
mount "$mount_point" >> "$LOG_FILE" 2>&1 || mounted=false
|
||||||
|
if [ "$mounted" = true ]
|
||||||
|
then
|
||||||
|
log "Mounted $mount_point."
|
||||||
|
true
|
||||||
|
return
|
||||||
|
else
|
||||||
|
log "Failed to mount $mount_point."
|
||||||
|
false
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensure_mountpoint_is_mounted () {
|
||||||
|
local mount_point="$1"
|
||||||
|
local mount_exists=true
|
||||||
|
|
||||||
|
findmnt --mountpoint "$mount_point" > /dev/null || mount_exists=false
|
||||||
|
|
||||||
|
if [ "$mount_exists" = true ]
|
||||||
|
then
|
||||||
|
log "$mount_point is already mounted."
|
||||||
|
else
|
||||||
|
mount_mountpoint "$mount_point"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensure_mountpoint_is_mounted_with_retry () {
|
||||||
|
retry ensure_mountpoint_is_mounted "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
function fix_errors_in_cam_file () {
|
||||||
|
fix_errors_in_mount_point "$CAM_MOUNT"
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensure_cam_file_is_mounted () {
|
||||||
|
log "Ensuring cam file is mounted..."
|
||||||
|
ensure_mountpoint_is_mounted_with_retry "$CAM_MOUNT"
|
||||||
|
log "Ensured cam file is mounted."
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensure_music_file_is_mounted () {
|
||||||
|
log "Ensuring music backing file is mounted..."
|
||||||
|
ensure_mountpoint_is_mounted_with_retry "$MUSIC_MOUNT"
|
||||||
|
log "Ensured cam drive is mounted."
|
||||||
|
}
|
||||||
|
|
||||||
|
function unmount_mount_point () {
|
||||||
|
local mount_point="$1"
|
||||||
|
log "Unmounting $mount_point..."
|
||||||
|
umount "$mount_point" >> "$LOG_FILE" 2>&1
|
||||||
|
log "Unmounted $mount_point."
|
||||||
|
}
|
||||||
|
|
||||||
|
function unmount_cam_file () {
|
||||||
|
unmount_mount_point "$CAM_MOUNT"
|
||||||
|
}
|
||||||
|
|
||||||
|
function unmount_music_file () {
|
||||||
|
unmount_mount_point "$MUSIC_MOUNT"
|
||||||
|
}
|
||||||
|
|
||||||
|
function fix_errors_in_music_file () {
|
||||||
|
fix_errors_in_mount_point "$MUSIC_MOUNT"
|
||||||
|
}
|
||||||
|
|
||||||
|
function wait_for_archive_to_be_unreachable () {
|
||||||
|
log "Waiting for archive to be unreachable..."
|
||||||
|
while [ true ]
|
||||||
|
do
|
||||||
|
if ! archive_is_reachable
|
||||||
|
then
|
||||||
|
log "Archive is unreachable."
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
if [ -e /tmp/archive_is_unreachable ]
|
||||||
|
then
|
||||||
|
log "Simulating archive being unreachable."
|
||||||
|
rm /tmp/archive_is_unreachable
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
sleep 1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
function mount_and_fix_errors_in_cam_file () {
|
||||||
|
ensure_cam_file_is_mounted
|
||||||
|
fix_errors_in_cam_file
|
||||||
|
unmount_cam_file
|
||||||
|
}
|
||||||
|
|
||||||
|
function mount_and_fix_errors_in_music_file () {
|
||||||
|
if [ -e "$MUSIC_MOUNT" ]
|
||||||
|
then
|
||||||
|
ensure_music_file_is_mounted
|
||||||
|
fix_errors_in_music_file
|
||||||
|
unmount_music_file
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
function mount_and_fix_errors_in_files () {
|
||||||
|
mount_and_fix_errors_in_cam_file
|
||||||
|
mount_and_fix_errors_in_music_file
|
||||||
|
}
|
||||||
|
|
||||||
|
function disconnect_usb_drives_from_host () {
|
||||||
|
log "Disconnecting usb from host..."
|
||||||
|
modprobe -r g_mass_storage
|
||||||
|
log "Disconnected usb from host."
|
||||||
|
}
|
||||||
|
|
||||||
|
function archive_teslacam_clips () {
|
||||||
|
log "Starting..."
|
||||||
|
|
||||||
|
/root/bin/connect-archive.sh
|
||||||
|
|
||||||
|
disconnect_usb_drives_from_host
|
||||||
|
|
||||||
|
ensure_cam_file_is_mounted
|
||||||
|
|
||||||
|
fix_errors_in_cam_file
|
||||||
|
|
||||||
|
/root/bin/archive-clips.sh
|
||||||
|
|
||||||
|
/root/bin/disconnect-archive.sh
|
||||||
|
|
||||||
|
unmount_cam_file
|
||||||
|
|
||||||
|
connect_usb_drives_to_host
|
||||||
|
}
|
||||||
|
|
||||||
|
function archive_clips () {
|
||||||
|
log "Archiving..."
|
||||||
|
if archive_teslacam_clips
|
||||||
|
then
|
||||||
|
log "Finished archiving."
|
||||||
|
else
|
||||||
|
log "Archiving failed."
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
export -f mount_mountpoint
|
||||||
|
export -f ensure_mountpoint_is_mounted
|
||||||
|
export -f retry
|
||||||
|
export -f ensure_mountpoint_is_mounted_with_retry
|
||||||
|
export -f log
|
||||||
|
|
||||||
|
log "Starting..."
|
||||||
|
|
||||||
|
if archive_is_reachable
|
||||||
|
then
|
||||||
|
# archive_clips will fix errors in the cam file
|
||||||
|
mount_and_fix_errors_in_music_file
|
||||||
|
|
||||||
|
archive_clips
|
||||||
|
|
||||||
|
wait_for_archive_to_be_unreachable
|
||||||
|
else
|
||||||
|
mount_and_fix_errors_in_files
|
||||||
|
|
||||||
|
connect_usb_drives_to_host
|
||||||
|
fi
|
||||||
|
|
||||||
|
while [ true ]
|
||||||
|
do
|
||||||
|
wait_for_archive_to_be_reachable
|
||||||
|
|
||||||
|
archive_clips
|
||||||
|
|
||||||
|
wait_for_archive_to_be_unreachable
|
||||||
|
done
|
||||||
24
run/cifs_archive/archive-clips.sh
Normal file
24
run/cifs_archive/archive-clips.sh
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#!/bin/bash -eu
|
||||||
|
|
||||||
|
log "Moving clips to archive..."
|
||||||
|
|
||||||
|
NUM_FILES_MOVED=0
|
||||||
|
|
||||||
|
for file_name in "$CAM_MOUNT"/TeslaCam/saved*; do
|
||||||
|
[ -e "$file_name" ] || continue
|
||||||
|
log "Moving $file_name ..."
|
||||||
|
|
||||||
|
if mv -f -t "$ARCHIVE_MOUNT" -- "$file_name" >> "$LOG_FILE" 2>&1
|
||||||
|
then
|
||||||
|
log "Moved $file_name."
|
||||||
|
NUM_FILES_MOVED=$((NUM_FILES_MOVED + 1))
|
||||||
|
else
|
||||||
|
log "Failed to move $file_name."
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
log "Moved $NUM_FILES_MOVED file(s)."
|
||||||
|
|
||||||
|
/root/bin/send-pushover "$NUM_FILES_MOVED"
|
||||||
|
|
||||||
|
log "Finished moving clips to archive."
|
||||||
26
run/cifs_archive/configure-archive.sh
Normal file
26
run/cifs_archive/configure-archive.sh
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#!/bin/bash -eu
|
||||||
|
|
||||||
|
function configure_archive () {
|
||||||
|
local archive_server_ip_address="$1"
|
||||||
|
|
||||||
|
echo "Configuring the archive..."
|
||||||
|
|
||||||
|
local archive_path="/mnt/archive"
|
||||||
|
|
||||||
|
if [ ! -e "$archive_path" ]
|
||||||
|
then
|
||||||
|
mkdir "$archive_path"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local credentials_file_path="/root/.teslaCamArchiveCredentials"
|
||||||
|
|
||||||
|
/root/bin/write-archive-credentials-to.sh "$credentials_file_path"
|
||||||
|
|
||||||
|
echo "//$archive_server_ip_address/$sharename $archive_path cifs vers=${cifs_version},credentials=${credentials_file_path},iocharset=utf8,file_mode=0777,dir_mode=0777 0" >> /etc/fstab
|
||||||
|
|
||||||
|
echo "Configured the archive."
|
||||||
|
}
|
||||||
|
|
||||||
|
ARCHIVE_SERVER_IP_ADDRESS="$( /root/bin/get-archiveserver-ip-address.sh )"
|
||||||
|
|
||||||
|
configure_archive "$ARCHIVE_SERVER_IP_ADDRESS"
|
||||||
9
run/cifs_archive/connect-archive.sh
Normal file
9
run/cifs_archive/connect-archive.sh
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/bin/bash -eu
|
||||||
|
|
||||||
|
function ensure_archive_is_mounted () {
|
||||||
|
log "Ensuring cam archive is mounted..."
|
||||||
|
ensure_mountpoint_is_mounted_with_retry "$ARCHIVE_MOUNT"
|
||||||
|
log "Ensured cam archive is mounted."
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_archive_is_mounted
|
||||||
2
run/cifs_archive/disconnect-archive.sh
Normal file
2
run/cifs_archive/disconnect-archive.sh
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/bash -eu
|
||||||
|
# Nothing to do. It's okay to leave the archive mounted.
|
||||||
49
run/cifs_archive/verify-archive-configuration.sh
Normal file
49
run/cifs_archive/verify-archive-configuration.sh
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
#!/bin/bash -eu
|
||||||
|
|
||||||
|
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 ]
|
||||||
|
then
|
||||||
|
echo "STOP: The archive server $archiveserver is unreachable. Try specifying its IP address instead."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "The archive server is reachable."
|
||||||
|
}
|
||||||
|
|
||||||
|
function check_archive_mountable () {
|
||||||
|
local archive_server_ip_address="$1"
|
||||||
|
|
||||||
|
local test_mount_location="/tmp/archivetestmount"
|
||||||
|
|
||||||
|
if [ ! -e "$test_mount_location" ]
|
||||||
|
then
|
||||||
|
mkdir "$test_mount_location"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local tmp_credentials_file_path="/tmp/teslaCamArchiveCredentials"
|
||||||
|
|
||||||
|
/root/bin/write-archive-credentials-to.sh "$tmp_credentials_file_path"
|
||||||
|
|
||||||
|
local mount_failed=false
|
||||||
|
mount -t cifs "//$archive_server_ip_address/$sharename" "$test_mount_location" -o "vers=${cifs_version},credentials=${tmp_credentials_file_path},iocharset=utf8,file_mode=0777,dir_mode=0777" || mount_failed=true
|
||||||
|
|
||||||
|
if [ "$mount_failed" = true ]
|
||||||
|
then
|
||||||
|
echo "STOP: The archive couldn't be mounted with CIFS version ${cifs_version}. Try specifying a lower number for the CIFS version like this:"
|
||||||
|
echo " export cifs_version=2.1"
|
||||||
|
echo "Other versions you can try are 2.0 and 1.0"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
umount "$test_mount_location"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_archive_server_reachable
|
||||||
|
|
||||||
|
ARCHIVE_SERVER_IP_ADDRESS="$( /root/bin/get-archiveserver-ip-address.sh )"
|
||||||
|
|
||||||
|
check_archive_mountable "$ARCHIVE_SERVER_IP_ADDRESS"
|
||||||
6
run/cifs_archive/write-archive-credentials-to.sh
Normal file
6
run/cifs_archive/write-archive-credentials-to.sh
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash -eu
|
||||||
|
|
||||||
|
FILE_PATH="$1"
|
||||||
|
|
||||||
|
echo "username=$shareuser" > "$FILE_PATH"
|
||||||
|
echo "password=$sharepassword" >> "$FILE_PATH"
|
||||||
3
run/get-archiveserver-ip-address.sh
Normal file
3
run/get-archiveserver-ip-address.sh
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#!/bin/bash -eu
|
||||||
|
|
||||||
|
echo "$(ping -c 1 -w 1 $archiveserver 2>/dev/null | head -n 1 | grep -o -e "(\([[:digit:]]\{1,3\}\.\)\{3\}[[:digit:]]\{1,3\})" | tr -d '()')"
|
||||||
16
run/rsync_archive/archive-clips.sh
Normal file
16
run/rsync_archive/archive-clips.sh
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash -eu
|
||||||
|
|
||||||
|
log "Archiving through rsync..."
|
||||||
|
|
||||||
|
source /root/.teslaCamRsyncConfig
|
||||||
|
|
||||||
|
num_files_moved=$(rsync -auvh --stats --log-file=/tmp/archive-rsync-cmd.log /mnt/cam/TeslaCam/saved* $user@$server:$path | awk '/files transferred/{print $NF}')
|
||||||
|
|
||||||
|
/root/bin/send-pushover "$num_files_moved"
|
||||||
|
|
||||||
|
if [ $num_files_moved > 0 ]
|
||||||
|
then
|
||||||
|
log "Successfully synced files through rsync."
|
||||||
|
else
|
||||||
|
log "No files to archive through rsync."
|
||||||
|
fi
|
||||||
16
run/rsync_archive/configure-archive.sh
Normal file
16
run/rsync_archive/configure-archive.sh
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#!/bin/bash -eu
|
||||||
|
|
||||||
|
function configure_archive () {
|
||||||
|
local archive_server_ip_address="$1"
|
||||||
|
|
||||||
|
echo "Configuring the archive..."
|
||||||
|
|
||||||
|
echo "Configuring for Rsync..."
|
||||||
|
echo "user=$RSYNC_USER" > /root/.teslaCamRsyncConfig
|
||||||
|
echo "server=$RSYNC_SERVER" >> /root/.teslaCamRsyncConfig
|
||||||
|
echo "path=$RSYNC_PATH" >> /root/.teslaCamRsyncConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
ARCHIVE_SERVER_IP_ADDRESS="$( /root/bin/get-archiveserver-ip-address.sh )"
|
||||||
|
|
||||||
|
configure_archive "$ARCHIVE_SERVER_IP_ADDRESS"
|
||||||
2
run/rsync_archive/connect-archive.sh
Normal file
2
run/rsync_archive/connect-archive.sh
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/bash -eu
|
||||||
|
# Nothing to do.
|
||||||
2
run/rsync_archive/disconnect-archive.sh
Normal file
2
run/rsync_archive/disconnect-archive.sh
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
#!/bin/bash -eu
|
||||||
|
# Nothing to do.
|
||||||
1
run/rsync_archive/verify-archive-configuration.sh
Normal file
1
run/rsync_archive/verify-archive-configuration.sh
Normal file
@@ -0,0 +1 @@
|
|||||||
|
#!/bin/bash -eu
|
||||||
21
run/send-pushover
Normal file
21
run/send-pushover
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#!/bin/bash -eu
|
||||||
|
|
||||||
|
NUM_FILES_MOVED="$1"
|
||||||
|
|
||||||
|
function log () {
|
||||||
|
echo "$( date )" >> "$LOG_FILE"
|
||||||
|
echo "$1" >> "$LOG_FILE"
|
||||||
|
}
|
||||||
|
|
||||||
|
if [ -r "/root/.teslaCamPushoverCredentials" ] && [ $NUM_FILES_MOVED > 0 ]
|
||||||
|
then
|
||||||
|
log "Sending Pushover message for moved files."
|
||||||
|
|
||||||
|
source /root/.teslaCamPushoverCredentials
|
||||||
|
|
||||||
|
curl -F "token=$pushover_app_key" \
|
||||||
|
-F "user=$pushover_user_key" \
|
||||||
|
-F "title=Dashcam Copy Complete" \
|
||||||
|
-F "message=$NUM_FILES_MOVED file(s) were copied." \
|
||||||
|
https://api.pushover.net/1/messages
|
||||||
|
fi
|
||||||
0
mac_linux_archive/setup-piForHeadlessConfig.sh → setup/macos_linux/setup-piForHeadlessConfig.sh
Executable file → Normal file
0
mac_linux_archive/setup-piForHeadlessConfig.sh → setup/macos_linux/setup-piForHeadlessConfig.sh
Executable file → Normal file
@@ -21,7 +21,13 @@ function add_drive () {
|
|||||||
echo "$filename $mountpoint vfat noauto,users,umask=000 0 0" >> /etc/fstab
|
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)"
|
function create_teslacam_directory () {
|
||||||
|
mount /mnt/cam
|
||||||
|
mkdir /mnt/cam/TeslaCam
|
||||||
|
umount /mnt/cam
|
||||||
|
}
|
||||||
|
|
||||||
|
FREE_1K_BLOCKS="$(df --output=avail --block-size=1K $BACKINGFILES_MOUNTPOINT/ | tail -n 1)"
|
||||||
|
|
||||||
CAM_DISK_SIZE="$(( $FREE_1K_BLOCKS * $CAM_PERCENT / 100 ))"
|
CAM_DISK_SIZE="$(( $FREE_1K_BLOCKS * $CAM_PERCENT / 100 ))"
|
||||||
CAM_DISK_FILE_NAME="$BACKINGFILES_MOUNTPOINT/cam_disk.bin"
|
CAM_DISK_FILE_NAME="$BACKINGFILES_MOUNTPOINT/cam_disk.bin"
|
||||||
@@ -29,10 +35,12 @@ add_drive "cam" "CAM" "$CAM_DISK_SIZE" "$CAM_DISK_FILE_NAME"
|
|||||||
|
|
||||||
if [ "$CAM_PERCENT" -lt 100 ]
|
if [ "$CAM_PERCENT" -lt 100 ]
|
||||||
then
|
then
|
||||||
MUSIC_DISK_SIZE="$(df --output=avail --block-size=1K /backingfiles/ | tail -n 1)"
|
MUSIC_DISK_SIZE="$(df --output=avail --block-size=1K $BACKINGFILES_MOUNTPOINT/ | tail -n 1)"
|
||||||
MUSIC_DISK_FILE_NAME="$BACKINGFILES_MOUNTPOINT/music_disk.bin"
|
MUSIC_DISK_FILE_NAME="$BACKINGFILES_MOUNTPOINT/music_disk.bin"
|
||||||
add_drive "music" "MUSIC" "$MUSIC_DISK_SIZE" "$MUSIC_DISK_FILE_NAME"
|
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"
|
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
|
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"
|
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
|
fi
|
||||||
|
|
||||||
|
create_teslacam_directory
|
||||||
@@ -1,9 +1,10 @@
|
|||||||
#!/bin/bash -eu
|
#!/bin/bash -eu
|
||||||
|
|
||||||
REPO=cimryan
|
USER_ENABLED_PUSHOVER=false
|
||||||
BRANCH=master
|
|
||||||
user_enabled_pushover=false
|
|
||||||
|
|
||||||
|
REPO=${REPO:-cimryan}
|
||||||
|
|
||||||
|
BRANCH=${BRANCH:-master}
|
||||||
|
|
||||||
if ! [ $(id -u) = 0 ]
|
if ! [ $(id -u) = 0 ]
|
||||||
then
|
then
|
||||||
@@ -35,7 +36,7 @@ function check_pushover_enabled () {
|
|||||||
echo "STOP: You're trying to setup Pushover, but didn't replace the default User and App key values."
|
echo "STOP: You're trying to setup Pushover, but didn't replace the default User and App key values."
|
||||||
exit 1
|
exit 1
|
||||||
else
|
else
|
||||||
user_enabled_pushover=true
|
USER_ENABLED_PUSHOVER=true
|
||||||
echo "export pushover_enabled=true" > /root/.teslaCamPushoverCredentials
|
echo "export pushover_enabled=true" > /root/.teslaCamPushoverCredentials
|
||||||
echo "export pushover_user_key=$pushover_user_key" >> /root/.teslaCamPushoverCredentials
|
echo "export pushover_user_key=$pushover_user_key" >> /root/.teslaCamPushoverCredentials
|
||||||
echo "export pushover_app_key=$pushover_app_key" >> /root/.teslaCamPushoverCredentials
|
echo "export pushover_app_key=$pushover_app_key" >> /root/.teslaCamPushoverCredentials
|
||||||
@@ -43,22 +44,6 @@ function check_pushover_enabled () {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
check_pushover_enabled
|
|
||||||
|
|
||||||
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 ]
|
|
||||||
then
|
|
||||||
echo "STOP: The archive server $archiveserver is unreachable. Try specifying its IP address instead."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "The archive server is reachable."
|
|
||||||
}
|
|
||||||
|
|
||||||
function check_available_space () {
|
function check_available_space () {
|
||||||
echo "Verifying that there is sufficient space available on the MicroSD card..."
|
echo "Verifying that there is sufficient space available on the MicroSD card..."
|
||||||
|
|
||||||
@@ -73,22 +58,26 @@ function check_available_space () {
|
|||||||
echo "There is sufficient space available."
|
echo "There is sufficient space available."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function get_script () {
|
||||||
|
local local_path="$1"
|
||||||
|
local name="$2"
|
||||||
|
local remote_path="${3:-}"
|
||||||
|
|
||||||
|
wget -O "$local_path/$name" https://raw.githubusercontent.com/"$REPO"/teslausb/"$BRANCH"/"$remote_path"/"$name"
|
||||||
|
chmod +x "$local_path/$name"
|
||||||
|
}
|
||||||
|
|
||||||
function get_ancillary_setup_scripts () {
|
function get_ancillary_setup_scripts () {
|
||||||
pushd /tmp
|
get_script /tmp create-backingfiles-partition.sh setup/pi
|
||||||
wget https://raw.githubusercontent.com/"$REPO"/teslausb/"$BRANCH"/windows_archive/create-backingfiles-partition.sh
|
get_script /tmp create-backingfiles.sh setup/pi
|
||||||
chmod +x ./create-backingfiles-partition.sh
|
get_script /tmp make-root-fs-readonly.sh setup/pi
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function fix_cmdline_txt_modules_load ()
|
function fix_cmdline_txt_modules_load ()
|
||||||
{
|
{
|
||||||
echo "Fixing the modules-load parameter in /boot/cmdline.txt..."
|
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/ modules-load=dwc2,g_ether/ modules-load=dwc2/' > /boot/cmdline.txt
|
||||||
rm ~/cmdline.txt
|
rm ~/cmdline.txt
|
||||||
echo "Fixed cmdline.txt."
|
echo "Fixed cmdline.txt."
|
||||||
}
|
}
|
||||||
@@ -96,66 +85,63 @@ function fix_cmdline_txt_modules_load ()
|
|||||||
BACKINGFILES_MOUNTPOINT=/backingfiles
|
BACKINGFILES_MOUNTPOINT=/backingfiles
|
||||||
|
|
||||||
function create_usb_drive_backing_files () {
|
function create_usb_drive_backing_files () {
|
||||||
mkdir "$BACKINGFILES_MOUNTPOINT"
|
if [ ! -e "$BACKINGFILES_MOUNTPOINT" ]
|
||||||
/tmp/create-backingfiles-partition.sh "$BACKINGFILES_MOUNTPOINT"
|
then
|
||||||
|
mkdir "$BACKINGFILES_MOUNTPOINT"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Mounting the partition for the backing files..."
|
if [ ! -e /dev/mmcblk0p3 ]
|
||||||
mount /backingfiles
|
then
|
||||||
echo "Mounted the partition for the backing files."
|
/tmp/create-backingfiles-partition.sh "$BACKINGFILES_MOUNTPOINT"
|
||||||
|
fi
|
||||||
|
|
||||||
/tmp/create-backingfiles.sh "$campercent" "$BACKINGFILES_MOUNTPOINT"
|
if ! findmnt --mountpoint $BACKINGFILES_MOUNTPOINT
|
||||||
}
|
then
|
||||||
|
echo "Mounting the partition for the backing files..."
|
||||||
|
mount $BACKINGFILES_MOUNTPOINT
|
||||||
|
echo "Mounted the partition for the backing files."
|
||||||
|
fi
|
||||||
|
|
||||||
function configure_archive () {
|
if [ ! -e $BACKINGFILES_MOUNTPOINT/*.bin ]
|
||||||
echo "Configuring the archive..."
|
then
|
||||||
mkdir /mnt/archive
|
/tmp/create-backingfiles.sh "$campercent" "$BACKINGFILES_MOUNTPOINT"
|
||||||
local archive_server_ip_address="$(ping -c 1 -w 1 $archiveserver 2>/dev/null | head -n 1 | grep -o -e "(\([[:digit:]]\{1,3\}\.\)\{3\}[[:digit:]]\{1,3\})" | tr -d '()')"
|
fi
|
||||||
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 () {
|
function configure_archive_scripts () {
|
||||||
echo "Configuring the archive scripts..."
|
echo "Configuring the archive scripts..."
|
||||||
mkdir /root/bin
|
|
||||||
|
|
||||||
pushd ~
|
get_script /root/bin archiveloop run
|
||||||
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
|
if [ $RSYNC_ENABLE = true ]
|
||||||
rm ~/archiveloop
|
then
|
||||||
chmod +x /root/bin/archiveloop
|
get_script /root/bin archive-clips.sh run/rsync_archive
|
||||||
popd
|
get_script /root/bin connect-archive.sh run/rsync_archive
|
||||||
|
get_script /root/bin disconnect-archive.sh run/rsync_archive
|
||||||
|
else
|
||||||
|
get_script /root/bin archive-clips.sh run/cifs_archive
|
||||||
|
get_script /root/bin connect-archive.sh run/cifs_archive
|
||||||
|
get_script /root/bin disconnect-archive.sh run/cifs_archive
|
||||||
|
fi
|
||||||
|
|
||||||
|
get_script /root/bin remountfs_rw run
|
||||||
|
|
||||||
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."
|
echo "Configured the archive scripts."
|
||||||
|
|
||||||
pushd /root
|
|
||||||
wget https://raw.githubusercontent.com/"$REPO"/teslausb/"$BRANCH"/windows_archive/remountfs_rw
|
|
||||||
chmod +x remountfs_rw
|
|
||||||
popd
|
|
||||||
echo "Downloaded script to remount filesystems read/write if needed (/root/remountfs_rw)."
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function configure_pushover_scripts() {
|
function configure_pushover_scripts() {
|
||||||
if [ ${user_enabled_pushover} = "true" ]
|
get_script /root/bin send-pushover run
|
||||||
then
|
|
||||||
pushd /root/bin
|
|
||||||
wget https://raw.githubusercontent.com/"$REPO"/teslausb/"$BRANCH"/windows_archive/send-pushover
|
|
||||||
chmod +x send-pushover
|
|
||||||
popd
|
|
||||||
fi
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function configure_rc_local () {
|
function configure_rc_local () {
|
||||||
|
if grep -q archiveloop /etc/rc.local
|
||||||
|
then
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
echo "Configuring /etc/rc.local to run the archive scripts at startup..."
|
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
|
echo "archiveserver=\"${archiveserver}\"" >> ~/rc.local
|
||||||
cat << 'EOF' >> ~/rc.local
|
cat << 'EOF' >> ~/rc.local
|
||||||
LOGFILE=/tmp/rc.local.log
|
LOGFILE=/tmp/rc.local.log
|
||||||
|
|
||||||
@@ -165,7 +151,7 @@ function log () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log "Launching archival script..."
|
log "Launching archival script..."
|
||||||
/root/bin/archiveloop &
|
/root/bin/archiveloop "$archiveserver" &
|
||||||
log "All done"
|
log "All done"
|
||||||
exit 0
|
exit 0
|
||||||
EOF
|
EOF
|
||||||
@@ -193,15 +179,45 @@ function make_root_fs_readonly () {
|
|||||||
|
|
||||||
echo "Verifying environment variables..."
|
echo "Verifying environment variables..."
|
||||||
|
|
||||||
|
RSYNC_ENABLE="${RSYNC_ENABLE:-false}"
|
||||||
|
|
||||||
|
if [ "$RSYNC_ENABLE" = true ]
|
||||||
|
then
|
||||||
|
check_variable "RSYNC_USER"
|
||||||
|
check_variable "RSYNC_SERVER"
|
||||||
|
export archiveserver="$RSYNC_SERVER"
|
||||||
|
check_variable "RSYNC_PATH"
|
||||||
|
else # Else for now, TODO allow both for more redundancy?
|
||||||
|
check_variable "sharename"
|
||||||
|
check_variable "shareuser"
|
||||||
|
check_variable "sharepassword"
|
||||||
|
|
||||||
|
export cifs_version="${cifs_version:-3.0}"
|
||||||
|
fi
|
||||||
|
|
||||||
check_variable "archiveserver"
|
check_variable "archiveserver"
|
||||||
check_variable "sharename"
|
|
||||||
check_variable "shareuser"
|
|
||||||
check_variable "sharepassword"
|
|
||||||
check_variable "campercent"
|
check_variable "campercent"
|
||||||
|
|
||||||
check_pushover_enabled
|
check_pushover_enabled
|
||||||
|
|
||||||
check_archive_server_reachable
|
if [ ! -e /root/bin ]
|
||||||
|
then
|
||||||
|
mkdir /root/bin
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$RSYNC_ENABLE" = true ]
|
||||||
|
then
|
||||||
|
get_script /root/bin verify-archive-configuration.sh run/rsync_archive
|
||||||
|
get_script /root/bin configure-archive.sh run/rsync_archive
|
||||||
|
else
|
||||||
|
get_script /root/bin verify-archive-configuration.sh run/cifs_archive
|
||||||
|
get_script /root/bin configure-archive.sh run/cifs_archive
|
||||||
|
get_script /root/bin write-archive-credentials-to.sh run/cifs_archive
|
||||||
|
fi
|
||||||
|
|
||||||
|
get_script /root/bin get-archiveserver-ip-address.sh run
|
||||||
|
|
||||||
|
/root/bin/verify-archive-configuration.sh
|
||||||
|
|
||||||
check_available_space
|
check_available_space
|
||||||
|
|
||||||
@@ -219,7 +235,7 @@ echo "" >> /etc/fstab
|
|||||||
|
|
||||||
create_usb_drive_backing_files
|
create_usb_drive_backing_files
|
||||||
|
|
||||||
configure_archive
|
/root/bin/configure-archive.sh
|
||||||
|
|
||||||
configure_rc_local
|
configure_rc_local
|
||||||
|
|
||||||
91
setup/windows/WpaSupplicantConf.psm1
Normal file
91
setup/windows/WpaSupplicantConf.psm1
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
function Write-Header {
|
||||||
|
param(
|
||||||
|
[string]$driveLetter
|
||||||
|
)
|
||||||
|
$header=@"
|
||||||
|
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
|
||||||
|
update_config=1
|
||||||
|
"@
|
||||||
|
|
||||||
|
Set-WpaSupplicantConfContent "$driveLetter" "$header"
|
||||||
|
}
|
||||||
|
|
||||||
|
function Add-Network {
|
||||||
|
param(
|
||||||
|
[string]$driveLetter,
|
||||||
|
[string]$wifiSSID,
|
||||||
|
[string]$wifiPSK
|
||||||
|
)
|
||||||
|
|
||||||
|
$network=@"
|
||||||
|
|
||||||
|
|
||||||
|
network={
|
||||||
|
ssid="$wifiSSID"
|
||||||
|
psk="$wifiPSK"
|
||||||
|
}
|
||||||
|
"@
|
||||||
|
|
||||||
|
Add-WpaSupplicantConfContent "$driveLetter" "$network"
|
||||||
|
}
|
||||||
|
|
||||||
|
function Set-WpaSupplicantConfContent {
|
||||||
|
param(
|
||||||
|
[string]$driveLetter,
|
||||||
|
[string]$content
|
||||||
|
)
|
||||||
|
|
||||||
|
$wpaSupplicantConfPath = Get-WpaSupplicantConfPath $driveLetter
|
||||||
|
$encodedContent = Encode-Content $content
|
||||||
|
Set-Content -Value $encodedContent -Encoding Byte -Path "$wpaSupplicantConfPath"
|
||||||
|
}
|
||||||
|
|
||||||
|
function Add-WpaSupplicantConfContent {
|
||||||
|
param(
|
||||||
|
[string]$driveLetter,
|
||||||
|
[string]$content
|
||||||
|
)
|
||||||
|
|
||||||
|
$wpaSupplicantConfPath = Get-WpaSupplicantConfPath $driveLetter
|
||||||
|
$encodedContent = Encode-Content $content
|
||||||
|
Add-Content -Value $encodedContent -Encoding Byte -Path "$wpaSupplicantConfPath"
|
||||||
|
}
|
||||||
|
|
||||||
|
function Verify-WpaSupplicantConfPath {
|
||||||
|
param(
|
||||||
|
[string]$driveLetter
|
||||||
|
)
|
||||||
|
|
||||||
|
$drivePath="${driveLetter}:"
|
||||||
|
$configPath = "$drivePath\config.txt"
|
||||||
|
$cmdlinePath = "$drivePath\cmdline.txt"
|
||||||
|
$sshPath = "$drivePath\ssh"
|
||||||
|
|
||||||
|
if ((![System.IO.File]::Exists($configPath) -or
|
||||||
|
(![System.IO.File]::Exists($cmdlinePath)))) {
|
||||||
|
Write-Error "Didn't find cmdline.txt and config.txt on drive $drivePath."
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Encode-Content {
|
||||||
|
param(
|
||||||
|
[string]$content
|
||||||
|
)
|
||||||
|
$utf8 = New-Object System.Text.UTF8Encoding $false
|
||||||
|
|
||||||
|
return $utf8.GetBytes($content)
|
||||||
|
}
|
||||||
|
|
||||||
|
function Get-WpaSupplicantConfPath {
|
||||||
|
param(
|
||||||
|
[string]$driveLetter
|
||||||
|
)
|
||||||
|
|
||||||
|
Verify-WpaSupplicantConfPath $driveLetter
|
||||||
|
|
||||||
|
return "${driveLetter}:\wpa_supplicant.conf"
|
||||||
|
}
|
||||||
|
|
||||||
|
Export-ModuleMember -Function Write-Header
|
||||||
|
Export-ModuleMember -Function Add-Network
|
||||||
18
setup/windows/add-wifi.ps1
Normal file
18
setup/windows/add-wifi.ps1
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
[CmdletBinding()]
|
||||||
|
Param
|
||||||
|
(
|
||||||
|
[Parameter(Mandatory=$True,Position=1)]
|
||||||
|
[string]$driveLetter,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$True,Position=2)]
|
||||||
|
[string]$wifiSSID,
|
||||||
|
|
||||||
|
[Parameter(Mandatory=$True,Position=3)]
|
||||||
|
[string]$wifiPSK
|
||||||
|
)
|
||||||
|
|
||||||
|
Import-Module -Name ".\WpaSupplicantConf.psm1" -Force
|
||||||
|
|
||||||
|
Add-Network "$driveLetter" "$wifiSSID" "$wifiPSK"
|
||||||
|
|
||||||
|
Write-Verbose "All done."
|
||||||
@@ -11,6 +11,11 @@ Param
|
|||||||
[string]$wifiPSK
|
[string]$wifiPSK
|
||||||
)
|
)
|
||||||
|
|
||||||
|
wget https://raw.githubusercontent.com/cimryan/teslausb/master/setup/windows/WpaSupplicantConf.psm1 -OutFile WpaSupplicantConf.psm1
|
||||||
|
wget https://raw.githubusercontent.com/cimryan/teslausb/master/setup/windows/add-wifi.ps1 -OutFile add-wifi.ps1
|
||||||
|
|
||||||
|
Import-Module -Name ".\WpaSupplicantConf.psm1" -Force
|
||||||
|
|
||||||
$drivePath="${driveLetter}:"
|
$drivePath="${driveLetter}:"
|
||||||
$configPath = "$drivePath\config.txt"
|
$configPath = "$drivePath\config.txt"
|
||||||
$cmdlinePath = "$drivePath\cmdline.txt"
|
$cmdlinePath = "$drivePath\cmdline.txt"
|
||||||
@@ -34,24 +39,9 @@ $cmdlinetxtContent.Replace("rootwait", "rootwait modules-load=dwc2,g_ether").Rep
|
|||||||
Write-Verbose "Enabling SSH ..."
|
Write-Verbose "Enabling SSH ..."
|
||||||
[System.IO.File]::CreateText($sshPath).Dispose()
|
[System.IO.File]::CreateText($sshPath).Dispose()
|
||||||
|
|
||||||
# Sets up wifi credentials so wifi will be
|
|
||||||
# auto configured on first boot
|
|
||||||
|
|
||||||
$wpaSupplicantConfPath="$drivePath\wpa_supplicant.conf"
|
|
||||||
|
|
||||||
Write-Verbose "(Re)creating WiFi configuration file $wpaSupplicantConfPath."
|
Write-Verbose "(Re)creating WiFi configuration file $wpaSupplicantConfPath."
|
||||||
if ([System.IO.File]::Exists("$wpaSupplicantConfPath")) {
|
|
||||||
del "$wpaSupplicantConfPath"
|
|
||||||
}
|
|
||||||
|
|
||||||
"ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev`
|
Write-Header "$driveLetter"
|
||||||
update_config=1`
|
Add-Network "$driveLetter" "$wifiSSID" "$wifiPSK"
|
||||||
`
|
|
||||||
network={`
|
|
||||||
ssid=`"$wifiSSID`"`
|
|
||||||
psk=`"$wifiPSK`"`
|
|
||||||
key_mgmt=WPA-PSK`
|
|
||||||
}`
|
|
||||||
" | Out-File -FilePath "$wpaSupplicantConfPath" -Encoding utf8
|
|
||||||
|
|
||||||
Write-Verbose "All done."
|
Write-Verbose "All done."
|
||||||
@@ -1,143 +0,0 @@
|
|||||||
#!/bin/bash -eu
|
|
||||||
|
|
||||||
LOG_FILE=/tmp/archiveloop.log
|
|
||||||
CAM_MOUNT=/mnt/cam
|
|
||||||
ARCHIVE_MOUNT=/mnt/archive
|
|
||||||
|
|
||||||
function log () {
|
|
||||||
echo "$( date ) : $1" >> "$LOG_FILE"
|
|
||||||
}
|
|
||||||
|
|
||||||
function retry () {
|
|
||||||
local attempts=0
|
|
||||||
while [ true ]
|
|
||||||
do
|
|
||||||
if eval "$@"
|
|
||||||
then
|
|
||||||
true
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
if [ "$attempts" -ge 10 ]
|
|
||||||
then
|
|
||||||
log "Attempts exhausted."
|
|
||||||
false
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
log "Sleeping before retry..."
|
|
||||||
/bin/sleep 1
|
|
||||||
attempts=$((attempts + 1))
|
|
||||||
log "Retrying..."
|
|
||||||
done
|
|
||||||
false
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
function mount_mountpoint () {
|
|
||||||
local mount_point="$1"
|
|
||||||
log "Mounting $mount_point..."
|
|
||||||
|
|
||||||
local mounted=true
|
|
||||||
mount "$mount_point" >> "$LOG_FILE" 2>&1 || mounted=false
|
|
||||||
if [ "$mounted" = true ]
|
|
||||||
then
|
|
||||||
log "Mounted $mount_point."
|
|
||||||
if [ -d "/mnt/cam/TeslaCam" ]
|
|
||||||
then
|
|
||||||
log "TeslaCam folder exists"
|
|
||||||
true
|
|
||||||
return
|
|
||||||
else
|
|
||||||
mkdir /mnt/cam/TeslaCam
|
|
||||||
true
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
log "Failed to mount $mount_point."
|
|
||||||
false
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensure_mountpoint_is_mounted () {
|
|
||||||
local mount_point="$1"
|
|
||||||
local mount_exists=true
|
|
||||||
|
|
||||||
findmnt --mountpoint "$mount_point" > /dev/null || mount_exists=false
|
|
||||||
|
|
||||||
if [ "$mount_exists" = true ]
|
|
||||||
then
|
|
||||||
log "$mount_point is already mounted."
|
|
||||||
else
|
|
||||||
mount_mountpoint "$mount_point"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensure_mountpoint_is_mounted_with_retry () {
|
|
||||||
retry ensure_mountpoint_is_mounted "$1"
|
|
||||||
}
|
|
||||||
|
|
||||||
function move_clips_to_archive () {
|
|
||||||
log "Moving clips to archive..."
|
|
||||||
move_count=0
|
|
||||||
for file_name in "$CAM_MOUNT"/TeslaCam/saved*; do
|
|
||||||
[ -e "$file_name" ] || continue
|
|
||||||
log "Moving $file_name ..."
|
|
||||||
mv -- "$file_name" "$ARCHIVE_MOUNT" >> "$LOG_FILE" 2>&1 || echo ""
|
|
||||||
log "Moved $file_name."
|
|
||||||
move_count=$((move_count + 1))
|
|
||||||
|
|
||||||
done
|
|
||||||
log "Moved $move_count file(s)."
|
|
||||||
if [ -e "/root/.teslaCamPushoverCredentials" ] && [ ${move_count} -gt 0 ]
|
|
||||||
then
|
|
||||||
log "Sending Pushover message for copied files."
|
|
||||||
/root/bin/send-pushover $move_count
|
|
||||||
fi
|
|
||||||
log "Finished moving clips to archive."
|
|
||||||
}
|
|
||||||
|
|
||||||
function disconnect_usb_drives_from_host () {
|
|
||||||
log "Disconnecting usb from host..."
|
|
||||||
modprobe -r g_mass_storage
|
|
||||||
log "Disconnected usb from host."
|
|
||||||
}
|
|
||||||
|
|
||||||
function fix_errors_on_cam_drive () {
|
|
||||||
log "Running fsck..."
|
|
||||||
/sbin/fsck "$CAM_MOUNT" -- -a >> "$LOG_FILE" 2>&1 || echo ""
|
|
||||||
log "Finished running fsck."
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensure_archive_is_mounted () {
|
|
||||||
log "Ensuring cam archive is mounted..."
|
|
||||||
ensure_mountpoint_is_mounted_with_retry "$ARCHIVE_MOUNT"
|
|
||||||
log "Ensured cam archive is mounted."
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensure_cam_drive_is_mounted () {
|
|
||||||
log "Ensuring cam drive is mounted..."
|
|
||||||
ensure_mountpoint_is_mounted_with_retry "$CAM_MOUNT"
|
|
||||||
log "Ensured cam drive is mounted."
|
|
||||||
}
|
|
||||||
|
|
||||||
function unmount_cam_drive () {
|
|
||||||
log "Unmounting cam drive..."
|
|
||||||
umount "$CAM_MOUNT"
|
|
||||||
log "Unmounted cam drive."
|
|
||||||
}
|
|
||||||
|
|
||||||
log "Starting..."
|
|
||||||
|
|
||||||
ensure_archive_is_mounted
|
|
||||||
|
|
||||||
disconnect_usb_drives_from_host
|
|
||||||
|
|
||||||
fix_errors_on_cam_drive
|
|
||||||
|
|
||||||
ensure_cam_drive_is_mounted
|
|
||||||
|
|
||||||
move_clips_to_archive
|
|
||||||
|
|
||||||
unmount_cam_drive
|
|
||||||
|
|
||||||
connect_usb_drives_to_host
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
#!/bin/bash -eu
|
|
||||||
|
|
||||||
# Change the value on the right side of the equal sign to the name of the server hosting the archive.
|
|
||||||
ARCHIVE_HOST_NAME=archiveserver
|
|
||||||
LOG_FILE=/tmp/archiveloop.log
|
|
||||||
|
|
||||||
function log () {
|
|
||||||
echo "$( date ) : $1" >> "$LOG_FILE"
|
|
||||||
}
|
|
||||||
|
|
||||||
function archive_is_reachable () {
|
|
||||||
local reachable=true
|
|
||||||
ping -q -w 1 -c 1 "$ARCHIVE_HOST_NAME" > /dev/null 2>&1 || reachable=false
|
|
||||||
if [ "$reachable" = false ]
|
|
||||||
then
|
|
||||||
false
|
|
||||||
return
|
|
||||||
fi
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
function connect_usb_drives_to_host() {
|
|
||||||
log "Connecting usb to host..."
|
|
||||||
modprobe g_mass_storage
|
|
||||||
log "Connected usb to host."
|
|
||||||
}
|
|
||||||
|
|
||||||
function wait_for_archive_to_be_reachable () {
|
|
||||||
log "Waiting for archive to be reachable..."
|
|
||||||
while [ true ]
|
|
||||||
do
|
|
||||||
if archive_is_reachable
|
|
||||||
then
|
|
||||||
log "Archive is reachable."
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
function archive_clips () {
|
|
||||||
log "Archiving..."
|
|
||||||
/root/bin/archive-teslacam-clips
|
|
||||||
log "Finished archiving."
|
|
||||||
}
|
|
||||||
|
|
||||||
function wait_for_archive_to_be_unreachable () {
|
|
||||||
log "Waiting for archive to be unreachable..."
|
|
||||||
while [ true ]
|
|
||||||
do
|
|
||||||
if ! archive_is_reachable
|
|
||||||
then
|
|
||||||
log "Archive is unreachable."
|
|
||||||
break
|
|
||||||
fi
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
}
|
|
||||||
|
|
||||||
export -f connect_usb_drives_to_host
|
|
||||||
|
|
||||||
log "Starting..."
|
|
||||||
|
|
||||||
if archive_is_reachable
|
|
||||||
then
|
|
||||||
archive_clips
|
|
||||||
|
|
||||||
wait_for_archive_to_be_unreachable
|
|
||||||
else
|
|
||||||
connect_usb_drives_to_host
|
|
||||||
fi
|
|
||||||
|
|
||||||
while [ true ]
|
|
||||||
do
|
|
||||||
wait_for_archive_to_be_reachable
|
|
||||||
|
|
||||||
archive_clips
|
|
||||||
|
|
||||||
wait_for_archive_to_be_unreachable
|
|
||||||
done
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
#!/bin/bash -eu
|
|
||||||
|
|
||||||
files_copied=$1
|
|
||||||
|
|
||||||
LOG_FILE=/tmp/archiveloop.log
|
|
||||||
|
|
||||||
function log () {
|
|
||||||
echo "$( date ) : $1" >> "$LOG_FILE"
|
|
||||||
}
|
|
||||||
|
|
||||||
source /root/.teslaCamPushoverCredentials
|
|
||||||
|
|
||||||
if ping -c 1 api.pushover.net &> /dev/null
|
|
||||||
then
|
|
||||||
if [ $files_copied -gt 0 ]
|
|
||||||
then
|
|
||||||
log "Sending notification that $files_copied were copied."
|
|
||||||
curl -s -F "token=$pushover_app_key" \
|
|
||||||
-F "user=$pushover_user_key" \
|
|
||||||
-F "title=Dashcam Copy Complete" \
|
|
||||||
-F "message=${files_copied} file(s) were copied." \
|
|
||||||
https://api.pushover.net/1/messages
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
Reference in New Issue
Block a user