def task(ctx, config): """ Mount/unmount a ``kernel`` client. The config is optional and defaults to mounting on all clients. If a config is given, it is expected to be a list of clients to do this operation on. This lets you e.g. set up one client with ``ceph-fuse`` and another with ``kclient``. Example that mounts all clients:: tasks: - ceph: - kclient: - interactive: Example that uses both ``kclient` and ``ceph-fuse``:: tasks: - ceph: - ceph-fuse: [client.0] - kclient: [client.1] - interactive: :param ctx: Context :param config: Configuration """ log.info('Mounting kernel clients...') assert config is None or isinstance(config, list), \ "task kclient got invalid config" if config is None: config = ['client.{id}'.format(id=id_) for id_ in misc.all_roles_of_type(ctx.cluster, 'client')] clients = list(misc.get_clients(ctx=ctx, roles=config)) test_dir = misc.get_testdir(ctx) # Assemble mon addresses remotes_and_roles = ctx.cluster.remotes.items() roles = [roles for (remote_, roles) in remotes_and_roles] ips = [remote_.ssh.get_transport().getpeername()[0] for (remote_, _) in remotes_and_roles] mons = misc.get_mons(roles, ips).values() mounts = {} for id_, remote in clients: kernel_mount = KernelMount(mons, test_dir, id_, remote) mounts[id_] = kernel_mount kernel_mount.mount() ctx.mounts = mounts try: yield mounts finally: log.info('Unmounting kernel clients...') for mount in mounts.values(): mount.umount()
def test_get_mons(): ips = ['1.1.1.1', '2.2.2.2', '3.3.3.3'] addrs = ['1.1.1.1:6789', '1.1.1.1:6790', '1.1.1.1:6791'] mons = misc.get_mons([['mon.a']], ips) assert mons == {'mon.a': addrs[0]} mons = misc.get_mons([['cluster-a.mon.foo', 'client.b'], ['osd.0']], ips) assert mons == {'cluster-a.mon.foo': addrs[0]} mons = misc.get_mons([['mon.a', 'mon.b', 'ceph.mon.c']], ips) assert mons == {'mon.a': addrs[0], 'mon.b': addrs[1], 'ceph.mon.c': addrs[2]} mons = misc.get_mons([['mon.a'], ['mon.b'], ['ceph.mon.c']], ips) assert mons == {'mon.a': addrs[0], 'mon.b': ips[1] + ':6789', 'ceph.mon.c': ips[2] + ':6789'}
def task(ctx, config): """ Mount/unmount a ``kernel`` client. The config is optional and defaults to mounting on all clients. If a config is given, it is expected to be a list of clients to do this operation on. This lets you e.g. set up one client with ``ceph-fuse`` and another with ``kclient``. Example that mounts all clients:: tasks: - ceph: - kclient: - interactive: Example that uses both ``kclient` and ``ceph-fuse``:: tasks: - ceph: - ceph-fuse: [client.0] - kclient: [client.1] - interactive: Pass a dictionary instead of lists to specify per-client config: tasks: -kclient: client.0: debug: true :param ctx: Context :param config: Configuration """ log.info('Mounting kernel clients...') assert config is None or isinstance(config, list) or isinstance(config, dict), \ "task kclient got invalid config" if config is None: config = ['client.{id}'.format(id=id_) for id_ in misc.all_roles_of_type(ctx.cluster, 'client')] if isinstance(config, list): client_roles = config config = dict([r, dict()] for r in client_roles) elif isinstance(config, dict): client_roles = filter(lambda x: 'client.' in x, config.keys()) else: raise ValueError("Invalid config object: {0} ({1})".format(config, config.__class__)) # config has been converted to a dict by this point overrides = ctx.config.get('overrides', {}) deep_merge(config, overrides.get('kclient', {})) clients = list(misc.get_clients(ctx=ctx, roles=client_roles)) test_dir = misc.get_testdir(ctx) # Assemble mon addresses remotes_and_roles = ctx.cluster.remotes.items() roles = [roles for (remote_, roles) in remotes_and_roles] ips = [remote_.ssh.get_transport().getpeername()[0] for (remote_, _) in remotes_and_roles] mons = misc.get_mons(roles, ips).values() mounts = {} for id_, remote in clients: client_config = config.get("client.%s" % id_) if client_config is None: client_config = {} if config.get("disabled", False) or not client_config.get('mounted', True): continue kernel_mount = KernelMount( mons, test_dir, id_, remote, ctx.teuthology_config.get('ipmi_user', None), ctx.teuthology_config.get('ipmi_password', None), ctx.teuthology_config.get('ipmi_domain', None) ) mounts[id_] = kernel_mount if client_config.get('debug', False): remote.run(args=["sudo", "bash", "-c", "echo 'module ceph +p' > /sys/kernel/debug/dynamic_debug/control"]) remote.run(args=["sudo", "bash", "-c", "echo 'module libceph +p' > /sys/kernel/debug/dynamic_debug/control"]) kernel_mount.mount() def umount_all(): log.info('Unmounting kernel clients...') forced = False for mount in mounts.values(): if mount.is_mounted(): try: mount.umount() except (CommandFailedError, MaxWhileTries): log.warn("Ordinary umount failed, forcing...") forced = True mount.umount_wait(force=True) return forced ctx.mounts = mounts try: yield mounts except: umount_all() # ignore forced retval, we are already in error handling finally: forced = umount_all() if forced: # The context managers within the kclient manager worked (i.e. # the test workload passed) but for some reason we couldn't # umount, so turn this into a test failure. raise RuntimeError("Kernel mounts did not umount cleanly")
def task(ctx, config): """ Mount/unmount a ``kernel`` client. The config is optional and defaults to mounting on all clients. If a config is given, it is expected to be a list of clients to do this operation on. This lets you e.g. set up one client with ``ceph-fuse`` and another with ``kclient``. Example that mounts all clients:: tasks: - ceph: - kclient: - interactive: Example that uses both ``kclient` and ``cfuse``:: tasks: - ceph: - cfuse: [client.0] - kclient: [client.1] - interactive: """ log.info('Mounting kernel clients...') assert config is None or isinstance(config, list), \ "task kclient got invalid config" if config is None: config = [ 'client.{id}'.format(id=id_) for id_ in teuthology.all_roles_of_type(ctx.cluster, 'client') ] clients = list(teuthology.get_clients(ctx=ctx, roles=config)) for id_, remote in clients: mnt = os.path.join('/tmp/cephtest', 'mnt.{id}'.format(id=id_)) log.info('Mounting kclient client.{id} at {remote} {mnt}...'.format( id=id_, remote=remote, mnt=mnt)) # figure mon ips remotes_and_roles = ctx.cluster.remotes.items() roles = [roles for (remote_, roles) in remotes_and_roles] ips = [ host for (host, port) in (remote_.ssh.get_transport().getpeername() for (remote_, roles) in remotes_and_roles) ] mons = teuthology.get_mons(roles, ips).values() secret = '/tmp/cephtest/data/client.{id}.secret'.format(id=id_) teuthology.write_secret_file(remote, 'client.{id}'.format(id=id_), secret) remote.run(args=[ 'mkdir', '--', mnt, ], ) remote.run(args=[ 'sudo', '/tmp/cephtest/enable-coredump', '/tmp/cephtest/binary/usr/local/bin/ceph-coverage', '/tmp/cephtest/archive/coverage', '/tmp/cephtest/binary/usr/local/sbin/mount.ceph', '{mons}:/'.format(mons=','.join(mons)), mnt, '-v', '-o', 'name={id},secretfile={secret}'.format(id=id_, secret=secret), ], ) try: yield finally: log.info('Unmounting kernel clients...') for id_, remote in clients: log.debug('Unmounting client client.{id}...'.format(id=id_)) mnt = os.path.join('/tmp/cephtest', 'mnt.{id}'.format(id=id_)) remote.run(args=[ 'sudo', 'umount', mnt, ], ) remote.run(args=[ 'rmdir', '--', mnt, ], )
def task(ctx, config): """ Mount/unmount a ``kernel`` client. The config is optional and defaults to mounting on all clients. If a config is given, it is expected to be a list of clients to do this operation on. This lets you e.g. set up one client with ``ceph-fuse`` and another with ``kclient``. Example that mounts all clients:: tasks: - ceph: - kclient: - interactive: Example that uses both ``kclient` and ``cfuse``:: tasks: - ceph: - cfuse: [client.0] - kclient: [client.1] - interactive: """ log.info('Mounting kernel clients...') assert config is None or isinstance(config, list), \ "task kclient got invalid config" if config is None: config = ['client.{id}'.format(id=id_) for id_ in teuthology.all_roles_of_type(ctx.cluster, 'client')] clients = list(teuthology.get_clients(ctx=ctx, roles=config)) for id_, remote in clients: mnt = os.path.join('/tmp/cephtest', 'mnt.{id}'.format(id=id_)) log.info('Mounting kclient client.{id} at {remote} {mnt}...'.format( id=id_, remote=remote, mnt=mnt)) # figure mon ips remotes_and_roles = ctx.cluster.remotes.items() roles = [roles for (remote_, roles) in remotes_and_roles] ips = [host for (host, port) in (remote_.ssh.get_transport().getpeername() for (remote_, roles) in remotes_and_roles)] mons = teuthology.get_mons(roles, ips).values() secret = '/tmp/cephtest/data/client.{id}.secret'.format(id=id_) teuthology.write_secret_file(remote, 'client.{id}'.format(id=id_), secret) remote.run( args=[ 'mkdir', '--', mnt, ], ) remote.run( args=[ 'sudo', '/tmp/cephtest/enable-coredump', '/tmp/cephtest/binary/usr/local/bin/ceph-coverage', '/tmp/cephtest/archive/coverage', '/tmp/cephtest/binary/usr/local/sbin/mount.ceph', '{mons}:/'.format(mons=','.join(mons)), mnt, '-v', '-o', 'name={id},secretfile={secret}'.format(id=id_, secret=secret), ], ) try: yield finally: log.info('Unmounting kernel clients...') for id_, remote in clients: log.debug('Unmounting client client.{id}...'.format(id=id_)) mnt = os.path.join('/tmp/cephtest', 'mnt.{id}'.format(id=id_)) remote.run( args=[ 'sudo', 'umount', mnt, ], ) remote.run( args=[ 'rmdir', '--', mnt, ], )
def task(ctx, config): """ Mount/unmount a ``kernel`` client. The config is optional and defaults to mounting on all clients. If a config is given, it is expected to be a list of clients to do this operation on. This lets you e.g. set up one client with ``ceph-fuse`` and another with ``kclient``. Example that mounts all clients:: tasks: - ceph: - kclient: - interactive: Example that uses both ``kclient` and ``ceph-fuse``:: tasks: - ceph: - ceph-fuse: [client.0] - kclient: [client.1] - interactive: Pass a dictionary instead of lists to specify per-client config: tasks: -kclient: client.0: debug: true :param ctx: Context :param config: Configuration """ log.info('Mounting kernel clients...') assert config is None or isinstance(config, list) or isinstance(config, dict), \ "task kclient got invalid config" if config is None: config = [ 'client.{id}'.format(id=id_) for id_ in misc.all_roles_of_type(ctx.cluster, 'client') ] if isinstance(config, list): client_roles = config config = dict([r, dict()] for r in client_roles) elif isinstance(config, dict): client_roles = filter(lambda x: 'client.' in x, config.keys()) else: raise ValueError("Invalid config object: {0} ({1})".format( config, config.__class__)) # config has been converted to a dict by this point overrides = ctx.config.get('overrides', {}) deep_merge(config, overrides.get('kclient', {})) clients = list(misc.get_clients(ctx=ctx, roles=client_roles)) test_dir = misc.get_testdir(ctx) # Assemble mon addresses remotes_and_roles = ctx.cluster.remotes.items() roles = [roles for (remote_, roles) in remotes_and_roles] ips = [ remote_.ssh.get_transport().getpeername()[0] for (remote_, _) in remotes_and_roles ] mons = misc.get_mons(roles, ips).values() mounts = {} for id_, remote in clients: client_config = config.get("client.%s" % id_) if client_config is None: client_config = {} if config.get("disabled", False) or not client_config.get('mounted', True): continue kernel_mount = KernelMount( ctx, mons, test_dir, id_, remote, ctx.teuthology_config.get('ipmi_user', None), ctx.teuthology_config.get('ipmi_password', None), ctx.teuthology_config.get('ipmi_domain', None)) mounts[id_] = kernel_mount if client_config.get('debug', False): remote.run(args=[ "sudo", "bash", "-c", "echo 'module ceph +p' > /sys/kernel/debug/dynamic_debug/control" ]) remote.run(args=[ "sudo", "bash", "-c", "echo 'module libceph +p' > /sys/kernel/debug/dynamic_debug/control" ]) kernel_mount.mount() def umount_all(): log.info('Unmounting kernel clients...') forced = False for mount in mounts.values(): if mount.is_mounted(): try: mount.umount() except (CommandFailedError, MaxWhileTries): log.warn("Ordinary umount failed, forcing...") forced = True mount.umount_wait(force=True) return forced ctx.mounts = mounts try: yield mounts except: umount_all() # ignore forced retval, we are already in error handling finally: forced = umount_all() if forced: # The context managers within the kclient manager worked (i.e. # the test workload passed) but for some reason we couldn't # umount, so turn this into a test failure. raise RuntimeError("Kernel mounts did not umount cleanly")
def task(ctx, config): """ Mount/unmount a ``kernel`` client. The config is optional and defaults to mounting on all clients. If a config is given, it is expected to be a list of clients to do this operation on. This lets you e.g. set up one client with ``ceph-fuse`` and another with ``kclient``. Example that mounts all clients:: tasks: - ceph: - kclient: - interactive: Example that uses both ``kclient` and ``ceph-fuse``:: tasks: - ceph: - ceph-fuse: [client.0] - kclient: [client.1] - interactive: Pass a dictionary instead of lists to specify per-client config: tasks: -kclient: client.0: debug: true :param ctx: Context :param config: Configuration """ log.info('Mounting kernel clients...') assert config is None or isinstance(config, list) or isinstance(config, dict), \ "task kclient got invalid config" if config is None: config = ['client.{id}'.format(id=id_) for id_ in misc.all_roles_of_type(ctx.cluster, 'client')] if isinstance(config, list): client_roles = config config = dict([r, dict()] for r in client_roles) elif isinstance(config, dict): client_roles = config.keys() else: raise ValueError("Invalid config object: {0} ({1})".format(config, config.__class__)) # config has been converted to a dict by this point overrides = ctx.config.get('overrides', {}) deep_merge(config, overrides.get('kclient', {})) clients = list(misc.get_clients(ctx=ctx, roles=client_roles)) test_dir = misc.get_testdir(ctx) # Assemble mon addresses remotes_and_roles = ctx.cluster.remotes.items() roles = [roles for (remote_, roles) in remotes_and_roles] ips = [remote_.ssh.get_transport().getpeername()[0] for (remote_, _) in remotes_and_roles] mons = misc.get_mons(roles, ips).values() mounts = {} for id_, remote in clients: kernel_mount = KernelMount( mons, test_dir, id_, remote, ctx.teuthology_config.get('ipmi_user', None), ctx.teuthology_config.get('ipmi_password', None), ctx.teuthology_config.get('ipmi_domain', None) ) mounts[id_] = kernel_mount client_config = config["client.{0}".format(id_)] if client_config.get('debug', False): remote.run(args=["sudo", "bash", "-c", "echo 'module ceph +p' > /sys/kernel/debug/dynamic_debug/control"]) remote.run(args=["sudo", "bash", "-c", "echo 'module libceph +p' > /sys/kernel/debug/dynamic_debug/control"]) kernel_mount.mount() ctx.mounts = mounts try: yield mounts finally: log.info('Unmounting kernel clients...') for mount in mounts.values(): mount.umount()