dockerctl: Update authorized_keys in bootstrap images during restore

After backup-reinstall-restore Fuel uses bootstrap with wrong ssh keys.

dockerctl backup procedure does not save the bootstrap's root
filesystem, which holds the list of authorized keys that should be
matching the private key located in /root/.ssh on the master.
It would result in inaccessible nodes from a new master installation
(which has bootstrap images regenerated with a new key, not matching
the original one, restored from the backup).

This patch updates authorized_keys inside squashfsed bootstrap images,
so it will be retained during backup-reinstall-restore procedure, if
user has not requested a full backup. Full backups already contain a
full copy of /var/www/nailgun, so no changes are needed.

User should carefully restore from non-full backups - only active
bootstrap will have its ssh keys updated. To propagate ssh keys to
already running nodes, you can use something like:
  mco rpc --agent execute_shell_command --action execute --arg cmd="echo '$(cat /root/.ssh/id_rsa.pub)' >> /root/.ssh/authorized_keys" -v

Change-Id: I3945200d02b29ed10e60900f7d03ed30970159a3
Closes-Bug: #1536198
DocImpact
This commit is contained in:
Dmitry Bilunov 2016-01-20 17:27:57 +03:00
parent 9d6647d561
commit fce2e2a764
1 changed files with 51 additions and 0 deletions

View File

@ -735,6 +735,56 @@ function check_nailgun_tasks {
return $?
}
# Defer expression evaluation until the current subshell exits
function defer {
declare -ga traps
traps[${#traps[*]}]=`trap`
trapcmd="$(printf "%q " "$@"); __finally"
trap "eval eval \"$(printf '"%q" ' "$trapcmd")\"" EXIT
}
# Helper function for "defer"
function __finally {
declare -ga traps
local cmd
cmd="${traps[${#traps[@]}-1]}"
unset traps[${#traps[@]}-1]
eval set -- "${cmd}"
if [ "$1/$2/$4" = "trap/--/EXIT" ]; then
eval "$3" || true
else
eval "${cmd}"
fi
}
function update_ssh_keys {
# Copy masternode's .ssh/id*.pub to all bootstrap images
cat /root/.ssh/id*.pub > /tmp/authorized_keys
SQ_MOUNT_POINT=$(mktemp -d)
sqfs=/var/www/nailgun/bootstraps/active_bootstrap/root.squashfs
test -e /var/www/nailgun/bootstraps/active_bootstrap/root.squashfs || return 0
b=${sqfs#/var/www/nailgun/bootstraps/}
(
set -e
mount -o loop,ro $sqfs $SQ_MOUNT_POINT
defer umount $SQ_MOUNT_POINT
mount -t tmpfs tmpfs $SQ_MOUNT_POINT/mnt
defer umount $SQ_MOUNT_POINT/mnt
mkdir $SQ_MOUNT_POINT/mnt/{bootstraps,src}
defer rmdir $SQ_MOUNT_POINT/mnt/{bootstraps,src}
mount --bind /var/www/nailgun/bootstraps $SQ_MOUNT_POINT/mnt/bootstraps
defer umount $SQ_MOUNT_POINT/mnt/bootstraps
mount --bind $SQ_MOUNT_POINT $SQ_MOUNT_POINT/mnt/src
defer umount $SQ_MOUNT_POINT/mnt/src
COMP=$(chroot $SQ_MOUNT_POINT unsquashfs -s /mnt/bootstraps/$b | awk '/Compression/ { print $2 }')
mount --bind /tmp/authorized_keys $SQ_MOUNT_POINT/root/.ssh/authorized_keys
defer umount $SQ_MOUNT_POINT/root/.ssh/authorized_keys
chroot $SQ_MOUNT_POINT mksquashfs /mnt/src/ /mnt/bootstraps/$b~ -comp $COMP -no-progress -noappend
mv $sqfs~ $sqfs
)
rmdir $SQ_MOUNT_POINT
}
function restore {
#TODO(mattymo): Optionally not include system dirs during restore
#TODO(mattymo): support remote file such as ssh://user@myhost/backup.tar.lrz
@ -782,6 +832,7 @@ finish or cancel them. Run \"fuel task list\" for more details." 1>&2
unpack_archive "$backupfile" "$restoredir"
[ "$fullrestore" == "1" ] && restore_images "$restoredir"
[ "$fullrestore" == "1" ] && rename_images "$timestamp"
[ "$fullrestore" == "1" ] || update_ssh_keys
restore_systemdirs "$restoredir"
set +e
echo "Starting containers..."