Commit a8ba07d5 authored by Kirill Smelkov's avatar Kirill Smelkov

gitlab-backup/restore: Allow restoration on higher GitLab version, if user requests so

Currently GitLab backup restoration works on exactly the same GitLab
version, as the one with which the backup was made:

    https://gitlab.com/gitlab-org/gitlab-ce/blob/7383453b/lib/backup/manager.rb#L132

However in many cases restoring backup on a newer GitLab version is
desirable - e.g. when moving GitLab instance to upgraded software.
GitLab answer - that we should first prepare exactly the same GitLab
version on moved instance, restore backup, then upgrade GitLab itself
_inplace_, is not satisfactory in e.g. slapos case - as upgrading can
take a long time, and in-place software changes can render GitLab
instance non-working.

What we better prefer to do is to fully prepare new GitLab software
version, and then knowing software is ready, restore backup in a quick
manner.

The following analysis says we should be 99% ok to do so:

1. git-backup cares backward compatibility for format of repositories backup.
2. db dump is backward compatible, because Rails, when seeing old db
   schema, will run migrations.
3. the rest is relatively minor - e.g. uploads, which is just files in
   tar, and format for such things changes seldomly.

because of 3, strictly speaking, it is not 100% correct to restore
backup from older gitlab version to newer one (since gitlab does not
provide a promise of backward compatibility on e.g. uploads/ backup
format) , but in practice it is 99% correct and is usually handy.

/cc @kazuhiko
parent 48062989
...@@ -18,6 +18,7 @@ die() { ...@@ -18,6 +18,7 @@ die() {
} }
GITLAB_VERSION=
GITLAB_BACKUP_PATH= GITLAB_BACKUP_PATH=
GITLAB_REPOS_PATH= GITLAB_REPOS_PATH=
GITLAB_HOOKS_PATH= GITLAB_HOOKS_PATH=
...@@ -34,6 +35,7 @@ need_gitlab_config() { ...@@ -34,6 +35,7 @@ need_gitlab_config() {
# various gitlab config values extracted in 1 go (gitlab is very slow to load) # various gitlab config values extracted in 1 go (gitlab is very slow to load)
{ {
read GITLAB_VERSION
read GITLAB_BACKUP_PATH read GITLAB_BACKUP_PATH
read GITLAB_REPOS_PATH read GITLAB_REPOS_PATH
read GITLAB_HOOKS_PATH read GITLAB_HOOKS_PATH
...@@ -52,7 +54,7 @@ need_gitlab_config() { ...@@ -52,7 +54,7 @@ need_gitlab_config() {
} < <(gitlab-rails r ' } < <(gitlab-rails r '
c = Gitlab.config c = Gitlab.config
s = c.gitlab_shell s = c.gitlab_shell
puts c.backup.path, s.repos_path, s.hooks_path puts Gitlab::VERSION, c.backup.path, s.repos_path, s.hooks_path
c = Backup::Database.new.config c = Backup::Database.new.config
puts c["database"] puts c["database"]
...@@ -184,6 +186,7 @@ backup_pull() { ...@@ -184,6 +186,7 @@ backup_pull() {
backup_restore() { backup_restore() {
HEAD=$1 HEAD=$1
vupok=$2
need_gitlab_config need_gitlab_config
...@@ -230,6 +233,26 @@ backup_restore() { ...@@ -230,6 +233,26 @@ backup_restore() {
gzip "$tmpd/gitlab_backup/db/database.sql" # gzip sql dump, as gitlab expects .gz gzip "$tmpd/gitlab_backup/db/database.sql" # gzip sql dump, as gitlab expects .gz
# tweak gitlab_version in backup_information.yml if vup is ok
# ( rationale for doing so:
# 1. git-backup cares backward compatibility for format of repositories backup.
# 2. db dump is backward compatible, because Rails, when seeing old db
# schema, will run migrations.
# 3. the rest is relatively minor - e.g. uploads, which is just files in
# tar, and format for such things changes seldomly.
#
# because of 3, strictly speaking, it is not 100% correct to restore
# backup from older gitlab version to newer one, but in practice it is
# 99% correct and is usually handy. )
if [ $vupok = y ]; then
# put current gitlab version into backup_information.yml if it is >=
# gitlab version used at backup time.
backup_gitlab_version=`grep "^:gitlab_version:" "$backup_info" | sed -e 's/:gitlab_version:\s*//'`
if echo -e "$backup_gitlab_version\n$GITLAB_VERSION" | sort -V -C ; then
sed -i -e "s/^:gitlab_version:.*\$/:gitlab_version: $GITLAB_VERSION/" "$backup_info"
fi
fi
# 2. find out backup timestamp as saved by gitlab # 2. find out backup timestamp as saved by gitlab
backup_created_at=`grep :backup_created_at: "$backup_info" | backup_created_at=`grep :backup_created_at: "$backup_info" |
sed -e s'/:backup_created_at: //'` sed -e s'/:backup_created_at: //'`
...@@ -297,7 +320,7 @@ umask 0077 # XXX maybe not good - e.g. git-data/repositories should (?) be rw ...@@ -297,7 +320,7 @@ umask 0077 # XXX maybe not good - e.g. git-data/repositories should (?) be rw
usage() { usage() {
echo "Usage: gitlab-backup [pull | restore <commit-ish>]" echo "Usage: gitlab-backup [pull | restore (-vupok) <commit-ish>]"
} }
...@@ -310,8 +333,24 @@ case "$action" in ...@@ -310,8 +333,24 @@ case "$action" in
backup_pull backup_pull
;; ;;
restore) restore)
vupok=n # gitlab version >= backup's gitlab version is ok
while test $# != 0; do
case "$1" in
-vupok)
vupok=y
;;
-*)
die `usage`
;;
*)
break
;;
esac
shift
done
test $# -lt 1 && die `usage` test $# -lt 1 && die `usage`
backup_restore "$1" backup_restore "$1" $vupok
;; ;;
-h) -h)
usage usage
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment