summaryrefslogtreecommitdiff
path: root/parabola-mirror
blob: 96f024f3418e3455a10209e4f1e765dd426fbfe4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/bin/bash

# alfplayer
# 2014-06-12
#
# Mirror the whole Parabola repository using rsync and keep snapshots

set -e

script_filename="$(basename "$0")"

# Default configuration values.
# They can be overridden by setting the variables in the calling environment.
# 1 to set, 0 to unset
: ${repo:=rsync://repo.parabola.nu:875/repos}
: ${base_dir:=/srv/http}
: ${parabola_dir:=${base_dir}/parabola}
: ${oldest_version:=10}    # snapshots older than this one will be deleted (see also no_delete above)
#: ${date_exclude:=2014.06.19}    # disable running this script this date (see next line)
: ${forcerun:=0}    # force running on excluded date
#: ${terminal:=1}    # outputs to stdout using rsync --progress (and logs to a file)
: ${no_delete:=0}    # disable deletion of oldest snapshots
#: ${TZ:=UTC}      # set time zone

export TZ

# Lock with flock (provided by util-linux)
LOCKFILE="/var/lock/${script_filename}"
LOCKFD=99

_lock()             { flock -$1 $LOCKFD; }

_no_more_locking()  {
    set +e

    # Save exit status
    es=$?

    if [[ -e ${parabola_dir}.tmp ]] ; then
	echo "=> WARNING: Directory with partial transfer ${LOCAL}.tmp remains in file system"
    fi

    if [[ $es != 0 ]] ; then
        echo "=> ERROR: Unsuccessful script termination. Exit status: $es"
        fi
    fi

    _lock u
    _lock xn && \
	rm -f $LOCKFILE
}

_prepare_locking()  { eval "exec $LOCKFD>\"$LOCKFILE\""; trap _no_more_locking EXIT; }

_prepare_locking

# Lock now. The lock is disabled automatically when the script exits (with any error code).
if ! _lock xn ; then
    echo "=> ERROR: Could not obtain lock. Exiting." >&2
    exit 1
fi

date="$(date +%Y.%m.%d)"
current="${parabola_dir}-${date}"
local_useful=0


if [[ ${date_exclude} && ${forcerun} != 1 ]] ; then
    if [[ $DATE == ${date_exclude} ]] ; then
	echo "Manually disabled: ${date}. Exiting."
	exit 0
    fi
fi

# Test if ${parabola_dir} is an existing symlink pointing to an existing directory
if [[ -h ${parabola_dir} ]] ; then
  last_path="$(readlink -f "${parabola_dir}")"
  if [[ -d ${last_path} ]] ; then
    last="${last_path##*/}"
    local_useful=1
  else
    echo "=> ERROR: ${parabola_dir} is a symlink which does not point to an existing directory." >&2
    exit 1
  fi
else
  echo "=> ERROR: ${parabola_dir} does not exist or is not a symlink." >&2
  exit 1
fi


echo
echo "=> Creating snapshot for date ${date}"

if [[ -e "${current}" ]] ; then
  echo "${current} already exists. Exiting." >&2
  exit 1
fi

if [[ -e "${parabola_dir}".tmp ]] ; then
  echo "${parabola_dir}.tmp already exists. Resuming."
else
  cp -al "${last_path}" "${parabola_dir}".tmp
fi


rsync "${repo}"/ -rtvlH ${terminal:+--progress} --safe-links --delete --link-dest="$base_dir"/archlinux/ --link-dest="$parabola_dir" "$parabola_dir".tmp

cd "$base_dir"

echo "=> Delete versions older than the ${oldest_version} oldest version"
delete_list=( $(for dir in parabola-* ; do echo "$(find "$dir" -type f -printf '%T@\n' | sort -n | tail -1) $dir" ; done | awk '{print $2}' | head -n -"${oldest_version}") )

for dir in ${delete_list[@]} ; do
    if [[ ${no_delete} != 1 ]] ; then
        echo "$dir"
        rm -rf "$dir"
    else
	echo "DRY-RUN: rm -rf $dir"
    fi
done

echo "=> Start serving the new repository version"
mv "${parabola_dir}.tmp" "${current}"

if [[ ${local_useful} == 1 ]] ; then
    echo "  => Deleting ${parabola_dir} symlink"
    rm -rf "${parabola_dir}"
fi

# Create symlink
echo "  => Creating symlink ${current} to ${parabola_dir}"
ln -s ${current##*/} ${parabola_dir}

echo "=> Disk space report"
df -h "${base_dir}"

echo "=> ${script_filename} finished successfully. Finish time: $(date --rfc-3339=seconds)"