def _setup_mon(ctx, manager, remote, mon, name, data_path, conf_path): # co-locate a new monitor on remote where an existing monitor is hosted cluster = manager.cluster remote.run(args=['sudo', 'mkdir', '-p', data_path]) keyring_path = '/etc/ceph/{cluster}.keyring'.format( cluster=manager.cluster) testdir = teuthology.get_testdir(ctx) monmap_path = '{tdir}/{cluster}.monmap'.format(tdir=testdir, cluster=cluster) manager.raw_cluster_cmd('mon', 'getmap', '-o', monmap_path) if manager.controller != remote: monmap = teuthology.get_file(manager.controller, monmap_path) teuthology.write_file(remote, monmap_path, StringIO(monmap)) remote.run( args=[ 'sudo', 'ceph-mon', '--cluster', cluster, '--mkfs', '-i', mon, '--monmap', monmap_path, '--keyring', keyring_path]) if manager.controller != remote: teuthology.delete_file(remote, monmap_path) # raw_cluster_cmd() is performed using sudo, so sudo here also. teuthology.delete_file(manager.controller, monmap_path, sudo=True) # update ceph.conf so that the ceph CLI is able to connect to the cluster if conf_path: ip = remote.ip_address port = _get_next_port(ctx, ip, cluster) mon_addr = '{ip}:{port}'.format(ip=ip, port=port) ctx.ceph[cluster].conf[name] = {'mon addr': mon_addr} write_conf(ctx, conf_path, cluster)
def install_epel(remote): ''' install a disabled-by-default epel repo config file ''' remove = False try: if remote.os.package_type == 'deb': yield else: remove = True distromajor = remote.os.version.split('.')[0] repofiledata = textwrap.dedent(''' [epel] name=epel{version} metalink=http://mirrors.fedoraproject.org/metalink?repo=epel-{version}&arch=$basearch enabled=0 gpgcheck=0 ''').format(version=distromajor) misc.create_file(remote, '/etc/yum.repos.d/epel.repo', data=repofiledata, sudo=True) remote.run(args='sudo yum clean all') yield finally: if remove: misc.delete_file(remote, '/etc/yum.repos.d/epel.repo', sudo=True)
def _setup_mon(ctx, manager, remote, mon, name, data_path, conf_path): # co-locate a new monitor on remote where an existing monitor is hosted cluster = manager.cluster remote.run(args=['sudo', 'mkdir', '-p', data_path]) keyring_path = '/etc/ceph/{cluster}.keyring'.format( cluster=manager.cluster) testdir = teuthology.get_testdir(ctx) monmap_path = '{tdir}/{cluster}.monmap'.format(tdir=testdir, cluster=cluster) manager.raw_cluster_cmd('mon', 'getmap', '-o', monmap_path) if manager.controller != remote: monmap = teuthology.get_file(manager.controller, monmap_path) teuthology.write_file(remote, monmap_path, StringIO(monmap)) remote.run(args=[ 'sudo', 'ceph-mon', '--cluster', cluster, '--mkfs', '-i', mon, '--monmap', monmap_path, '--keyring', keyring_path ]) if manager.controller != remote: teuthology.delete_file(remote, monmap_path) # raw_cluster_cmd() is performed using sudo, so sudo here also. teuthology.delete_file(manager.controller, monmap_path, sudo=True) # update ceph.conf so that the ceph CLI is able to connect to the cluster if conf_path: ip = remote.ip_address port = _get_next_port(ctx, ip, cluster) mon_addr = '{ip}:{port}'.format(ip=ip, port=port) ctx.ceph[cluster].conf[name] = {'mon addr': mon_addr} write_conf(ctx, conf_path, cluster)
def install_distro_kernel(remote): """ RPM: Find newest kernel on the machine and update grub to use kernel + reboot. DEB: Find newest kernel. Parse grub.cfg to figure out the entryname/subentry. then modify 01_ceph_kernel to have correct entry + updategrub + reboot. """ system_type = teuthology.get_system_type(remote) distribution = '' if system_type == 'rpm': output, err_mess = StringIO(), StringIO() remote.run(args=['rpm', '-q', 'kernel', '--last' ], stdout=output, stderr=err_mess ) newest=output.getvalue().split()[0].split('kernel-')[1] log.info('Distro Kernel Version: {version}'.format(version=newest)) update_grub_rpm(remote, newest) remote.run( args=['sudo', 'shutdown', '-r', 'now'], wait=False ) output.close() err_mess.close() return if system_type == 'deb': distribution = teuthology.get_system_type(remote, distro=True) newversion = get_version_from_pkg(remote, distribution) if 'ubuntu' in distribution: grub2conf = teuthology.get_file(remote, '/boot/grub/grub.cfg', True) submenu = '' menuentry = '' for line in grub2conf.split('\n'): if 'submenu' in line: submenu = line.split('submenu ')[1] # Ubuntu likes to be sneaky and change formatting of # grub.cfg between quotes/doublequotes between versions if submenu.startswith("'"): submenu = submenu.split("'")[1] if submenu.startswith('"'): submenu = submenu.split('"')[1] if 'menuentry' in line: if newversion in line and 'recovery' not in line: menuentry = line.split('\'')[1] break if submenu: grubvalue = submenu + '>' + menuentry else: grubvalue = menuentry grubfile = 'cat <<EOF\nset default="' + grubvalue + '"\nEOF' teuthology.delete_file(remote, '/etc/grub.d/01_ceph_kernel', sudo=True, force=True) teuthology.sudo_write_file(remote, '/etc/grub.d/01_ceph_kernel', StringIO(grubfile), '755') log.info('Distro Kernel Version: {version}'.format(version=newversion)) remote.run(args=['sudo', 'update-grub']) remote.run(args=['sudo', 'shutdown', '-r', 'now'], wait=False ) return if 'debian' in distribution: grub2_kernel_select_generic(remote, newversion, 'deb') log.info('Distro Kernel Version: {version}'.format(version=newversion)) remote.run( args=['sudo', 'shutdown', '-r', 'now'], wait=False ) return
def push_keys_to_host(ctx, config, public_key, private_key): """ Push keys to all hosts """ log.info('generated public key {pub_key}'.format(pub_key=public_key)) # add an entry for all hosts in ctx to auth_keys_data auth_keys_data = '' for inner_host in ctx.cluster.remotes.keys(): inner_username, inner_hostname = str(inner_host).split('@') # create a 'user@hostname' string using our fake hostname fake_hostname = '{user}@{host}'.format(user=ssh_keys_user, host=str(inner_hostname)) auth_keys_data += '\nssh-rsa {pub_key} {user_host}\n'.format( pub_key=public_key, user_host=fake_hostname) key_backup_files = dict() # for each host in ctx, add keys for all other hosts for remote in ctx.cluster.remotes: username, hostname = str(remote).split('@') if "" == username or "" == hostname: continue else: log.info('pushing keys to {host} for {user}'.format(host=hostname, user=username)) # adding a private key priv_key_file = '/home/{user}/.ssh/id_rsa'.format(user=username) priv_key_data = '{priv_key}'.format(priv_key=private_key) misc.delete_file(remote, priv_key_file, force=True) # Hadoop requires that .ssh/id_rsa have permissions of '500' misc.create_file(remote, priv_key_file, priv_key_data, str(500)) # then a private key pub_key_file = '/home/{user}/.ssh/id_rsa.pub'.format(user=username) pub_key_data = 'ssh-rsa {pub_key} {user_host}'.format( pub_key=public_key, user_host=str(remote)) misc.delete_file(remote, pub_key_file, force=True) misc.create_file(remote, pub_key_file, pub_key_data) # add appropriate entries to the authorized_keys file for this host auth_keys_file = '/home/{user}/.ssh/authorized_keys'.format( user=username) key_backup_files[remote] = backup_file(remote, auth_keys_file) misc.append_lines_to_file(remote, auth_keys_file, auth_keys_data) try: yield finally: # cleanup the keys log.info("Cleaning up SSH keys") cleanup_added_key(ctx, key_backup_files, auth_keys_file)
def push_keys_to_host(ctx, config, public_key, private_key): """ Push keys to all hosts """ log.info('generated public key {pub_key}'.format(pub_key=public_key)) # add an entry for all hosts in ctx to auth_keys_data auth_keys_data = '' for inner_host in ctx.cluster.remotes.iterkeys(): inner_username, inner_hostname = str(inner_host).split('@') # create a 'user@hostname' string using our fake hostname fake_hostname = '{user}@{host}'.format(user=ssh_keys_user, host=str(inner_hostname)) auth_keys_data += '\nssh-rsa {pub_key} {user_host}\n'.format(pub_key=public_key, user_host=fake_hostname) # for each host in ctx, add keys for all other hosts for remote in ctx.cluster.remotes: username, hostname = str(remote).split('@') if "" == username or "" == hostname: continue else: log.info('pushing keys to {host} for {user}'.format(host=hostname, user=username)) # adding a private key priv_key_file = '/home/{user}/.ssh/id_rsa'.format(user=username) priv_key_data = '{priv_key}'.format(priv_key=private_key) misc.delete_file(remote, priv_key_file, force=True) # Hadoop requires that .ssh/id_rsa have permissions of '500' misc.create_file(remote, priv_key_file, priv_key_data, str(500)) # then a private key pub_key_file = '/home/{user}/.ssh/id_rsa.pub'.format(user=username) pub_key_data = 'ssh-rsa {pub_key} {user_host}'.format(pub_key=public_key, user_host=str(remote)) misc.delete_file(remote, pub_key_file, force=True) misc.create_file(remote, pub_key_file, pub_key_data) # add appropriate entries to the authorized_keys file for this host auth_keys_file = '/home/{user}/.ssh/authorized_keys'.format( user=username) backup_file(remote, auth_keys_file) lines = '#TEUTHOLOGY_START\n' + auth_keys_data + '\n#TEUTHOLOGY_END\n' misc.append_lines_to_file(remote, auth_keys_file, lines) try: yield finally: # cleanup the keys log.info("Cleaning up SSH keys") cleanup_added_key(ctx)
def write_info_yaml(cluster, client): ''' write info.yaml to client for nosetests ''' try: info = { 'cluster': { rem.name: {'roles': roles} for rem, roles in cluster.remotes.iteritems() } } misc.create_file(client, 'calamari/info.yaml', data=yaml.safe_dump(info, default_flow_style=False)) yield finally: misc.delete_file(client, 'calamari/info.yaml')
def cleanup_added_key(ctx, key_backup_files, path): """ Delete the keys and removes ~/.ssh/authorized_keys entries we added """ log.info('cleaning up keys added for testing') for remote in ctx.cluster.remotes: username, hostname = str(remote).split('@') if "" == username or "" == hostname: continue else: log.info(' cleaning up keys for user {user} on {host}'.format(host=hostname, user=username)) misc.delete_file(remote, '/home/{user}/.ssh/id_rsa'.format(user=username)) misc.delete_file(remote, '/home/{user}/.ssh/id_rsa.pub'.format(user=username)) misc.move_file(remote, key_backup_files[remote], path)
def remove_repo(remote): log.info('Removing repo on %s', remote) flavor = _get_relmap(remote)['flavor'] if flavor == 'deb': teuthology.delete_file(remote, '/etc/apt/sources.list.d/inktank.list', sudo=True, force=True) result = remote.run(args=['sudo', 'apt-get', 'update', '-y'], stdout=StringIO()) return result elif flavor == 'rpm': teuthology.delete_file(remote, '/etc/yum.repos.d/inktank.repo', sudo=True, force=True) return remote.run(args=['sudo', 'yum', 'makecache']) else: return False
def write_info_yaml(cluster, client): ''' write info.yaml to client for nosetests ''' try: info = { 'cluster': { rem.name: { 'roles': roles } for rem, roles in cluster.remotes.iteritems() } } misc.create_file(client, 'calamari/info.yaml', data=yaml.safe_dump(info, default_flow_style=False)) yield finally: misc.delete_file(client, 'calamari/info.yaml')
def cleanup_added_key(ctx): """ Delete the keys and removes ~/.ssh/authorized_keys entries we added """ log.info('cleaning up keys added for testing') for remote in ctx.cluster.remotes: username, hostname = str(remote).split('@') if "" == username or "" == hostname: continue else: log.info(' cleaning up keys for user {user} on {host}'.format( host=hostname, user=username)) misc.delete_file(remote, '/home/{user}/.ssh/id_rsa'.format(user=username)) misc.delete_file( remote, '/home/{user}/.ssh/id_rsa.pub'.format(user=username)) cmd = "sed -i /#TEUTHOLOGY_START/,/#TEUTHOLOGY_END/d /home/{user}/.ssh/authorized_keys".format( user=username).split() remote.run(args=cmd)
def write_test_conf(client): ''' write calamari/tests/test.conf to client for nosetests ''' try: testconf = textwrap.dedent(''' [testing] calamari_control = external ceph_control = external bootstrap = False api_username = admin api_password = admin embedded_timeout_factor = 1 external_timeout_factor = 3 external_cluster_path = info.yaml ''') misc.create_file(client, 'calamari/tests/test.conf', data=testconf) yield finally: misc.delete_file(client, 'calamari/tests/test.conf')
def cleanup_added_key(ctx): """ Delete the keys and removes ~/.ssh/authorized_keys entries we added """ log.info('cleaning up keys added for testing') for remote in ctx.cluster.remotes: username, hostname = str(remote).split('@') if "" == username or "" == hostname: continue else: log.info(' cleaning up keys for user {user} on {host}'.format(host=hostname, user=username)) misc.delete_file(remote, '/home/{user}/.ssh/id_rsa'.format(user=username)) misc.delete_file(remote, '/home/{user}/.ssh/id_rsa.pub'.format(user=username)) auth_keys_file = '/home/{user}/.ssh/authorized_keys'.format( user=username) backup_file(remote, auth_keys_file) args = [ 'sed', '-i', '/#TEUTHOLOGY_START/,/#TEUTHOLOGY_END/d', auth_keys_file, ] remote.run(args=args)
def cleanup_added_key(ctx): log.info('cleaning up keys added for testing') for remote in ctx.cluster.remotes: username, hostname = str(remote).split('@') if "" == username or "" == hostname: continue else: log.info(' cleaning up keys for user {user} on {host}'.format(host=hostname, user=username)) misc.delete_file(remote, '/home/{user}/.ssh/id_rsa'.format(user=username)) misc.delete_file(remote, '/home/{user}/.ssh/id_rsa.pub'.format(user=username)) misc.delete_file(remote, '/home/{user}/.ssh/authorized_keys2'.format(user=username))
def cleanup_added_key(ctx): log.info('cleaning up keys added for testing') for remote in ctx.cluster.remotes: username, hostname = str(remote).split('@') if "" == username or "" == hostname: continue else: log.info(' cleaning up keys for user {user} on {host}'.format( host=hostname, user=username)) misc.delete_file(remote, '/home/{user}/.ssh/id_rsa'.format(user=username)) misc.delete_file( remote, '/home/{user}/.ssh/id_rsa.pub'.format(user=username)) misc.delete_file( remote, '/home/{user}/.ssh/authorized_keys2'.format(user=username))
def install_kernel(remote, path=None, version=None): """ A bit of misnomer perhaps - the actual kernel package is installed elsewhere, this function deals with initrd and grub. Currently the following cases are handled: - local, gitbuilder, distro for rpm packages - distro for deb packages - see TODO in install_and_reboot() TODO: reboots should be issued from install_and_reboot() :param path: package path (for local and gitbuilder cases) :param version: for RPM distro kernels, pass this to update_grub_rpm """ templ = "install_kernel(remote={remote}, path={path}, version={version})" log.debug(templ.format(remote=remote, path=path, version=version)) package_type = remote.os.package_type if package_type == 'rpm': if path: version = get_image_version(remote, path) # This is either a gitbuilder or a local package and both of these # could have been built with upstream rpm targets with specs that # don't have a %post section at all, which means no initrd. maybe_generate_initrd_rpm(remote, path, version) elif not version or version == 'distro': version = get_latest_image_version_rpm(remote) update_grub_rpm(remote, version) remote.run( args=['sudo', 'shutdown', '-r', 'now'], wait=False ) return if package_type == 'deb': distribution = remote.os.name newversion = get_latest_image_version_deb(remote, distribution) if 'ubuntu' in distribution: grub2conf = teuthology.get_file(remote, '/boot/grub/grub.cfg', True) submenu = '' menuentry = '' for line in grub2conf.split('\n'): if 'submenu' in line: submenu = line.split('submenu ')[1] # Ubuntu likes to be sneaky and change formatting of # grub.cfg between quotes/doublequotes between versions if submenu.startswith("'"): submenu = submenu.split("'")[1] if submenu.startswith('"'): submenu = submenu.split('"')[1] if 'menuentry' in line: if newversion in line and 'recovery' not in line: menuentry = line.split('\'')[1] break if submenu: grubvalue = submenu + '>' + menuentry else: grubvalue = menuentry grubfile = 'cat <<EOF\nset default="' + grubvalue + '"\nEOF' teuthology.delete_file(remote, '/etc/grub.d/01_ceph_kernel', sudo=True, force=True) teuthology.sudo_write_file(remote, '/etc/grub.d/01_ceph_kernel', StringIO(grubfile), '755') log.info('Distro Kernel Version: {version}'.format(version=newversion)) remote.run(args=['sudo', 'update-grub']) remote.run(args=['sudo', 'shutdown', '-r', 'now'], wait=False ) return if 'debian' in distribution: grub2_kernel_select_generic(remote, newversion, 'deb') log.info('Distro Kernel Version: {version}'.format(version=newversion)) remote.run( args=['sudo', 'shutdown', '-r', 'now'], wait=False ) return
def install_distro_kernel(remote): """ RPM: Find newest kernel on the machine and update grub to use kernel + reboot. DEB: Find newest kernel. Parse grub.cfg to figure out the entryname/subentry. then modify 01_ceph_kernel to have correct entry + updategrub + reboot. """ system_type = teuthology.get_system_type(remote) distribution = '' if system_type == 'rpm': output, err_mess = StringIO(), StringIO() remote.run(args=['rpm', '-q', 'kernel', '--last'], stdout=output, stderr=err_mess) newest = output.getvalue().split()[0].split('kernel-')[1] log.info('Distro Kernel Version: {version}'.format(version=newest)) update_grub_rpm(remote, newest) remote.run(args=['sudo', 'shutdown', '-r', 'now'], wait=False) output.close() err_mess.close() return if system_type == 'deb': distribution = teuthology.get_system_type(remote, distro=True) newversion = get_version_from_pkg(remote, distribution) if 'ubuntu' in distribution: grub2conf = teuthology.get_file(remote, '/boot/grub/grub.cfg', True) submenu = '' menuentry = '' for line in grub2conf.split('\n'): if 'submenu' in line: submenu = line.split('submenu ')[1] # Ubuntu likes to be sneaky and change formatting of # grub.cfg between quotes/doublequotes between versions if submenu.startswith("'"): submenu = submenu.split("'")[1] if submenu.startswith('"'): submenu = submenu.split('"')[1] if 'menuentry' in line: if newversion in line and 'recovery' not in line: menuentry = line.split('\'')[1] break if submenu: grubvalue = submenu + '>' + menuentry else: grubvalue = menuentry grubfile = 'cat <<EOF\nset default="' + grubvalue + '"\nEOF' teuthology.delete_file(remote, '/etc/grub.d/01_ceph_kernel', sudo=True, force=True) teuthology.sudo_write_file(remote, '/etc/grub.d/01_ceph_kernel', StringIO(grubfile), '755') log.info( 'Distro Kernel Version: {version}'.format(version=newversion)) remote.run(args=['sudo', 'update-grub']) remote.run(args=['sudo', 'shutdown', '-r', 'now'], wait=False) return if 'debian' in distribution: grub2_kernel_select_generic(remote, newversion, 'deb') log.info( 'Distro Kernel Version: {version}'.format(version=newversion)) remote.run(args=['sudo', 'shutdown', '-r', 'now'], wait=False) return