install.sh 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. #!/usr/bin/env bash
  2. # This script will install a systemd service and timer to mount a remote ftp share, rsync a directory to it, and then unmount the share
  3. # I'm using this to sync photos to a digital picture frame
  4. #
  5. # Copyright (c) 2020 Bryan Roessler <bryanroessler@gmail.com>
  6. # Permission is hereby granted, free of charge, to any person obtaining a copy
  7. # of this software and associated documentation files (the "Software"), to deal
  8. # in the Software without restriction, including without limitation the rights
  9. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. # copies of the Software, and to permit persons to whom the Software is
  11. # furnished to do so, subject to the following conditions:
  12. #
  13. # The above copyright notice and this permission notice shall be included in all
  14. # copies or substantial portions of the Software.
  15. #
  16. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  22. # SOFTWARE.
  23. #
  24. version="0.1"
  25. debug="off" # turn "on" for debugging
  26. # IMPORTANT OPTIONS #
  27. service_name="rsync-to-picture-frame" # use something specific and memorable
  28. description="Mount picture frame ftp share and rsync syncthing picture_frame directory to it" # a short description
  29. ftp_share="192.168.1.100:2221" # source share, best to make this a static address if you can
  30. source_dir="$HOME/Pictures/picture_frame" # source files from this directory
  31. # Less important options
  32. user="$(id -un)" # default run as current user
  33. user_id="$(id -u)" # default run as current user
  34. group_id="$(id -g)" # default run as current user
  35. script_dir="$PWD" # where to copy the script to, default is $PWD (created automatically if missing)
  36. mount_dir="/media/picture_frame_ftp" # directory to mount the ftp share to (created automatically if missing)
  37. temp_dir="/tmp/picture_frame_ftp" # ftp does not support rsync temp files (created automatically if missing)
  38. # Service settings
  39. service_dir="$HOME/.config/systemd/user"
  40. on_calendar="hourly" # how often to mount and sync
  41. # END USER OPTIONS #
  42. # if debug is on, echo additional output
  43. debug() { [[ $debug == "on" ]] && echo "debug: $*"; }
  44. check_and_install() {
  45. if ! command -v "$1" > /dev/null 2>&1; then
  46. echo "Installing $1"
  47. [[ -f /etc/os-release ]] && source /etc/os-release
  48. if [[ "${NAME,,}" =~ (fedora|centos) ]]; then
  49. debug "sudo dnf install -y $1"
  50. if ! sudo dnf install -y "$1"; then
  51. echo "Could not install $1, exiting"
  52. exit 1
  53. fi
  54. elif [[ "${NAME,,}" =~ (debian|ubuntu) ]]; then
  55. debug "sudo apt install -y $1"
  56. if ! sudo apt install -y "$1"; then
  57. echo "Could not install $1, exiting"
  58. exit 1
  59. fi
  60. else
  61. echo "$1 must be installed"
  62. exit 1
  63. fi
  64. fi
  65. return $?
  66. }
  67. # Happily make directories
  68. mk_dir() {
  69. for DIR in "$@"; do
  70. if [[ ! -d "$DIR" ]]; then
  71. debug "mkdir -p $DIR"
  72. if ! mkdir -p "$DIR"; then
  73. debug "sudo mkdir -p $DIR"
  74. if ! sudo mkdir -p "$DIR"; then
  75. echo "sudo mkdir $DIR failed, exiting"
  76. exit 1
  77. fi
  78. fi
  79. fi
  80. done
  81. }
  82. # Happily chown directories as $user
  83. chown_dir() {
  84. for DIR in "$@"; do
  85. debug "chown $user:$user -R $DIR"
  86. if ! chown "$user":"$user" -R "$DIR"; then
  87. debug "sudo chown $user:$user -R $DIR"
  88. if ! sudo chown "$user":"$user" -R "$DIR"; then
  89. echo "sudo chown on $DIR failed, exiting"
  90. exit 1
  91. fi
  92. fi
  93. done
  94. return $?
  95. }
  96. # Happily make files executable
  97. make_exec() {
  98. for FILE in "$@"; do
  99. debug "chmod a+x $FILE"
  100. if ! chmod a+x "$FILE"; then
  101. debug "sudo chmod a+x $FILE"
  102. if ! sudo chmod a+x "$FILE"; then
  103. echo "sudo chmod on $FILE failed, exiting"
  104. exit 1
  105. fi
  106. fi
  107. done
  108. return $?
  109. }
  110. # Happily copy files
  111. cp_file() {
  112. if [[ ! -f "$1" ]]; then
  113. echo "$1 is missing"
  114. exit 1
  115. elif ! cp -af "$1" "$2"; then
  116. echo "failed, retrying with sudo"
  117. debug "sudo cp -f $1 $2"
  118. if ! sudo cp -af "$1" "$2"; then
  119. echo "Copying script failed, exiting"
  120. exit 1
  121. fi
  122. fi
  123. }
  124. # Use sed to find ($1) and replace ($2) a string in a file ($3)
  125. f_and_r() {
  126. debug "s#$1#$2#" "$3"
  127. if ! sed -i "s#$1#$2#g" "$3"; then
  128. exit 1
  129. fi
  130. }
  131. main() {
  132. # Install curlftps
  133. debug "check_and_install curlftpfs"
  134. check_and_install "curlftpfs"
  135. # Disable existing timer
  136. debug "systemctl --user disable --now $service_name.timer"
  137. systemctl --user disable --now "$service_name.timer" &> /dev/null
  138. # Unmount existing ftp share
  139. mountpoint -q -- "$mount_dir" && fusermount -u "$mount_dir"
  140. # Create directories
  141. mk_dir "$source_dir" "$mount_dir" "$service_dir" "$script_dir"
  142. chown_dir "$source_dir" "$mount_dir" "$service_dir" "$script_dir"
  143. # Copy script file
  144. cp_file "original.sh" "$script_dir/$service_name.sh"
  145. make_exec "$script_dir/$service_name.sh"
  146. f_and_r "{{mount_dir}}" "$mount_dir" "$script_dir/$service_name.sh"
  147. f_and_r "{{source_dir}}" "$source_dir" "$script_dir/$service_name.sh"
  148. f_and_r "{{ftp_share}}" "$ftp_share" "$script_dir/$service_name.sh"
  149. f_and_r "{{user_id}}" "$user_id" "$script_dir/$service_name.sh"
  150. f_and_r "{{group_id}}" "$group_id" "$script_dir/$service_name.sh"
  151. f_and_r "{{temp_dir}}" "$temp_dir" "$script_dir/$service_name.sh"
  152. # Copy service file
  153. cp_file "original.service" "$service_dir/$service_name.service"
  154. f_and_r "{{path_to_script}}" "$script_dir/$service_name.sh" "$service_dir/$service_name.service"
  155. f_and_r "{{description}}" "$script_dir/$service_name.sh" "$service_dir/$service_name.service"
  156. # Copy timer file
  157. cp_file "original.timer" "$service_dir/$service_name.timer"
  158. f_and_r "{{on_calendar}}" "$on_calendar" "$service_dir/$service_name.timer"
  159. f_and_r "{{description}}" "$description" "$service_dir/$service_name.timer"
  160. # Enable timer
  161. debug "systemctl --user daemon-reload"
  162. systemctl --user daemon-reload
  163. debug "systemctl --user enable --now $service_name.timer"
  164. systemctl --user enable --now "$service_name.timer"
  165. }
  166. main "$@"
  167. exit $?