install.sh 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  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. debug="off" # turn "on" for debugging
  25. # IMPORTANT OPTIONS #
  26. service_name="rsync-to-picture-frame" # use something specific and memorable
  27. description="Mount picture frame ftp share and rsync syncthing picture_frame directory to it" # a short description
  28. ftp_share="192.168.1.100:2221" # source share, best to make this a static address if you can
  29. source_dir="$HOME/Pictures/picture_frame" # source files from this directory
  30. # Less important options
  31. user="$(id -un)" # default run as current user
  32. user_id="$(id -u)" # default run as current user
  33. group_id="$(id -g)" # default run as current user
  34. script_dir="$PWD" # where to copy the script to, default is $PWD (created automatically if missing)
  35. mount_dir="/media/picture_frame_ftp" # directory to mount the ftp share to (created automatically if missing)
  36. temp_dir="/tmp/picture_frame_ftp" # ftp does not support rsync temp files (created automatically if missing)
  37. # Service settings
  38. service_dir="$HOME/.config/systemd/user"
  39. on_calendar="hourly" # how often to mount and sync
  40. # END USER OPTIONS #
  41. # if debug is on, echo additional output
  42. debug() { [[ $debug == "on" ]] && echo "debug: $*"; }
  43. check_and_install() {
  44. if ! command -v "$1" > /dev/null 2>&1; then
  45. echo "Installing $1"
  46. [[ -f /etc/os-release ]] && source /etc/os-release
  47. if [[ "${NAME,,}" =~ (fedora|centos) ]]; then
  48. debug "sudo dnf install -y $1"
  49. if ! sudo dnf install -y "$1"; then
  50. echo "Could not install $1, exiting"
  51. exit 1
  52. fi
  53. elif [[ "${NAME,,}" =~ (debian|ubuntu) ]]; then
  54. debug "sudo apt install -y $1"
  55. if ! sudo apt install -y "$1"; then
  56. echo "Could not install $1, exiting"
  57. exit 1
  58. fi
  59. else
  60. echo "$1 must be installed"
  61. exit 1
  62. fi
  63. fi
  64. return $?
  65. }
  66. # Happily make directories
  67. mk_dir() {
  68. for DIR in "$@"; do
  69. if [[ ! -d "$DIR" ]]; then
  70. debug "mkdir -p $DIR"
  71. if ! mkdir -p "$DIR"; then
  72. debug "sudo mkdir -p $DIR"
  73. if ! sudo mkdir -p "$DIR"; then
  74. echo "sudo mkdir $DIR failed, exiting"
  75. exit 1
  76. fi
  77. fi
  78. fi
  79. done
  80. }
  81. # Happily chown directories as $user
  82. chown_dir() {
  83. for DIR in "$@"; do
  84. debug "chown $user:$user -R $DIR"
  85. if ! chown "$user":"$user" -R "$DIR"; then
  86. debug "sudo chown $user:$user -R $DIR"
  87. if ! sudo chown "$user":"$user" -R "$DIR"; then
  88. echo "sudo chown on $DIR failed, exiting"
  89. exit 1
  90. fi
  91. fi
  92. done
  93. return $?
  94. }
  95. # Happily make files executable
  96. make_exec() {
  97. for FILE in "$@"; do
  98. debug "chmod a+x $FILE"
  99. if ! chmod a+x "$FILE"; then
  100. debug "sudo chmod a+x $FILE"
  101. if ! sudo chmod a+x "$FILE"; then
  102. echo "sudo chmod on $FILE failed, exiting"
  103. exit 1
  104. fi
  105. fi
  106. done
  107. return $?
  108. }
  109. # Happily copy files
  110. cp_file() {
  111. if [[ ! -f "$1" ]]; then
  112. echo "$1 is missing"
  113. exit 1
  114. elif ! cp -af "$1" "$2"; then
  115. echo "failed, retrying with sudo"
  116. debug "sudo cp -f $1 $2"
  117. if ! sudo cp -af "$1" "$2"; then
  118. echo "Copying script failed, exiting"
  119. exit 1
  120. fi
  121. fi
  122. }
  123. # Use sed to find ($1) and replace ($2) a string in a file ($3)
  124. f_and_r() {
  125. debug "s#$1#$2#" "$3"
  126. if ! sed -i "s#$1#$2#g" "$3"; then
  127. exit 1
  128. fi
  129. }
  130. main() {
  131. # Install curlftps
  132. debug "check_and_install curlftpfs"
  133. check_and_install "curlftpfs"
  134. # Disable existing timer
  135. debug "systemctl --user disable --now $service_name.timer"
  136. systemctl --user disable --now "$service_name.timer" &> /dev/null
  137. # Unmount existing ftp share
  138. mountpoint -q -- "$mount_dir" && fusermount -u "$mount_dir"
  139. # Create directories
  140. mk_dir "$source_dir" "$mount_dir" "$service_dir" "$script_dir"
  141. chown_dir "$source_dir" "$mount_dir" "$service_dir" "$script_dir"
  142. # Copy script file
  143. cp_file "original.sh" "$script_dir/$service_name.sh"
  144. make_exec "$script_dir/$service_name.sh"
  145. f_and_r "{{mount_dir}}" "$mount_dir" "$script_dir/$service_name.sh"
  146. f_and_r "{{source_dir}}" "$source_dir" "$script_dir/$service_name.sh"
  147. f_and_r "{{ftp_share}}" "$ftp_share" "$script_dir/$service_name.sh"
  148. f_and_r "{{user_id}}" "$user_id" "$script_dir/$service_name.sh"
  149. f_and_r "{{group_id}}" "$group_id" "$script_dir/$service_name.sh"
  150. f_and_r "{{temp_dir}}" "$temp_dir" "$script_dir/$service_name.sh"
  151. # Copy service file
  152. cp_file "original.service" "$service_dir/$service_name.service"
  153. f_and_r "{{path_to_script}}" "$script_dir/$service_name.sh" "$service_dir/$service_name.service"
  154. f_and_r "{{description}}" "$script_dir/$service_name.sh" "$service_dir/$service_name.service"
  155. # Copy timer file
  156. cp_file "original.timer" "$service_dir/$service_name.timer"
  157. f_and_r "{{on_calendar}}" "$on_calendar" "$service_dir/$service_name.timer"
  158. f_and_r "{{description}}" "$description" "$service_dir/$service_name.timer"
  159. # Enable timer
  160. debug "systemctl --user daemon-reload"
  161. systemctl --user daemon-reload
  162. debug "systemctl --user enable --now $service_name.timer"
  163. systemctl --user enable --now "$service_name.timer"
  164. }
  165. main "$@"
  166. exit $?