summaryrefslogtreecommitdiff
path: root/extensions/ssh-rsync.write
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/ssh-rsync.write')
-rwxr-xr-xextensions/ssh-rsync.write175
1 files changed, 0 insertions, 175 deletions
diff --git a/extensions/ssh-rsync.write b/extensions/ssh-rsync.write
deleted file mode 100755
index 1045c528..00000000
--- a/extensions/ssh-rsync.write
+++ /dev/null
@@ -1,175 +0,0 @@
-#!/usr/bin/python2
-# Copyright (C) 2013-2015 Codethink Limited
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; version 2 of the License.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
-'''A Morph deployment write extension for upgrading systems over ssh.'''
-
-
-import contextlib
-import os
-import subprocess
-import sys
-import tempfile
-import time
-
-import writeexts
-
-
-def ssh_runcmd_ignore_failure(location, command, **kwargs):
- try:
- return writeexts.ssh_runcmd(location, command, **kwargs)
- except writeexts.ExtensionError:
- pass
-
-
-class SshRsyncWriteExtension(writeexts.WriteExtension):
-
- '''See ssh-rsync.write.help for documentation'''
-
-
- def find_root_disk(self, location):
- '''Read /proc/mounts on location to find which device contains "/"'''
-
- self.status(msg='Finding device that contains "/"')
- contents = writeexts.ssh_runcmd(location,
- ['cat', '/proc/mounts'])
- for line in contents.splitlines():
- line_words = line.split()
- if (line_words[1] == '/' and line_words[0] != 'rootfs'):
- return line_words[0]
-
- @contextlib.contextmanager
- def _remote_mount_point(self, location):
- self.status(msg='Creating remote mount point')
- remote_mnt = writeexts.ssh_runcmd(location,
- ['mktemp', '-d']).strip()
- try:
- yield remote_mnt
- finally:
- self.status(msg='Removing remote mount point')
- writeexts.ssh_runcmd(location, ['rmdir', remote_mnt])
-
- @contextlib.contextmanager
- def _remote_mount(self, location, root_disk, mountpoint):
- self.status(msg='Mounting root disk')
- writeexts.ssh_runcmd(location, ['mount', root_disk, mountpoint])
- try:
- yield
- finally:
- self.status(msg='Unmounting root disk')
- writeexts.ssh_runcmd(location, ['umount', mountpoint])
-
- @contextlib.contextmanager
- def _created_version_root(self, location, remote_mnt, version_label):
- version_root = os.path.join(remote_mnt, 'systems', version_label)
- self.status(msg='Creating %(root)s', root=version_root)
- writeexts.ssh_runcmd(location, ['mkdir', version_root])
- try:
- yield version_root
- except BaseException as e:
- # catch all, we always want to clean up
- self.status(msg='Cleaning up %(root)s', root=version_root)
- ssh_runcmd_ignore_failure(location, ['rmdir', version_root])
- raise
-
- def get_old_orig(self, location, remote_mnt):
- '''Identify which subvolume to snapshot from'''
-
- # rawdisk upgrades use 'default'
- return os.path.join(remote_mnt, 'systems', 'default', 'orig')
-
- @contextlib.contextmanager
- def _created_orig_subvolume(self, location, remote_mnt, version_root):
- self.status(msg='Creating "orig" subvolume')
- old_orig = self.get_old_orig(location, remote_mnt)
- new_orig = os.path.join(version_root, 'orig')
- writeexts.ssh_runcmd(location, ['btrfs', 'subvolume', 'snapshot',
- old_orig, new_orig])
- try:
- yield new_orig
- except BaseException as e:
- ssh_runcmd_ignore_failure(
- location, ['btrfs', 'subvolume', 'delete', new_orig])
- raise
-
- def populate_remote_orig(self, location, new_orig, temp_root):
- '''Populate the subvolume version_root/orig on location'''
-
- self.status(msg='Populating "orig" subvolume')
- subprocess.check_call(['rsync', '-as', '--checksum', '--numeric-ids',
- '--delete', temp_root + os.path.sep,
- '%s:%s' % (location, new_orig)])
-
- @contextlib.contextmanager
- def _deployed_version(self, location, version_label,
- system_config_sync, system_version_manager):
- self.status(msg='Calling system-version-manager to deploy upgrade')
- deployment = os.path.join('/systems', version_label, 'orig')
- writeexts.ssh_runcmd(location,
- ['env', 'BASEROCK_SYSTEM_CONFIG_SYNC='+system_config_sync,
- system_version_manager, 'deploy', deployment])
- try:
- yield deployment
- except BaseException as e:
- self.status(msg='Cleaning up failed version installation')
- writeexts.ssh_runcmd(location,
- [system_version_manager, 'remove', version_label])
- raise
-
- def upgrade_remote_system(self, location, temp_root):
- root_disk = self.find_root_disk(location)
- uuid = writeexts.ssh_runcmd(location,
- ['blkid', '-s', 'UUID', '-o', 'value', root_disk]).strip()
-
- self.complete_fstab_for_btrfs_layout(temp_root, uuid)
-
- version_label = os.environ['VERSION_LABEL']
- autostart = self.get_environment_boolean('AUTOSTART')
-
- with self._remote_mount_point(location) as remote_mnt, \
- self._remote_mount(location, root_disk, remote_mnt), \
- self._created_version_root(location, remote_mnt,
- version_label) as version_root, \
- self._created_orig_subvolume(location, remote_mnt,
- version_root) as orig:
- self.populate_remote_orig(location, orig, temp_root)
- system_root = os.path.join(remote_mnt, 'systems',
- version_label, 'orig')
- config_sync = os.path.join(system_root, 'usr', 'bin',
- 'baserock-system-config-sync')
- version_manager = os.path.join(system_root, 'usr', 'bin',
- 'system-version-manager')
- with self._deployed_version(location, version_label,
- config_sync, version_manager):
- self.status(msg='Setting %(v)s as the new default system',
- v=version_label)
- writeexts.ssh_runcmd(location,
- [version_manager, 'set-default', version_label])
-
- if autostart:
- self.status(msg="Rebooting into new system ...")
- ssh_runcmd_ignore_failure(location, ['reboot'])
-
- def process_args(self, args):
- if len(args) != 2:
- raise writeexts.ExtensionError(
- 'Wrong number of command line args')
-
- temp_root, location = args
-
- self.upgrade_remote_system(location, temp_root)
-
-
-SshRsyncWriteExtension().run()