runner-export.sh.jinja2 4.34 KB
Newer Older
1
#!{{ shell_binary }}
2 3
LC_ALL=C
export LC_ALL
4
umask 077
5

6
# Exit on any error, to prevent inconsistent backup
7 8
# Error on unset variable expansion
set -eu
9
set -o pipefail
10

11
# Redirect output to log
12
exec > >(tee -ai '{{ output_log_file }}')
13 14 15 16
exec 2>&1

echo -e "\n\n$0 run at : $(date)"

17 18 19 20
srv_directory='{{ directory["srv"] }}'
backup_directory='{{ directory["backup"] }}'
etc_directory='{{ directory["etc"] }}'
tmp_directory='{{ directory["tmp"] }}'
21

22
rsync () {
23 24 25 26
  # Workaround for bug https://bugzilla.samba.org/show_bug.cgi?id=3653
  IGNOREEXIT=24
  IGNOREOUT='^(file has vanished: |rsync warning: some files vanished before they could be transferred)'

27
  set -x
28
  '{{ rsync_binary }}' -rlptgov --stats --safe-links --ignore-missing-args --delete --delete-excluded "$@" 2>&1 | (egrep -v "$IGNOREOUT" || true) || [ $? = "$IGNOREEXIT" ]
29 30
  set +x
}
31

32
(
33
  # XXX: code duplication with runner-import.sh.jinja2
34 35 36 37 38 39 40
  path=$srv_directory/runner
  backup_path=$backup_directory/runner/
  cd "$path"

  if [ -d instance ]; then
    # Concatenate the exclude file of each partition of webrunner
    # to create a global exclude file.
41
    # Also, ignore all buildout-managed files.
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58
    exclude=$({{ sys.executable }} - "$path" <<EOF
if 1:
        import glob, errno, os, sys
        sys.path[:0] = {{ repr(easy_install.buildout_and_setuptools_path) }}
        from zc.buildout.configparser import parse
        path = sys.argv[1]

        def print_relative(path_list):
            for p in path_list:
                p = p.strip()
                if p:
                    print(os.path.relpath(p, path))
        print("*.sock")
        print("*.socket")
        print("*.pid")
        print(".installed*.cfg")
        for partition in glob.glob(path + "/instance/slappart*"):
59 60 61 62 63 64
            try:
              os.chdir(partition)
            except OSError as e:
              if e.errno != errno.ENOTDIR:
                raise
              continue
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
            try:
                with open("srv/exporter.exclude") as f:
                    exclude = f.readlines()
            except IOError as e:
                if e.errno != errno.ENOENT:
                    raise
            else:
                print_relative(exclude)
            for installed in glob.glob(".installed*.cfg"):
                try:
                    with open(installed) as f:
                        installed = parse(f, installed)
                except IOError as e:
                    if e.errno != errno.ENOENT:
                        raise
                else:
                    for section in installed.itervalues():
                        print_relative(section.get(
                            '__buildout_installed__', '').splitlines())
EOF
)
    echo "$exclude" |rsync --exclude-from=- instance "$backup_path"
87 88
  fi

89 90 91
  test -d project  && rsync project "$backup_path"
  test -d public  && rsync public "$backup_path"
  test -f proxy.db && rsync proxy.db "$backup_path"
92
)
93
# We sync .* appart
94 95 96 97 98 99 100 101 102
(
  cd "$etc_directory"
  date +%s -u > .resilient-timestamp
  rsync config.json "$backup_directory"/etc/
  # Hidden files are related to the webrunner's internals
  cp -r .??* "$backup_directory/etc/"
)
if [ -d "$backup_directory"/runner/software ]; then
  rm "$backup_directory"/runner/software/*
103
fi
104

105 106
(
  cd "$backup_directory"
107
  find -type f ! -name backup.signature -print0 | xargs -0 sha256sum | sort -k 66 > backup.signature
108
)
109 110

# Check that export didn't happen during backup of instances
111
tmp_backup_sum=$(mktemp -p "$tmp_directory")
112 113

remove_tmp_files () {
114
  rm "$tmp_backup_sum"
115 116 117
}
trap remove_tmp_files EXIT

118 119 120 121 122
cd {{ directory['backup'] }}

# Wait a little to increase the probability to detect an ongoing backup.
sleep 5

123 124
# Getting files from runner backup directory, as instance backup files may be
# explicitely excluded from the backup, using the srv/exporter.exclude
125
find -path "./runner/instance/slappart*/srv/backup/*" -type f ! -name backup.signature -print0 |
126
xargs -r0 sha256sum | sort -k 66 > "$tmp_backup_sum"
127 128

# If no backup found, it's over
129
if [ ! -s "$tmp_backup_sum" ]; then
130 131 132 133
  exit 0
fi

# If the diff fails, then the notifier will restart this script
134 135 136 137 138 139 140
grep "instance/slappart.*/srv/backup/" "$backup_directory/backup.signature" |
diff "$tmp_backup_sum" - || {
  echo "ERROR: Some backups are not consistent, exporter should be re-run."
  echo "Let's sleep {{ backup_wait_time }} minutes, to let the backup end..."
  sleep {{ backup_wait_time }}m
  exit 1
}