From fce2e2a7649934636338939244723d3c3ea460b5 Mon Sep 17 00:00:00 2001 From: Dmitry Bilunov Date: Wed, 20 Jan 2016 17:27:57 +0300 Subject: [PATCH] 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 --- files/fuel-docker-utils/functions.sh | 51 ++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) diff --git a/files/fuel-docker-utils/functions.sh b/files/fuel-docker-utils/functions.sh index 2d51edbceb..ca106e3432 100644 --- a/files/fuel-docker-utils/functions.sh +++ b/files/fuel-docker-utils/functions.sh @@ -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..."