From a07858ea34b17fbc448ed4a85662b47858d68a8b Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Mon, 13 Mar 2017 14:04:43 -0400 Subject: [PATCH] mgr: add 'mgr create ...' This is basically a copy of mds.py, with s/mds/mgr/. Signed-off-by: Sage Weil --- ceph_deploy/mgr.py | 223 +++++++++++++++++++++++++++++++++++++++++++++ setup.py | 1 + 2 files changed, 224 insertions(+) create mode 100644 ceph_deploy/mgr.py diff --git a/ceph_deploy/mgr.py b/ceph_deploy/mgr.py new file mode 100644 index 0000000..72046a4 --- /dev/null +++ b/ceph_deploy/mgr.py @@ -0,0 +1,223 @@ +import logging +import os + +from ceph_deploy import conf +from ceph_deploy import exc +from ceph_deploy import hosts +from ceph_deploy.util import system +from ceph_deploy.lib import remoto +from ceph_deploy.cliutil import priority + + +LOG = logging.getLogger(__name__) + + +def get_bootstrap_mgr_key(cluster): + """ + Read the bootstrap-mgr key for `cluster`. + """ + path = '{cluster}.bootstrap-mgr.keyring'.format(cluster=cluster) + try: + with open(path, 'rb') as f: + return f.read() + except IOError: + raise RuntimeError('bootstrap-mgr keyring not found; run \'gatherkeys\'') + + +def create_mgr(distro, name, cluster, init): + conn = distro.conn + + path = '/var/lib/ceph/mgr/{cluster}-{name}'.format( + cluster=cluster, + name=name + ) + + conn.remote_module.safe_mkdir(path) + + bootstrap_keyring = '/var/lib/ceph/bootstrap-mgr/{cluster}.keyring'.format( + cluster=cluster + ) + + keypath = os.path.join(path, 'keyring') + + stdout, stderr, returncode = remoto.process.check( + conn, + [ + 'ceph', + '--cluster', cluster, + '--name', 'client.bootstrap-mgr', + '--keyring', bootstrap_keyring, + 'auth', 'get-or-create', 'mgr.{name}'.format(name=name), + 'mon', 'allow profile mgr', + '-o', + os.path.join(keypath), + ] + ) + if returncode > 0: + for line in stderr: + conn.logger.error(line) + for line in stdout: + # yes stdout as err because this is an error + conn.logger.error(line) + conn.logger.error('exit code from command was: %s' % returncode) + raise RuntimeError('could not create mgr') + + conn.remote_module.touch_file(os.path.join(path, 'done')) + conn.remote_module.touch_file(os.path.join(path, init)) + + if init == 'upstart': + remoto.process.run( + conn, + [ + 'initctl', + 'emit', + 'ceph-mgr', + 'cluster={cluster}'.format(cluster=cluster), + 'id={name}'.format(name=name), + ], + timeout=7 + ) + elif init == 'sysvinit': + remoto.process.run( + conn, + [ + 'service', + 'ceph', + 'start', + 'mgr.{name}'.format(name=name), + ], + timeout=7 + ) + if distro.is_el: + system.enable_service(distro.conn) + elif init == 'systemd': + remoto.process.run( + conn, + [ + 'systemctl', + 'enable', + 'ceph-mgr@{name}'.format(name=name), + ], + timeout=7 + ) + remoto.process.run( + conn, + [ + 'systemctl', + 'start', + 'ceph-mgr@{name}'.format(name=name), + ], + timeout=7 + ) + remoto.process.run( + conn, + [ + 'systemctl', + 'enable', + 'ceph.target', + ], + timeout=7 + ) + + + +def mgr_create(args): + conf_data = conf.ceph.load_raw(args) + LOG.debug( + 'Deploying mgr, cluster %s hosts %s', + args.cluster, + ' '.join(':'.join(x or '' for x in t) for t in args.mgr), + ) + + key = get_bootstrap_mgr_key(cluster=args.cluster) + + bootstrapped = set() + errors = 0 + failed_on_rhel = False + + for hostname, name in args.mgr: + try: + distro = hosts.get(hostname, username=args.username) + rlogger = distro.conn.logger + LOG.info( + 'Distro info: %s %s %s', + distro.name, + distro.release, + distro.codename + ) + + LOG.debug('remote host will use %s', distro.init) + + if hostname not in bootstrapped: + bootstrapped.add(hostname) + LOG.debug('deploying mgr bootstrap to %s', hostname) + distro.conn.remote_module.write_conf( + args.cluster, + conf_data, + args.overwrite_conf, + ) + + path = '/var/lib/ceph/bootstrap-mgr/{cluster}.keyring'.format( + cluster=args.cluster, + ) + + if not distro.conn.remote_module.path_exists(path): + rlogger.warning('mgr keyring does not exist yet, creating one') + distro.conn.remote_module.write_keyring(path, key) + + create_mgr(distro, name, args.cluster, distro.init) + distro.conn.exit() + except RuntimeError as e: + if distro.normalized_name == 'redhat': + LOG.error('this feature may not yet available for %s %s' % (distro.name, distro.release)) + failed_on_rhel = True + LOG.error(e) + errors += 1 + + if errors: + if failed_on_rhel: + # because users only read the last few lines :( + LOG.error( + 'RHEL RHCS systems do not have the ability to deploy MGR yet' + ) + + raise exc.GenericError('Failed to create %d MGRs' % errors) + + +def mgr(args): + if args.subcommand == 'create': + mgr_create(args) + else: + LOG.error('subcommand %s not implemented', args.subcommand) + + +def colon_separated(s): + host = s + name = s + if s.count(':') == 1: + (host, name) = s.split(':') + return (host, name) + + +@priority(30) +def make(parser): + """ + Ceph MGR daemon management + """ + mgr_parser = parser.add_subparsers(dest='subcommand') + mgr_parser.required = True + + mgr_create = mgr_parser.add_parser( + 'create', + help='Deploy Ceph MGR on remote host(s)' + ) + mgr_create.add_argument( + 'mgr', + metavar='HOST[:NAME]', + nargs='+', + type=colon_separated, + help='host (and optionally the daemon name) to deploy on', + ) + parser.set_defaults( + func=mgr, + ) diff --git a/setup.py b/setup.py index 1c318a0..98a94fd 100644 --- a/setup.py +++ b/setup.py @@ -67,6 +67,7 @@ setup( 'osd = ceph_deploy.osd:make', 'disk = ceph_deploy.osd:make_disk', 'mds = ceph_deploy.mds:make', + 'mgr = ceph_deploy.mgr:make', 'forgetkeys = ceph_deploy.forgetkeys:make', 'config = ceph_deploy.config:make', 'admin = ceph_deploy.admin:make', -- 2.47.3