4 targetHost=${targetHost%/}
6 source "$targetHost/config"
8 if ! which chunked >/dev/null; then
9 printf "Requires 'chunked' package from deb2.dogcraft.de\n" >&2
15 backup_target="$targetHost/backups"
17 ssh_target "sudo ./backup"
20 read -r line <&${COPROC[0]} || exit 1;
21 if [[ $line != "Backup service ready" ]]; then
22 echo "Backup service did not respond"
25 function start_backup {
26 ident="$(date "+%Y-%m-%d-%H-%M-%S")"
27 self="$backup_target/$ident"
29 if [[ -h "$backup_target/last" ]]; then
30 last="$(readlink "$backup_target/last")"
31 ln -s "../$last" "$self/prev"
32 rm "$backup_target/last"
34 ln -s "$ident" "$backup_target/last"
37 printf "base\n" >&${COPROC[1]}
38 chunked decode <&${COPROC[0]} > "$self/pg_base.tar.gz"
39 ls -alsh -- "$self/pg_base.tar.gz"
40 read -r line <&${COPROC[0]} || exit 1;
41 echo "pg_base done: $line"
43 tar xzO backup_label < "$self/pg_base.tar.gz"
45 function incremental {
48 if [[ $(find -L "$self" -maxdepth 14 -name "pg_base.tar.gz" | wc -l) -lt 1 ]]; then
49 printf "doing pg_base backup to $self/pg_base.tar.gz:\n"
51 last="$(tar xzO backup_label < "$self/pg_base.tar.gz" | grep "^START WAL LOCATION: " | sed "s/.*(file \\(.*\\))/\\1/")"
56 while [[ $last == "" ]]; do
58 last="$(tar tf "$folder/pg_wal.tar.gz" | grep "^[A-Z0-9]*$" | tail -n 1)"
60 echo "Found last WAL file in backup: $folder"
61 hash=$(tar xfO "$folder/pg_wal.tar.gz" "$last" | sha256sum | cut -d" " -f1)
63 printf "Last WAL-name: %s\n" "$last"
64 printf "incremental\n" >&${COPROC[1]}
65 printf "%s\n" "$last" >&${COPROC[1]}
66 printf "%s\n" "$hash" >&${COPROC[1]}
67 read -r line <&${COPROC[0]} || exit 1;
68 if [[ "$line" != "Ready" ]]; then
69 printf "incremental backup didn't start\n"
72 chunked decode <&${COPROC[0]} > "$self/pg_wal.tar.gz"
73 printf "Tar contents\n"
74 tar tf "$self/pg_wal.tar.gz"
75 ls -alsh -- "$self/pg_wal.tar.gz"
76 read -r line <&${COPROC[0]} || exit 1;
77 if [[ $line == "incremental backup done, confirm cleanup!" ]]; then
78 printf "y\n" >&${COPROC[1]}
80 printf "Done, but got strange line for cleanup confirmation: %s\n" "$line"
82 printf "Done incremental backup\n"
85 if [[ "$2" == "restore" ]]; then
87 sourceHost=${sourceHost%/}
88 backup_target="${sourceHost}/backups"
89 folder="$backup_target/last"
90 printf "Restoring backup %s\n" "$(readlink -e -- "$folder")"
91 tar tf "$folder/pg_wal.tar.gz"
92 while ! [[ -f "$folder/pg_base.tar.gz" ]]; do
94 printf "Requires backup %s\n" "$(readlink -e -- "$folder")"
95 tar tf "$folder/pg_wal.tar.gz"
97 #tar tf "$folder/pg_base.tar.gz"
98 printf "restore\n" >&${COPROC[1]}
99 read -r reply <&${COPROC[0]} || exit 1;
100 if [[ $reply != "postgres base" ]]; then
101 printf "Service is not ready to receive backup: %s\n" "$reply"
105 chunked < "$folder/pg_base.tar.gz" >&${COPROC[1]}
106 echo "done sending base"
107 folder="$backup_target/last"
109 read -r reply <&${COPROC[0]} || exit 1;
110 if [[ $reply != "incremental?" ]]; then
111 printf "Service is not ready to receive backup: %s\n" "$reply"
114 printf "y\n" >&${COPROC[1]}
115 printf "Sending pg_wal from %s\n" "$(readlink -e -- "$folder")"
116 chunked < "$folder/pg_wal.tar.gz" >&${COPROC[1]}
117 if [[ -f "$folder/pg_base.tar.gz" ]]; then
120 folder="$folder/prev"
122 read -r reply <&${COPROC[0]} || exit 1;
123 if [[ $reply != "incremental?" ]]; then
124 printf "Service is not ready to receive backup: %s\n" "$reply"
127 printf "n\n" >&${COPROC[1]}
128 elif [[ "$2" == "backup" ]]; then
132 printf "Error, unknown sub command: %s\n" "$2" >&2
136 printf "end\n" >&${COPROC[1]}
137 read -r line <&${COPROC[0]} || exit 1;
138 printf "END: %s\n" "$line"