From 4581d2ed753dc6e7e63cdefd5fcc68b7a4c4e3c9 Mon Sep 17 00:00:00 2001 From: Sam Thursfield Date: Tue, 18 Mar 2014 17:32:59 +0000 Subject: Make sanity checks for nfsboot deployments run earlier Move some code to the '.check' extension to verify that the deployment can happen *before* spending 5 minutes unpacking and configuring the rootfs. This is not a perfect solution yet because when multiple systems are being deployed in a cluster, we do not check all systems and then deploy them all. Instead, we check one, then deploy it, then check the second, etc. --- morphlib/exts/nfsboot.check | 66 +++++++++++++++++++++++++++++++++++++++++++++ morphlib/exts/nfsboot.write | 59 +++------------------------------------- 2 files changed, 70 insertions(+), 55 deletions(-) diff --git a/morphlib/exts/nfsboot.check b/morphlib/exts/nfsboot.check index 092a1df7..e240dd72 100755 --- a/morphlib/exts/nfsboot.check +++ b/morphlib/exts/nfsboot.check @@ -17,18 +17,84 @@ '''Preparatory checks for Morph 'nfsboot' write extension''' import cliapp +import os import morphlib.writeexts class NFSBootCheckExtension(morphlib.writeexts.WriteExtension): + + _nfsboot_root = '/srv/nfsboot' + def process_args(self, args): if len(args) != 1: raise cliapp.AppException('Wrong number of command line args') + location = args[0] + upgrade = self.get_environment_boolean('UPGRADE') if upgrade: raise cliapp.AppException( 'Upgrading is not currently supported for NFS deployments.') + hostname = os.environ.get('HOSTNAME', None) + if hostname is None: + raise cliapp.AppException('You must specify a HOSTNAME.') + if hostname == 'baserock': + raise cliapp.AppException('It is forbidden to nfsboot a system ' + 'with hostname "%s"' % hostname) + + self.test_good_server(location) + + version_label = os.getenv('VERSION_LABEL', 'factory') + versioned_root = os.path.join(self._nfsboot_root, hostname, 'systems', + version_label) + if self.version_exists(versioned_root, location): + raise cliapp.AppException( + 'Root file system for host %s (version %s) already exists on ' + 'the NFS server %s. Deployment aborted.' % (hostname, + version_label, location)) + + def test_good_server(self, server): + # Can be ssh'ed into + try: + cliapp.ssh_runcmd('root@%s' % server, ['true']) + except cliapp.AppException: + raise cliapp.AppException('You are unable to ssh into server %s' + % server) + + # Is an NFS server + try: + cliapp.ssh_runcmd( + 'root@%s' % server, ['test', '-e', '/etc/exports']) + except cliapp.AppException: + raise cliapp.AppException('server %s is not an nfs server' + % server) + try: + cliapp.ssh_runcmd( + 'root@%s' % server, ['systemctl', 'is-enabled', + 'nfs-server.service']) + + except cliapp.AppException: + raise cliapp.AppException('server %s does not control its ' + 'nfs server by systemd' % server) + + # TFTP server exports /srv/nfsboot/tftp + try: + cliapp.ssh_runcmd( + 'root@%s' % server, ['test' , '-d', '/srv/nfsboot/tftp']) + except cliapp.AppException: + raise cliapp.AppException('server %s does not export ' + '/srv/nfsboot/tftp' % server) + + def version_exists(self, versioned_root, location): + try: + cliapp.ssh_runcmd('root@%s' % location, + ['test', '-d', versioned_root]) + except cliapp.AppException: + return False + + return True + + NFSBootCheckExtension().run() diff --git a/morphlib/exts/nfsboot.write b/morphlib/exts/nfsboot.write index 34a72972..3bb66821 100755 --- a/morphlib/exts/nfsboot.write +++ b/morphlib/exts/nfsboot.write @@ -1,5 +1,5 @@ #!/usr/bin/python -# Copyright (C) 2013 Codethink Limited +# Copyright (C) 2013-2014 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 @@ -60,38 +60,18 @@ class NFSBootWriteExtension(morphlib.writeexts.WriteExtension): raise cliapp.AppException('Wrong number of command line args') temp_root, location = args - hostname = self.get_hostname(temp_root) - if hostname == 'baserock': - raise cliapp.AppException('It is forbidden to nfsboot a system ' - 'with hostname "baserock"') - self.test_good_server(location) version_label = os.getenv('VERSION_LABEL', 'factory') + hostname = os.environ.get('HOSTNAME') + versioned_root = os.path.join(self._nfsboot_root, hostname, 'systems', version_label) - if self.version_exists(versioned_root, location): - raise cliapp.AppException('Version %s already exists on' - ' this device. Deployment aborted' - % version_label) + self.copy_rootfs(temp_root, location, versioned_root, hostname) self.copy_kernel(temp_root, location, versioned_root, version_label, hostname) self.configure_nfs(location, hostname) - def version_exists(self, versioned_root, location): - try: - cliapp.ssh_runcmd('root@%s' % location, - ['test', '-d', versioned_root]) - except cliapp.AppException: - return False - - return True - - def get_hostname(self, temp_root): - hostnamepath = os.path.join(temp_root, 'etc', 'hostname') - with open(hostnamepath) as f: - return f.readline().strip() - def create_local_state(self, location, hostname): statedir = os.path.join(self._nfsboot_root, hostname, 'state') subdirs = [os.path.join(statedir, 'home'), @@ -209,37 +189,6 @@ mv "$temp" "$target" 'root@%s' % location, ['systemctl', 'restart', 'nfs-server.service']) - def test_good_server(self, server): - # Can be ssh'ed into - try: - cliapp.ssh_runcmd('root@%s' % server, ['true']) - except cliapp.AppException: - raise cliapp.AppException('You are unable to ssh into server %s' - % server) - - # Is an NFS server - try: - cliapp.ssh_runcmd( - 'root@%s' % server, ['test', '-e', '/etc/exports']) - except cliapp.AppException: - raise cliapp.AppException('server %s is not an nfs server' - % server) - try: - cliapp.ssh_runcmd( - 'root@%s' % server, ['systemctl', 'is-enabled', - 'nfs-server.service']) - - except cliapp.AppException: - raise cliapp.AppException('server %s does not control its ' - 'nfs server by systemd' % server) - - # TFTP server exports /srv/nfsboot/tftp - try: - cliapp.ssh_runcmd( - 'root@%s' % server, ['test' , '-d', '/srv/nfsboot/tftp']) - except cliapp.AppException: - raise cliapp.AppException('server %s does not export ' - '/srv/nfsboot/tftp' % server) NFSBootWriteExtension().run() -- cgit v1.2.1