diff --git a/README.md b/README.md index 4113c86..10b0fc0 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,21 @@ To run a specific test, say `test_dummy.py`, use poetry run pytest tests/test_dummy.py ``` +## Deployment +To deploy a build to the Raspberry Pi use the `deploy.sh` script. This script will create a tarball of file listed in a text file, transfer it to +a specified hostname and untar it there. + +To use the script execute it in the project's root directory with, +```bash +./deploy.sh [pathfile] [username]@[hostname] +``` +For example, to deploy the files listed in `deploypaths.txt` to `testpi` (using username raspberry) the command would be +```bash +./deploy.sh deploypaths.txt raspberry@testpi +``` +The pathname file should contain a path to a file or directory on each line. If a directory is listed `deploy.sh` will copy the entire contents over. +You can use the `#` character at the start of a line to leave comments. + ## Code Styling We use [black](https://black.readthedocs.io/en/stable/) for automated code formatting. To run Black, run this command from the root of the repo: diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 0000000..c4d06d0 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,84 @@ +#!/bin/bash + + +WARN="[\033[1;33mWARN\033[0m]" +INFO="[\033[1;32mINFO\033[0m]" +ERROR="[\033[1;31mERROR\033[0m]" + +PATHFILE=$1 +TEMPDIRPATH='package_temp' + +[ -d $TEMPDIRPATH ] +TEMPDIRCHECK=$? + +# Make temp dir if it doesn't exist +if [ $TEMPDIRCHECK == 1 ]; then + mkdir $TEMPDIRPATH +else + echo -e "$INFO Temp directory was pre-existing. I promise not to delete it." +fi + +cleanup () { + # Do not delete the temp dir if it was pre-existing + echo -e "$INFO Cleaning up" + if [ $TEMPDIRCHECK == 1 ]; then + rm -r $TEMPDIRPATH + fi +} + +BUILDPATH="${TEMPDIRPATH}/build" +mkdir $BUILDPATH + +echo -e "$INFO Copying Files" + +while read path; do + if [[ $path == \#* ]]; then + true + elif [ -d $path ]; then + #path is a directory + cp -r --parents $path $BUILDPATH + elif [ -e $path ]; then + #path is just a file + cp --parents $path ${BUILDPATH} + else + echo -e "${WARN}: $path not found" + fi +done <$PATHFILE + +# Hashing directory line from https://stackoverflow.com/questions/545387/linux-compute-a-single-hash-for-a-given-folder-contents +HASH=$( find ${BUILDPATH} -type f -print0 | sort -z | xargs -0 sha1sum | sha1sum ) +TARNAME="build-${HASH:0:8}.tar" # Truncate the hash for a nicer file names + +# Create tarball +echo -e "$INFO Creating Tarball" +if ! tar cf $TARNAME -C $TEMPDIRPATH "./build"; then + echo -e "$ERROR Tarball creation failed" + cleanup + exit 1 +fi + +SSHTARGET=$2 +# Check if we can find target +if ! nc -z $SSHTARGET 22 2>/dev/null; then + echo -e "$ERROR Host unreachable"; + cleanup + exit 1 +fi + +echo -e "$INFO Copying Tarball - destination's password may be needed" +if ! scp -q $TARNAME $SSHTARGET:~/; then + echo -e "$ERROR Copy unsuccessful" + cleanup + exit 1 +fi + +echo -e "$INFO Extracting Build - the password may be needed again" +if ! ssh $SSHTARGET "tar xf $TARNAME; rm $TARNAME"; then + echo -e "$ERROR Remote extraction failed" + cleanup + exit 1 +fi + +echo -e "$INFO Deployed Successfully" +cleanup +exit 0 diff --git a/deploypaths.txt b/deploypaths.txt new file mode 100644 index 0000000..5213d81 --- /dev/null +++ b/deploypaths.txt @@ -0,0 +1,3 @@ +# Enter paths of files and directories to be bundled and sent to the pi +# deploy.sh will preserve the source directory layout so imports between files +# should still work if all files are copied in \ No newline at end of file