From: Sage Weil Date: Thu, 7 Mar 2013 01:42:04 +0000 (-0800) Subject: avoid overwriting a modified ceph.conf without --overwrite-conf X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=8b43307fd440a978e83818e128b383d0c24bdad7;p=ceph-deploy.git avoid overwriting a modified ceph.conf without --overwrite-conf While we're at it, continue with mon/osd/mds creations if there is a failure, but return an error at the end. Signed-off-by: Sage Weil --- diff --git a/ceph_deploy/cli.py b/ceph_deploy/cli.py index 4d0bf95..8961afe 100644 --- a/ceph_deploy/cli.py +++ b/ceph_deploy/cli.py @@ -31,6 +31,11 @@ def parse_args(args=None, namespace=None): action='store_true', dest='dry_run', help='do not perform any action, but report what would be done', ) + parser.add_argument( + '--overwrite-conf', + action='store_true', + help='overwrite an existing conf file on remote host (if present)', + ) parser.add_argument( '--cluster', metavar='NAME', diff --git a/ceph_deploy/conf.py b/ceph_deploy/conf.py index fcd08e0..1b67cfe 100644 --- a/ceph_deploy/conf.py +++ b/ceph_deploy/conf.py @@ -36,3 +36,21 @@ def load(args): else: with contextlib.closing(f): return parse(f) + + +def write_conf(cluster, conf, overwrite): + import os + + path = '/etc/ceph/{cluster}.conf'.format(cluster=cluster) + tmp = '{path}.{pid}.tmp'.format(path=path, pid=os.getpid()) + + if os.path.exists(path): + with file(path, 'rb') as f: + old = f.read() + if old != conf and not overwrite: + raise RuntimeError('config file %s exists with different content; use --overwrite-conf to overwrite' % path) + with file(tmp, 'w') as f: + f.write(conf) + f.flush() + os.fsync(f) + os.rename(tmp, path) diff --git a/ceph_deploy/mds.py b/ceph_deploy/mds.py index 08a54dd..98df247 100644 --- a/ceph_deploy/mds.py +++ b/ceph_deploy/mds.py @@ -25,19 +25,6 @@ def get_bootstrap_mds_key(cluster): raise RuntimeError('bootstrap-mds keyring not found; run \'gatherkeys\'') -def write_conf(cluster, conf): - import os - - path = '/etc/ceph/{cluster}.conf'.format(cluster=cluster) - tmp = '{path}.{pid}.tmp'.format(path=path, pid=os.getpid()) - - with file(tmp, 'w') as f: - f.write(conf) - f.flush() - os.fsync(f) - os.rename(tmp, path) - - def create_mds_bootstrap(cluster, key): """ Run on mds node, writes the bootstrap key if not there yet. @@ -155,46 +142,54 @@ def mds_create(args): key = get_bootstrap_mds_key(cluster=args.cluster) bootstrapped = set() + errors = 0 for hostname, name in args.mds: - - # TODO username - sudo = args.pushy('ssh+sudo:{hostname}'.format(hostname=hostname)) - - lsb_release_r = sudo.compile(lsb.lsb_release) - (distro, release, codename) = lsb_release_r() - init = lsb.choose_init(distro, codename) - log.debug('Distro %s codename %s, will use %s', - distro, codename, init) - - if hostname not in bootstrapped: - bootstrapped.add(hostname) - log.debug('Deploying mds bootstrap to %s', hostname) - - write_conf_r = sudo.compile(write_conf) - conf_data = StringIO() - cfg.write(conf_data) - write_conf_r( + try: + # TODO username + sudo = args.pushy('ssh+sudo:{hostname}'.format(hostname=hostname)) + + lsb_release_r = sudo.compile(lsb.lsb_release) + (distro, release, codename) = lsb_release_r() + init = lsb.choose_init(distro, codename) + log.debug('Distro %s codename %s, will use %s', + distro, codename, init) + + if hostname not in bootstrapped: + bootstrapped.add(hostname) + log.debug('Deploying mds bootstrap to %s', hostname) + + write_conf_r = sudo.compile(conf.write_conf) + conf_data = StringIO() + cfg.write(conf_data) + write_conf_r( + cluster=args.cluster, + conf=conf_data.getvalue(), + overwrite=args.overwrite_conf, + ) + + create_mds_bootstrap_r = sudo.compile(create_mds_bootstrap) + error = create_mds_bootstrap_r( + cluster=args.cluster, + key=key, + ) + if error is not None: + raise exc.GenericError(error) + log.debug('Host %s is now ready for MDS use.', hostname) + + # create an mds + log.debug('Deploying mds.%s to %s', name, hostname) + create_mds_r = sudo.compile(create_mds) + create_mds_r( + name=name, cluster=args.cluster, - conf=conf_data.getvalue(), + init=init, ) + except RuntimeError as e: + log.error(e) + errors += 1 - create_mds_bootstrap_r = sudo.compile(create_mds_bootstrap) - error = create_mds_bootstrap_r( - cluster=args.cluster, - key=key, - ) - if error is not None: - raise exc.GenericError(error) - log.debug('Host %s is now ready for MDS use.', hostname) - - # create an mds - log.debug('Deploying mds.%s to %s', name, hostname) - create_mds_r = sudo.compile(create_mds) - create_mds_r( - name=name, - cluster=args.cluster, - init=init, - ) + if errors: + raise exc.GenericError('Failed to create %d MDSs' % errors) def mds(args): diff --git a/ceph_deploy/mon.py b/ceph_deploy/mon.py index d3135f1..9eb1a86 100644 --- a/ceph_deploy/mon.py +++ b/ceph_deploy/mon.py @@ -13,19 +13,6 @@ from .cliutil import priority log = logging.getLogger(__name__) -def write_conf(cluster, conf): - import os - - path = '/etc/ceph/{cluster}.conf'.format(cluster=cluster) - tmp = '{path}.{pid}.tmp'.format(path=path, pid=os.getpid()) - - with file(tmp, 'w') as f: - f.write(conf) - f.flush() - os.fsync(f) - os.rename(tmp, path) - - def create_mon(cluster, monitor_keyring, init): import os import socket @@ -120,34 +107,44 @@ def mon_create(args): ' '.join(args.mon), ) + errors = 0 for hostname in args.mon: - log.debug('Deploying mon to %s', hostname) - - # TODO username - sudo = args.pushy('ssh+sudo:{hostname}'.format(hostname=hostname)) - - lsb_release_r = sudo.compile(lsb.lsb_release) - (distro, release, codename) = lsb_release_r() - init = lsb.choose_init(distro, codename) - log.debug('Distro %s codename %s, will use %s', - distro, codename, init) - - write_conf_r = sudo.compile(write_conf) - conf_data = StringIO() - cfg.write(conf_data) - write_conf_r( - cluster=args.cluster, - conf=conf_data.getvalue(), - ) - - create_mon_r = sudo.compile(create_mon) - create_mon_r( - cluster=args.cluster, - monitor_keyring=monitor_keyring, - init=init, - ) - - # TODO add_bootstrap_peer_hint + try: + log.debug('Deploying mon to %s', hostname) + + # TODO username + sudo = args.pushy('ssh+sudo:{hostname}'.format(hostname=hostname)) + + lsb_release_r = sudo.compile(lsb.lsb_release) + (distro, release, codename) = lsb_release_r() + init = lsb.choose_init(distro, codename) + log.debug('Distro %s codename %s, will use %s', + distro, codename, init) + + write_conf_r = sudo.compile(conf.write_conf) + conf_data = StringIO() + cfg.write(conf_data) + write_conf_r( + cluster=args.cluster, + conf=conf_data.getvalue(), + overwrite=args.overwrite_conf, + ) + + create_mon_r = sudo.compile(create_mon) + create_mon_r( + cluster=args.cluster, + monitor_keyring=monitor_keyring, + init=init, + ) + + # TODO add_bootstrap_peer_hint + + except RuntimeError as e: + log.error(e) + errors += 1 + + if errors: + raise exc.GenericError('Failed to create %d monitors' % errors) def mon(args): if args.subcommand == 'create': diff --git a/ceph_deploy/osd.py b/ceph_deploy/osd.py index 38daaa2..2bcb47d 100644 --- a/ceph_deploy/osd.py +++ b/ceph_deploy/osd.py @@ -26,19 +26,6 @@ def get_bootstrap_osd_key(cluster): except IOError: raise RuntimeError('bootstrap-osd keyring not found; run \'gatherkeys\'') -def write_conf(cluster, conf): - import os - - path = '/etc/ceph/{cluster}.conf'.format(cluster=cluster) - tmp = '{path}.{pid}.tmp'.format(path=path, pid=os.getpid()) - - with file(tmp, 'w') as f: - f.write(conf) - f.flush() - os.fsync(f) - os.rename(tmp, path) - - def create_osd(cluster, key): """ Run on osd node, writes the bootstrap key if not there yet. @@ -147,48 +134,56 @@ def prepare(args, cfg, activate): key = get_bootstrap_osd_key(cluster=args.cluster) bootstrapped = set() + errors = 0 for hostname, disk, journal in args.disk: - - # TODO username - sudo = args.pushy('ssh+sudo:{hostname}'.format( - hostname=hostname, - )) - - if hostname not in bootstrapped: - bootstrapped.add(hostname) - log.debug('Deploying osd to %s', hostname) - - write_conf_r = sudo.compile(write_conf) - conf_data = StringIO() - cfg.write(conf_data) - write_conf_r( - cluster=args.cluster, - conf=conf_data.getvalue(), - ) - - create_osd_r = sudo.compile(create_osd) - error = create_osd_r( + try: + # TODO username + sudo = args.pushy('ssh+sudo:{hostname}'.format( + hostname=hostname, + )) + + if hostname not in bootstrapped: + bootstrapped.add(hostname) + log.debug('Deploying osd to %s', hostname) + + write_conf_r = sudo.compile(conf.write_conf) + conf_data = StringIO() + cfg.write(conf_data) + write_conf_r( + cluster=args.cluster, + conf=conf_data.getvalue(), + overwrite=args.overwrite_conf, + ) + + create_osd_r = sudo.compile(create_osd) + error = create_osd_r( + cluster=args.cluster, + key=key, + ) + if error is not None: + raise exc.GenericError(error) + log.debug('Host %s is now ready for osd use.', hostname) + + log.debug('Preparing host %s disk %s journal %s activate %s', + hostname, disk, journal, activate) + + prepare_disk_r = sudo.compile(prepare_disk) + prepare_disk_r( cluster=args.cluster, - key=key, + disk=disk, + journal=journal, + activate=activate, + zap=args.zap_disk, + dmcrypt=args.dmcrypt, + dmcrypt_dir=args.dmcrypt_key_dir, ) - if error is not None: - raise exc.GenericError(error) - log.debug('Host %s is now ready for osd use.', hostname) - log.debug('Preparing host %s disk %s journal %s activate %s', - hostname, disk, journal, activate) - - prepare_disk_r = sudo.compile(prepare_disk) - prepare_disk_r( - cluster=args.cluster, - disk=disk, - journal=journal, - activate=activate, - zap=args.zap_disk, - dmcrypt=args.dmcrypt, - dmcrypt_dir=args.dmcrypt_key_dir, - ) + except RuntimeError as e: + log.error(e) + errors += 1 + if errors: + raise exc.GenericError('Failed to create %d OSDs' % errors) def activate(args, cfg): log.debug(