Example #1
0
def binaries(ctx, config):
    path = config.get("path")

    if path is None:
        # fetch Apache Hadoop from gitbuilder
        log.info("Fetching and unpacking Apache Hadoop binaries from gitbuilder...")
        apache_sha1, apache_hadoop_bindir_url = teuthology.get_ceph_binary_url(
            package="apache-hadoop",
            branch=config.get("apache_branch"),
            tag=config.get("tag"),
            sha1=config.get("sha1"),
            flavor=config.get("flavor"),
            format=config.get("format"),
            dist=config.get("dist"),
            arch=config.get("arch"),
        )
        log.info("apache_hadoop_bindir_url %s" % (apache_hadoop_bindir_url))
        ctx.summary["apache-hadoop-sha1"] = apache_sha1

        # fetch Inktank Hadoop from gitbuilder
        log.info("Fetching and unpacking Inktank Hadoop binaries from gitbuilder...")
        inktank_sha1, inktank_hadoop_bindir_url = teuthology.get_ceph_binary_url(
            package="hadoop",
            branch=config.get("inktank_branch"),
            tag=config.get("tag"),
            sha1=config.get("sha1"),
            flavor=config.get("flavor"),
            format=config.get("format"),
            dist=config.get("dist"),
            arch=config.get("arch"),
        )
        log.info("inktank_hadoop_bindir_url %s" % (inktank_hadoop_bindir_url))
        ctx.summary["inktank-hadoop-sha1"] = inktank_sha1

    else:
        raise Exception("The hadoop task does not support the path argument at present")

    with parallel() as p:
        hadoopNodes = ctx.cluster.only(teuthology.is_type("hadoop"))
        # these can happen independently
        for remote in hadoopNodes.remotes.iterkeys():
            p.spawn(_node_binaries, ctx, config, remote, inktank_hadoop_bindir_url, apache_hadoop_bindir_url)

    try:
        yield
    finally:
        log.info("Removing hadoop binaries...")
        run.wait(
            ctx.cluster.run(
                args=["rm", "-rf", "--", "{tdir}/apache_hadoop".format(tdir=teuthology.get_testdir(ctx))], wait=False
            )
        )
        run.wait(
            ctx.cluster.run(
                args=["rm", "-rf", "--", "{tdir}/inktank_hadoop".format(tdir=teuthology.get_testdir(ctx))], wait=False
            )
        )
Example #2
0
def get_version_from_rpm(remote, sha1):
    """
    Get Actual version string from kernel file RPM URL.
    """
    system_type, system_ver = teuthology.get_system_type(remote, distro=True, version=True)
    if '.' in system_ver:
       system_ver = system_ver.split('.')[0]
    ldist = '{system_type}{system_ver}'.format(system_type=system_type, system_ver=system_ver)
    _, rpm_url = teuthology.get_ceph_binary_url(
        package='kernel',
        sha1=sha1,
        format='rpm',
        flavor='basic',
        arch='x86_64',
        dist=ldist,
        )
    kernel_url = urlparse.urljoin(rpm_url, 'kernel.x86_64.rpm')
    kerninfo, kern_err = StringIO(), StringIO()
    remote.run(args=['rpm', '-qp', kernel_url ], stdout=kerninfo, stderr=kern_err)
    kernelstring = ''
    if '\n' in kerninfo.getvalue():
        kernelstring = kerninfo.getvalue().split('\n')[0]
    else:
        kernelstring = kerninfo.getvalue()
    return kernelstring, kernel_url
Example #3
0
def download_deb(ctx, config):
    """
    Download a Debian kernel and copy the assocated linux image.

    :param ctx: Context
    :param config: Configuration
    """
    procs = {}
    for role, src in config.iteritems():
        (role_remote,) = ctx.cluster.only(role).remotes.keys()
        if src.find('/') >= 0:
            # local deb
            log.info('Copying kernel deb {path} to {role}...'.format(path=src,
                                                                     role=role))
            f = open(src, 'r')
            proc = role_remote.run(
                args=[
                    'python', '-c',
                    'import shutil, sys; shutil.copyfileobj(sys.stdin, file(sys.argv[1], "wb"))',
                    '/tmp/linux-image.deb',
                    ],
                wait=False,
                stdin=f
                )
            procs[role_remote.name] = proc

        else:
            log.info('Downloading kernel {sha1} on {role}...'.format(sha1=src,
                                                                     role=role))
            larch, ldist = _find_arch_and_dist(ctx)
            _, deb_url = teuthology.get_ceph_binary_url(
                package='kernel',
                sha1=src,
                format='deb',
                flavor='basic',
                arch=larch,
                dist=ldist,
                )

            log.info('fetching kernel from {url}'.format(url=deb_url))
            proc = role_remote.run(
                args=[
                    'sudo', 'rm', '-f', '/tmp/linux-image.deb',
                    run.Raw('&&'),
                    'echo',
                    'linux-image.deb',
                    run.Raw('|'),
                    'wget',
                    '-nv',
                    '-O',
                    '/tmp/linux-image.deb',
                    '--base={url}'.format(url=deb_url),
                    '--input-file=-',
                    ],
                wait=False)
            procs[role_remote.name] = proc

    for name, proc in procs.iteritems():
        log.debug('Waiting for download/copy to %s to complete...', name)
        proc.exitstatus.get()
Example #4
0
def download_deb(ctx, config):
    procs = {}
    for role, src in config.iteritems():
        (role_remote, ) = ctx.cluster.only(role).remotes.keys()
        if src.find('/') >= 0:
            # local deb
            log.info('Copying kernel deb {path} to {role}...'.format(
                path=src, role=role))
            f = open(src, 'r')
            proc = role_remote.run(args=[
                'python',
                '-c',
                'import shutil, sys; shutil.copyfileobj(sys.stdin, file(sys.argv[1], "wb"))',
                '/tmp/linux-image.deb',
            ],
                                   wait=False,
                                   stdin=f)
            procs[role_remote.name] = proc

        else:
            log.info('Downloading kernel {sha1} on {role}...'.format(
                sha1=src, role=role))
            larch, ldist = _find_arch_and_dist(ctx)
            _, deb_url = teuthology.get_ceph_binary_url(
                package='kernel',
                sha1=src,
                format='deb',
                flavor='basic',
                arch=larch,
                dist=ldist,
            )

            log.info('fetching kernel from {url}'.format(url=deb_url))
            proc = role_remote.run(args=[
                'sudo',
                'rm',
                '-f',
                '/tmp/linux-image.deb',
                run.Raw('&&'),
                'echo',
                'linux-image.deb',
                run.Raw('|'),
                'wget',
                '-nv',
                '-O',
                '/tmp/linux-image.deb',
                '--base={url}'.format(url=deb_url),
                '--input-file=-',
            ],
                                   wait=False)
            procs[role_remote.name] = proc

    for name, proc in procs.iteritems():
        log.debug('Waiting for download/copy to %s to complete...', name)
        proc.exitstatus.get()
Example #5
0
def binaries(ctx, config):
    path = config.get('path')
    tmpdir = None

    if path is None:
        # fetch from gitbuilder gitbuilder
        log.info('Fetching and unpacking hadoop binaries from gitbuilder...')
        sha1, hadoop_bindir_url = teuthology.get_ceph_binary_url(
            package='hadoop',
            branch=config.get('branch'),
            tag=config.get('tag'),
            sha1=config.get('sha1'),
            flavor=config.get('flavor'),
            format=config.get('format'),
            dist=config.get('dist'),
            arch=config.get('arch'),
            )
        log.info('hadoop_bindir_url %s' % (hadoop_bindir_url))
        ctx.summary['ceph-sha1'] = sha1
        if ctx.archive is not None:
            with file(os.path.join(ctx.archive, 'ceph-sha1'), 'w') as f:
                f.write(sha1 + '\n')

    with parallel() as p:
        hadoopNodes = ctx.cluster.only(teuthology.is_type('hadoop'))
        for remote in hadoopNodes.remotes.iterkeys():
            p.spawn(_download_hadoop_binaries, remote, hadoop_bindir_url)

    try:
        yield
    finally:
        log.info('Removing hadoop binaries...')
        run.wait(
            ctx.cluster.run(
                args=[ 'rm', '-rf', '--', '/tmp/cephtest/hadoop'],
                wait=False,
                ),
            )
Example #6
0
def download_kernel(ctx, config):
    """
    Supply each remote with a kernel package:
      - local kernels are copied over
      - gitbuilder kernels are downloaded
      - nothing is done for distro kernels

    :param ctx: Context
    :param config: Configuration
    """
    procs = {}
    for role, src in config.iteritems():
        needs_download = False

        if src == 'distro':
            # don't need to download distro kernels
            log.debug("src is distro, skipping download");
            continue

        (role_remote,) = ctx.cluster.only(role).remotes.keys()
        if isinstance(src, dict):
            # we're downloading a kernel from koji, the src dict here
            # is the build_info retrieved from koji using get_koji_build_info
            if src.get("id"):
                build_id = src["id"]
                log.info("Downloading kernel with build_id {build_id} on {role}...".format(
                    build_id=build_id,
                    role=role
                ))
                needs_download = True
                baseurl = get_kojiroot_base_url(src)
                pkg_name = get_koji_package_name("kernel", src)
            elif src.get("task_id"):
                needs_download = True
                log.info("Downloading kernel with task_id {task_id} on {role}...".format(
                    task_id=src["task_id"],
                    role=role
                ))
                baseurl = src["base_url"]
                # this var is also poorly named as it's not the package name,
                # but the full name of the rpm file to download.
                pkg_name = src["rpm_name"]
        elif src.find('/') >= 0:
            # local package - src is path
            log.info('Copying kernel package {path} to {role}...'.format(
                path=src, role=role))
            f = open(src, 'r')
            proc = role_remote.run(
                args=[
                    'python', '-c',
                    'import shutil, sys; shutil.copyfileobj(sys.stdin, file(sys.argv[1], "wb"))',
                    remote_pkg_path(role_remote),
                    ],
                wait=False,
                stdin=f
                )
            procs[role_remote.name] = proc
        else:
            # gitbuilder package - src is sha1
            log.info('Downloading kernel {sha1} on {role}...'.format(sha1=src,
                                                                     role=role))
            needs_download = True
            package_type = role_remote.os.package_type
            if package_type == 'rpm':
                system_type = role_remote.os.name
                system_ver = role_remote.os.version
                if '.' in system_ver:
                   system_ver = system_ver.split('.')[0]
                ldist = '{system_type}{system_ver}'.format(
                    system_type=system_type, system_ver=system_ver)
                larch = 'x86_64'
            elif package_type == 'deb':
                ldist, larch = role_remote.os.codename, role_remote.arch
            else:
                raise UnsupportedPackageTypeError(role_remote)

            _, baseurl = teuthology.get_ceph_binary_url(
                package='kernel',
                sha1=src,
                format=package_type,
                flavor='basic',
                arch=larch,
                dist=ldist,
                )

            pkg_name = gitbuilder_pkg_name(role_remote)

            log.info("fetching, gitbuilder baseurl is %s", baseurl)

        if needs_download:
            proc = role_remote.run(
                args=[
                    'rm', '-f', remote_pkg_path(role_remote),
                    run.Raw('&&'),
                    'echo',
                    pkg_name,
                    run.Raw('|'),
                    'wget',
                    '-nv',
                    '-O',
                    remote_pkg_path(role_remote),
                    '--base={url}'.format(url=baseurl),
                    '--input-file=-',
                    ],
                wait=False)
            procs[role_remote.name] = proc

    for name, proc in procs.iteritems():
        log.debug('Waiting for download/copy to %s to complete...', name)
        proc.wait()
Example #7
0
def task(ctx, config):
    """
    Make sure the specified kernel is installed.
    This can be a branch, tag, or sha1 of ceph-client.git.

    To install the kernel from the master branch on all hosts::

        kernel:
        tasks:
        - ceph:

    To wait 5 minutes for hosts to reboot::

        kernel:
          timeout: 300
        tasks:
        - ceph:

    To specify different kernels for each client::

        kernel:
          client.0:
            branch: foo
          client.1:
            tag: v3.0rc1
          client.2:
            sha1: db3540522e955c1ebb391f4f5324dff4f20ecd09
        tasks:
        - ceph:

    You can specify a branch, tag, or sha1 for all roles
    of a certain type (more specific roles override this)::

        kernel:
          client:
            tag: v3.0
          osd:
            branch: btrfs_fixes
          client.1:
            branch: more_specific_branch
          osd.3:
            branch: master

    To enable kdb::

        kernel:
          kdb: true

    :param ctx: Context
    :param config: Configuration
    """
    assert config is None or isinstance(config, dict), \
        "task kernel only supports a dictionary for configuration"

    timeout = 300
    if config is not None and 'timeout' in config:
        timeout = config.pop('timeout')

    config = normalize_config(ctx, config)
    validate_config(ctx, config)
    log.info('config %s' % config)

    need_install = {}  # sha1 to dl, or path to deb
    need_sha1 = {}     # sha1
    kdb = {}
    for role, role_config in config.iteritems():
        if role_config.get('deb'):
            path = role_config.get('deb')
            match = re.search('\d+-g(\w{7})', path)
            if match:
                sha1 = match.group(1)
                log.info('kernel deb sha1 appears to be %s', sha1)
                if need_to_install(ctx, role, sha1):
                    need_install[role] = path
                    need_sha1[role] = sha1
            else:
                log.info('unable to extract sha1 from deb path, forcing install')
                assert False
        elif role_config.get('sha1') == 'distro':
            if need_to_install_distro(ctx, role):
                need_install[role] = 'distro'
                need_sha1[role] = 'distro'
        else:
            larch, ldist = _find_arch_and_dist(ctx)
            sha1, _ = teuthology.get_ceph_binary_url(
                package='kernel',
                branch=role_config.get('branch'),
                tag=role_config.get('tag'),
                sha1=role_config.get('sha1'),
                flavor='basic',
                format='deb',
                dist=ldist,
                arch=larch,
                )
            log.debug('sha1 for {role} is {sha1}'.format(role=role, sha1=sha1))
            ctx.summary['{role}-kernel-sha1'.format(role=role)] = sha1
            if need_to_install(ctx, role, sha1):
                need_install[role] = sha1
                need_sha1[role] = sha1

        # enable or disable kdb if specified, otherwise do not touch
        if role_config.get('kdb') is not None:
            kdb[role] = role_config.get('kdb')

    if need_install:
        install_firmware(ctx, need_install)
        download_deb(ctx, need_install)
        install_and_reboot(ctx, need_install)
        wait_for_reboot(ctx, need_sha1, timeout)

    enable_disable_kdb(ctx, kdb)
Example #8
0
def binaries(ctx, config):
    """
    Fetch the binaries from the gitbuilder, and spawn the download tasks on
    the remote machines.
    """
    path = config.get('path')

    if path is None:
        # fetch Apache Hadoop from gitbuilder
        log.info(
            'Fetching and unpacking Apache Hadoop binaries from gitbuilder...')
        apache_sha1, apache_hadoop_bindir_url = teuthology.get_ceph_binary_url(
            package='apache-hadoop',
            branch=config.get('apache_branch'),
            tag=config.get('tag'),
            sha1=config.get('sha1'),
            flavor=config.get('flavor'),
            format=config.get('format'),
            dist=config.get('dist'),
            arch=config.get('arch'),
            )
        log.info('apache_hadoop_bindir_url %s' % (apache_hadoop_bindir_url))
        ctx.summary['apache-hadoop-sha1'] = apache_sha1

        # fetch Inktank Hadoop from gitbuilder
        log.info(
            'Fetching and unpacking Inktank Hadoop binaries from gitbuilder...')
        inktank_sha1, inktank_hadoop_bindir_url = \
            teuthology.get_ceph_binary_url(
                package='hadoop',
                branch=config.get('inktank_branch'),
                tag=config.get('tag'),
                sha1=config.get('sha1'),
                flavor=config.get('flavor'),
                format=config.get('format'),
                dist=config.get('dist'),
                arch=config.get('arch'),
                )
        log.info('inktank_hadoop_bindir_url %s' % (inktank_hadoop_bindir_url))
        ctx.summary['inktank-hadoop-sha1'] = inktank_sha1

    else:
        raise Exception(
                "The hadoop task does not support the path argument at present")

    with parallel() as parallel_task:
        hadoop_nodes = ctx.cluster.only(teuthology.is_type('hadoop'))
        # these can happen independently
        for remote in hadoop_nodes.remotes.iterkeys():
            parallel_task.spawn(_node_binaries, ctx, remote,
                    inktank_hadoop_bindir_url, apache_hadoop_bindir_url)

    try:
        yield
    finally:
        log.info('Removing hadoop binaries...')
        run.wait(
            ctx.cluster.run(
                args=['rm', '-rf', '--', '{tdir}/apache_hadoop'.format(
                        tdir=teuthology.get_testdir(ctx))],
                wait=False,
                ),
            )
        run.wait(
            ctx.cluster.run(
                args=['rm', '-rf', '--', '{tdir}/inktank_hadoop'.format(
                        tdir=teuthology.get_testdir(ctx))],
                wait=False,
                ),
            )
Example #9
0
def task(ctx, config):
    """
    Make sure the specified kernel is installed.
    This can be a branch, tag, or sha1 of ceph-client.git or a local
    kernel package.

    To install ceph-client.git branch (default: master)::

        kernel:
          branch: testing

    To install ceph-client.git tag::

        kernel:
          tag: v3.18

    To install ceph-client.git sha1::

        kernel:
          sha1: 275dd19ea4e84c34f985ba097f9cddb539f54a50

    To install local rpm (target should be an rpm system)::

        kernel:
          rpm: /path/to/appropriately-named.rpm

    To install local deb (target should be a deb system)::

        kernel:
          deb: /path/to/appropriately-named.deb

    For rpm: or deb: to work it should be able to figure out sha1 from
    local kernel package basename, see get_sha1_from_pkg_name().  This
    means that you can't for example install a local tag - package built
    with upstream {rpm,deb}-pkg targets won't have a sha1 in its name.

    If you want to schedule a run and use a local kernel package, you
    have to copy the package over to a box teuthology workers are
    running on and specify a path to the package on that box.

    All of the above will install a specified kernel on all targets.
    You can specify different kernels for each role or for all roles of
    a certain type (more specific roles override less specific, see
    normalize_config() for details)::

        kernel:
          client:
            tag: v3.0
          osd:
            branch: btrfs_fixes
          client.1:
            branch: more_specific
          osd.3:
            branch: master

    To wait 3 minutes for hosts to reboot (default: 300)::

        kernel:
          timeout: 180

    To enable kdb::

        kernel:
          kdb: true

    :param ctx: Context
    :param config: Configuration
    """
    assert config is None or isinstance(config, dict), \
        "task kernel only supports a dictionary for configuration"

    timeout = 300
    if config is not None and 'timeout' in config:
        timeout = config.pop('timeout')

    config = normalize_config(ctx, config)
    validate_config(ctx, config)
    log.info('config %s' % config)

    need_install = {}  # sha1 to dl, or path to rpm or deb
    need_version = {}  # utsrelease or sha1
    kdb = {}
    for role, role_config in config.iteritems():
        # gather information about this remote
        (role_remote, ) = ctx.cluster.only(role).remotes.keys()
        system_type, system_ver = role_remote.os.name, role_remote.os.version
        if role_config.get('rpm') or role_config.get('deb'):
            # We only care about path - deb: vs rpm: is meaningless,
            # rpm: just happens to be parsed first.  Nothing is stopping
            # 'deb: /path/to/foo.rpm' and it will work provided remote's
            # os.package_type is 'rpm' and vice versa.
            path = role_config.get('rpm')
            if not path:
                path = role_config.get('deb')
            sha1 = get_sha1_from_pkg_name(path)
            assert sha1, "failed to extract commit hash from path %s" % path
            if need_to_install(ctx, role, sha1):
                need_install[role] = path
                need_version[role] = sha1
        elif role_config.get('sha1') == 'distro':
            if need_to_install_distro(ctx, role):
                need_install[role] = 'distro'
                need_version[role] = 'distro'
        elif role_config.get("koji", None):
            # installing a kernel from koji
            build_id = role_config.get("koji")
            if role_remote.os.package_type != "rpm":
                msg = ("Installing a kernel from koji is only supported "
                       "on rpm based systems. System type is {system_type}.")
                msg = msg.format(system_type=system_type)
                log.error(msg)
                ctx.summary["failure_reason"] = msg
                ctx.summary["status"] = "dead"
                raise ConfigError(msg)

            # FIXME: this install should probably happen somewhere else
            # but I'm not sure where, so we'll leave it here for now.
            install_package('koji', role_remote)

            # get information about this build from koji
            build_info = get_koji_build_info(build_id, role_remote, ctx)
            version = "{ver}-{rel}.x86_64".format(ver=build_info["version"],
                                                  rel=build_info["release"])

            if need_to_install(ctx, role, version):
                need_install[role] = build_info
                need_version[role] = version
        else:
            package_type = role_remote.os.package_type
            larch = role_remote.arch
            if package_type == 'rpm':
                if '.' in system_ver:
                    system_ver = system_ver.split('.')[0]
                ldist = '{system_type}{system_ver}'.format(
                    system_type=system_type, system_ver=system_ver)
            if package_type == 'deb':
                system_ver = role_remote.os.codename
                ldist = '{system_ver}'.format(system_ver=system_ver)
            sha1, base_url = teuthology.get_ceph_binary_url(
                package='kernel',
                branch=role_config.get('branch'),
                tag=role_config.get('tag'),
                sha1=role_config.get('sha1'),
                flavor='basic',
                format=package_type,
                dist=ldist,
                arch=larch,
            )
            log.debug('sha1 for {role} is {sha1}'.format(role=role, sha1=sha1))
            ctx.summary['{role}-kernel-sha1'.format(role=role)] = sha1

            if need_to_install(ctx, role, sha1):
                version = sha1
                version_url = urlparse.urljoin(base_url, 'version')
                try:
                    version_fp = urllib2.urlopen(version_url)
                    version = version_fp.read().rstrip('\n')
                    version_fp.close()
                except urllib2.HTTPError:
                    log.debug(
                        'failed to get utsrelease string using url {url}'.
                        format(url=version_url))

                if not version:
                    raise VersionNotFoundError(
                        "{url} is empty!".format(url=version_url))

                need_install[role] = sha1
                need_version[role] = version

        # enable or disable kdb if specified, otherwise do not touch
        if role_config.get('kdb') is not None:
            kdb[role] = role_config.get('kdb')

    if need_install:
        install_firmware(ctx, need_install)
        download_kernel(ctx, need_install)
        install_and_reboot(ctx, need_install)
        wait_for_reboot(ctx, need_version, timeout)

    enable_disable_kdb(ctx, kdb)
Example #10
0
def download_kernel(ctx, config):
    """
    Download a Debian kernel and copy the assocated linux image.

    :param ctx: Context
    :param config: Configuration
    """
    procs = {}
    #Don't need to download distro kernels
    for role, src in config.iteritems():
        (role_remote,) = ctx.cluster.only(role).remotes.keys()
	if src.find('distro') >= 0:
            log.info('Installing newest kernel distro');
            return
        package_type = teuthology.get_system_type(role_remote)
        if src.find('/') >= 0:
            # local deb
            log.info('Copying kernel deb {path} to {role}...'.format(path=src,
                                                                     role=role))
            f = open(src, 'r')
            proc = role_remote.run(
                args=[
                    'python', '-c',
                    'import shutil, sys; shutil.copyfileobj(sys.stdin, file(sys.argv[1], "wb"))',
                    '/tmp/linux-image.deb',
                    ],
                wait=False,
                stdin=f
                )
            procs[role_remote.name] = proc
        else:
            log.info('Downloading kernel {sha1} on {role}...'.format(sha1=src,
                                                                     role=role))
            if package_type == 'rpm':
                kernelstring, kernel_url = get_version_from_rpm(role_remote, src)
                unamestring = kernelstring.split('-')[1]
                output, err_mess = StringIO(), StringIO()
                role_remote.run(args=['sudo', 'yum', 'list', 'installed', 'kernel'], stdout=output, stderr=err_mess )
                # Check if short (first 8 digits) sha1 is in uname output as expected
                short_sha1 = src[0:7]
                if short_sha1 in output.getvalue() or unamestring in output.getvalue():
                    output.close()
                    err_mess.close()
                    continue
                output.close()
                err_mess.close()
                proc = role_remote.run(
                    args=[
                        'sudo',
                        'rpm',
                        '-ivh',
                        '--oldpackage',
                        '--replacefiles',
                        '--replacepkgs', 
                        kernel_url
                        ],
                    wait=False
                    )
                procs[role_remote.name] = proc
                continue

            larch, ldist = role_remote.arch, role_remote.os.codename
            _, deb_url = teuthology.get_ceph_binary_url(
                package='kernel',
                sha1=src,
                format='deb',
                flavor='basic',
                arch=larch,
                dist=ldist,
                )

            log.info('fetching kernel from {url}'.format(url=deb_url))
            proc = role_remote.run(
                args=[
                    'sudo', 'rm', '-f', '/tmp/linux-image.deb',
                    run.Raw('&&'),
                    'echo',
                    'linux-image.deb',
                    run.Raw('|'),
                    'wget',
                    '-nv',
                    '-O',
                    '/tmp/linux-image.deb',
                    '--base={url}'.format(url=deb_url),
                    '--input-file=-',
                    ],
                wait=False)
            procs[role_remote.name] = proc

    for name, proc in procs.iteritems():
        log.debug('Waiting for download/copy to %s to complete...', name)
        proc.wait()
Example #11
0
def binaries(ctx, config):
    path = config.get('path')

    if path is None:
        # fetch Apache Hadoop from gitbuilder
        log.info(
            'Fetching and unpacking Apache Hadoop binaries from gitbuilder...')
        apache_sha1, apache_hadoop_bindir_url = teuthology.get_ceph_binary_url(
            package='apache-hadoop',
            branch=config.get('apache_branch'),
            tag=config.get('tag'),
            sha1=config.get('sha1'),
            flavor=config.get('flavor'),
            format=config.get('format'),
            dist=config.get('dist'),
            arch=config.get('arch'),
        )
        log.info('apache_hadoop_bindir_url %s' % (apache_hadoop_bindir_url))
        ctx.summary['apache-hadoop-sha1'] = apache_sha1

        # fetch Inktank Hadoop from gitbuilder
        log.info(
            'Fetching and unpacking Inktank Hadoop binaries from gitbuilder...'
        )
        inktank_sha1, inktank_hadoop_bindir_url = teuthology.get_ceph_binary_url(
            package='hadoop',
            branch=config.get('inktank_branch'),
            tag=config.get('tag'),
            sha1=config.get('sha1'),
            flavor=config.get('flavor'),
            format=config.get('format'),
            dist=config.get('dist'),
            arch=config.get('arch'),
        )
        log.info('inktank_hadoop_bindir_url %s' % (inktank_hadoop_bindir_url))
        ctx.summary['inktank-hadoop-sha1'] = inktank_sha1

    else:
        raise Exception(
            "The hadoop task does not support the path argument at present")

    with parallel() as p:
        hadoopNodes = ctx.cluster.only(teuthology.is_type('hadoop'))
        # these can happen independently
        for remote in hadoopNodes.remotes.iterkeys():
            p.spawn(_node_binaries, ctx, config, remote,
                    inktank_hadoop_bindir_url, apache_hadoop_bindir_url)

    try:
        yield
    finally:
        log.info('Removing hadoop binaries...')
        run.wait(
            ctx.cluster.run(
                args=[
                    'rm', '-rf', '--', '{tdir}/apache_hadoop'.format(
                        tdir=teuthology.get_testdir(ctx))
                ],
                wait=False,
            ), )
        run.wait(
            ctx.cluster.run(
                args=[
                    'rm', '-rf', '--', '{tdir}/inktank_hadoop'.format(
                        tdir=teuthology.get_testdir(ctx))
                ],
                wait=False,
            ), )
Example #12
0
def install_hadoop(ctx, config):
    testdir = teuthology.get_testdir(ctx)

    log.info("Downloading Hadoop...")
    hadoop_tarball = "{tdir}/hadoop.tar.gz".format(tdir=testdir)
    hadoops = ctx.cluster.only(teuthology.is_type('hadoop'))
    run.wait(
        hadoops.run(
            args = [
                'wget',
                '-nv',
                '-O',
                hadoop_tarball,
                HADOOP_2x_URL
            ],
            wait = False,
            )
        )

    log.info("Create directory for Hadoop install...")
    hadoop_dir = "{tdir}/hadoop".format(tdir=testdir)
    run.wait(
        hadoops.run(
            args = [
                'mkdir',
                hadoop_dir
            ],
            wait = False,
            )
        )

    log.info("Unpacking Hadoop...")
    run.wait(
        hadoops.run(
            args = [
                'tar',
                'xzf',
                hadoop_tarball,
                '--strip-components=1',
                '-C',
                hadoop_dir
            ],
            wait = False,
            )
        )

    log.info("Removing Hadoop download...")
    run.wait(
        hadoops.run(
            args = [
                'rm',
                hadoop_tarball
            ],
            wait = False,
            )
        )

    log.info("Create Hadoop temporary directory...")
    hadoop_tmp_dir = "{tdir}/hadoop_tmp".format(tdir=testdir)
    run.wait(
        hadoops.run(
            args = [
                'mkdir',
                hadoop_tmp_dir
            ],
            wait = False,
            )
        )

    if not config.get('hdfs', False):
        log.info("Fetching cephfs-hadoop...")

        sha1, url = teuthology.get_ceph_binary_url(
                package = "hadoop",
                format = "jar",
                dist = "precise",
                arch = "x86_64",
                flavor = "basic",
                branch = "master")

        run.wait(
            hadoops.run(
                args = [
                    'wget',
                    '-nv',
                    '-O',
                    "{tdir}/cephfs-hadoop.jar".format(tdir=testdir), # FIXME
                    url + "/cephfs-hadoop-0.80.6.jar", # FIXME
                ],
                wait = False,
                )
            )

        run.wait(
            hadoops.run(
                args = [
                    'mv',
                    "{tdir}/cephfs-hadoop.jar".format(tdir=testdir),
                    "{tdir}/hadoop/share/hadoop/common/".format(tdir=testdir),
                ],
                wait = False,
                )
            )

        # Copy JNI native bits. Need to do this explicitly because the
        # handling is dependent on the os-type.
        for remote in hadoops.remotes:
            libcephfs_jni_path = None
            if remote.os.package_type == 'rpm':
                libcephfs_jni_path = "/usr/lib64/libcephfs_jni.so.1.0.0"
            elif remote.os.package_type == 'deb':
                libcephfs_jni_path = "/usr/lib/jni/libcephfs_jni.so"
            else:
                raise UnsupportedPackageTypeError(remote)

            libcephfs_jni_fname = "libcephfs_jni.so"
            remote.run(
                args = [
                    'cp',
                    libcephfs_jni_path,
                    "{tdir}/hadoop/lib/native/{fname}".format(tdir=testdir,
                        fname=libcephfs_jni_fname),
                ])

        run.wait(
            hadoops.run(
                args = [
                    'cp',
                    "/usr/share/java/libcephfs.jar",
                    "{tdir}/hadoop/share/hadoop/common/".format(tdir=testdir),
                ],
                wait = False,
                )
            )

    configure(ctx, config, hadoops)

    try:
        yield
    finally:
        run.wait(
            hadoops.run(
                args = [
                    'rm',
                    '-rf',
                    hadoop_dir,
                    hadoop_tmp_dir
                ],
                wait = False,
                )
            )
Example #13
0
def binaries(ctx, config):
    path = config.get('path')
    tmpdir = None

    if path is None:
        # fetch from gitbuilder gitbuilder
        log.info('Fetching and unpacking ceph binaries from gitbuilder...')
        sha1, ceph_bindir_url = teuthology.get_ceph_binary_url(
            branch=config.get('branch'),
            tag=config.get('tag'),
            sha1=config.get('sha1'),
            flavor=config.get('flavor'),
            )
        ctx.summary['ceph-sha1'] = sha1
        if ctx.archive is not None:
            with file(os.path.join(ctx.archive, 'ceph-sha1'), 'w') as f:
                f.write(sha1 + '\n')

        with parallel() as p:
            for remote in ctx.cluster.remotes.iterkeys():
                p.spawn(_download_binaries, remote, ceph_bindir_url)
    else:
        with tempfile.TemporaryFile(prefix='teuthology-tarball-', suffix='.tgz') as tar_fp:
            tmpdir = tempfile.mkdtemp(prefix='teuthology-tarball-')
            try:
                log.info('Installing %s to %s...' % (path, tmpdir))
                subprocess.check_call(
                    args=[
                        'make',
                        'install',
                        'DESTDIR={tmpdir}'.format(tmpdir=tmpdir),
                        ],
                    cwd=path,
                    )
                try:
                    os.symlink('.', os.path.join(tmpdir, 'usr', 'local'))
                except OSError as e:
                    if e.errno == errno.EEXIST:
                        pass
                    else:
                        raise
                log.info('Building ceph binary tarball from %s...', tmpdir)
                subprocess.check_call(
                    args=[
                        'tar',
                        'cz',
                        '.',
                        ],
                    cwd=tmpdir,
                    stdout=tar_fp,
                    )
            finally:
                shutil.rmtree(tmpdir, ignore_errors=True)
            log.info('Pushing tarball...')
            tar_fp.seek(0)
            writes = ctx.cluster.run(
                args=[
                    'install', '-d', '-m0755', '--', '/tmp/cephtest/binary',
                    run.Raw('&&'),
                    'tar', '-xzf', '-', '-C', '/tmp/cephtest/binary'
                    ],
                stdin=run.PIPE,
                wait=False,
                )
            teuthology.feed_many_stdins_and_close(tar_fp, writes)
            run.wait(writes)

    try:
        yield
    finally:
        log.info('Removing ceph binaries...')
        run.wait(
            ctx.cluster.run(
                args=[
                    'rm',
                    '-rf',
                    '--',
                    '/tmp/cephtest/binary',
                    ],
                wait=False,
                ),
            )
Example #14
0
def install_and_reboot(ctx, config):
    procs = {}
    for role, sha1 in config.iteritems():
        log.info('Installing kernel version {sha1} on {role}...'.format(
            sha1=sha1, role=role))
        (role_remote, ) = ctx.cluster.only(role).remotes.keys()
        _, deb_url = teuthology.get_ceph_binary_url(sha1=sha1, flavor='kernel')
        log.info('fetching kernel from {url}'.format(url=deb_url))
        proc = role_remote.run(
            args=[
                'echo',
                'linux-image.deb',
                run.Raw('|'),
                'wget',
                '-nv',
                '-O',
                '/tmp/linux-image.deb',
                '--base={url}'.format(url=deb_url),
                '--input-file=-',
                run.Raw('&&'),
                'sudo',
                'dpkg',
                '-i',
                '/tmp/linux-image.deb',
                run.Raw('&&'),
                # and now extract the actual boot image name from the deb
                'dpkg-deb',
                '--fsys-tarfile',
                '/tmp/linux-image.deb',
                run.Raw('|'),
                'tar',
                '-t',
                '-v',
                '-f',
                '-',
                '--wildcards',
                '--',
                './boot/vmlinuz-*',
                run.Raw('|'),
                # we can only rely on mawk being installed, so just call it explicitly
                'mawk',
                # and use the image name to construct the content of
                # the grub menu entry, so we can default to it;
                # hardcoded to assume Ubuntu, English, etc.
                r'{sub("^\\./boot/vmlinuz-", "", $6); print "cat <<EOF\n" "set default=\"Ubuntu, with Linux " $6 "\"\n" "EOF"}',
                # make it look like an emacs backup file so
                # unfortunately timed update-grub runs don't pick it
                # up yet; use sudo tee so we are able to write to /etc
                run.Raw('|'),
                'sudo',
                'tee',
                '--',
                '/etc/grub.d/01_ceph_kernel.tmp~',
                run.Raw('>/dev/null'),
                run.Raw('&&'),
                'sudo',
                'chmod',
                'a+x',
                '--',
                '/etc/grub.d/01_ceph_kernel.tmp~',
                run.Raw('&&'),
                'sudo',
                'mv',
                '--',
                '/etc/grub.d/01_ceph_kernel.tmp~',
                '/etc/grub.d/01_ceph_kernel',
                run.Raw('&&'),
                'sudo',
                'update-grub',
                run.Raw('&&'),
                'rm',
                '/tmp/linux-image.deb',
                run.Raw('&&'),
                'sudo',
                'shutdown',
                '-r',
                'now',
            ],
            wait=False,
        )
        procs[role_remote.name] = proc

    for name, proc in procs.iteritems():
        log.debug('Waiting for install on %s to complete...', name)
        proc.exitstatus.get()
Example #15
0
def task(ctx, config):
    """
    Make sure the specified kernel is installed.
    This can be a branch, tag, or sha1 of ceph-client.git.

    To install the kernel from the master branch on all hosts::

        kernel:
        tasks:
        - ceph:

    To wait 5 minutes for hosts to reboot::

        kernel:
          timeout: 300
        tasks:
        - ceph:

    To specify different kernels for each client::

        kernel:
          client.0:
            branch: foo
          client.1:
            tag: v3.0rc1
          client.2:
            sha1: db3540522e955c1ebb391f4f5324dff4f20ecd09
        tasks:
        - ceph:

    You can specify a branch, tag, or sha1 for all roles
    of a certain type (more specific roles override this)::

        kernel:
          client:
            tag: v3.0
          osd:
            branch: btrfs_fixes
          client.1:
            branch: more_specific_branch
          osd.3:
            branch: master
    """
    assert config is None or isinstance(config, dict), \
        "task kernel only supports a dictionary for configuration"

    timeout = 300
    if config is not None and 'timeout' in config:
        timeout = config.pop('timeout')

    config = normalize_config(ctx, config)
    validate_config(ctx, config)

    need_install = {}
    for role, role_config in config.iteritems():
        sha1, _ = teuthology.get_ceph_binary_url(
            branch=role_config.get('branch'),
            tag=role_config.get('tag'),
            sha1=role_config.get('sha1'),
            flavor='kernel',
        )
        log.debug('sha1 for {role} is {sha1}'.format(role=role, sha1=sha1))
        ctx.summary['{role}-kernel-sha1'.format(role=role)] = sha1
        if need_to_install(ctx, role, sha1):
            need_install[role] = sha1

    if need_install:
        install_and_reboot(ctx, need_install)
        wait_for_reboot(ctx, need_install, timeout)
Example #16
0
def download_kernel(ctx, config):
    """
    Download a Debian kernel and copy the assocated linux image.

    :param ctx: Context
    :param config: Configuration
    """
    procs = {}
    #Don't need to download distro kernels
    for role, src in config.iteritems():
        (role_remote, ) = ctx.cluster.only(role).remotes.keys()
        if src.find('distro') >= 0:
            log.info('Installing newest kernel distro')
            return
        package_type = teuthology.get_system_type(role_remote)
        if src.find('/') >= 0:
            # local deb
            log.info('Copying kernel deb {path} to {role}...'.format(
                path=src, role=role))
            f = open(src, 'r')
            proc = role_remote.run(args=[
                'python',
                '-c',
                'import shutil, sys; shutil.copyfileobj(sys.stdin, file(sys.argv[1], "wb"))',
                '/tmp/linux-image.deb',
            ],
                                   wait=False,
                                   stdin=f)
            procs[role_remote.name] = proc
        else:
            log.info('Downloading kernel {sha1} on {role}...'.format(
                sha1=src, role=role))
            if package_type == 'rpm':
                dist, ver = teuthology.get_system_type(role_remote,
                                                       distro=True,
                                                       version=True)
                if '.' in ver:
                    ver = ver.split('.')[0]
                ldist = '{dist}{ver}'.format(dist=dist, ver=ver)
                _, rpm_url = teuthology.get_ceph_binary_url(
                    package='kernel',
                    sha1=src,
                    format='rpm',
                    flavor='basic',
                    arch='x86_64',
                    dist=ldist,
                )

                kernel_url = urlparse.urljoin(rpm_url, 'kernel.x86_64.rpm')
                output, err_mess = StringIO(), StringIO()
                role_remote.run(
                    args=['sudo', 'yum', 'list', 'installed', 'kernel'],
                    stdout=output,
                    stderr=err_mess)
                # Check if short (first 8 digits) sha1 is in uname output as expected
                short_sha1 = src[0:7]
                if short_sha1 in output.getvalue():
                    output.close()
                    err_mess.close()
                    continue
                output.close()
                err_mess.close()
                proc = role_remote.run(
                    args=['sudo', 'yum', 'install', '-y', kernel_url],
                    wait=False)
                procs[role_remote.name] = proc
                continue

            larch, ldist = _find_arch_and_dist(ctx)
            _, deb_url = teuthology.get_ceph_binary_url(
                package='kernel',
                sha1=src,
                format='deb',
                flavor='basic',
                arch=larch,
                dist=ldist,
            )

            log.info('fetching kernel from {url}'.format(url=deb_url))
            proc = role_remote.run(args=[
                'sudo',
                'rm',
                '-f',
                '/tmp/linux-image.deb',
                run.Raw('&&'),
                'echo',
                'linux-image.deb',
                run.Raw('|'),
                'wget',
                '-nv',
                '-O',
                '/tmp/linux-image.deb',
                '--base={url}'.format(url=deb_url),
                '--input-file=-',
            ],
                                   wait=False)
            procs[role_remote.name] = proc

    for name, proc in procs.iteritems():
        log.debug('Waiting for download/copy to %s to complete...', name)
        proc.wait()
Example #17
0
def task(ctx, config):
    """
    Make sure the specified kernel is installed.
    This can be a branch, tag, or sha1 of ceph-client.git.

    To install the kernel from the master branch on all hosts::

        kernel:
        tasks:
        - ceph:

    To wait 5 minutes for hosts to reboot::

        kernel:
          timeout: 300
        tasks:
        - ceph:

    To specify different kernels for each client::

        kernel:
          client.0:
            branch: foo
          client.1:
            tag: v3.0rc1
          client.2:
            sha1: db3540522e955c1ebb391f4f5324dff4f20ecd09
        tasks:
        - ceph:

    You can specify a branch, tag, or sha1 for all roles
    of a certain type (more specific roles override this)::

        kernel:
          client:
            tag: v3.0
          osd:
            branch: btrfs_fixes
          client.1:
            branch: more_specific_branch
          osd.3:
            branch: master

    To enable kdb::

        kernel:
          kdb: true

    :param ctx: Context
    :param config: Configuration
    """
    assert config is None or isinstance(config, dict), \
        "task kernel only supports a dictionary for configuration"

    timeout = 300
    if config is not None and 'timeout' in config:
        timeout = config.pop('timeout')

    config = normalize_config(ctx, config)
    validate_config(ctx, config)
    log.info('config %s' % config)

    need_install = {}  # sha1 to dl, or path to deb
    need_version = {}  # utsrelease or sha1
    kdb = {}
    for role, role_config in config.iteritems():
        if role_config.get('deb'):
            path = role_config.get('deb')
            match = re.search('\d+-g(\w{7})', path)
            if match:
                sha1 = match.group(1)
                log.info('kernel deb sha1 appears to be %s', sha1)
                if need_to_install(ctx, role, sha1):
                    need_install[role] = path
                    need_version[role] = sha1
            else:
                log.info(
                    'unable to extract sha1 from deb path, forcing install')
                assert False
        elif role_config.get('sha1') == 'distro':
            if need_to_install_distro(ctx, role):
                need_install[role] = 'distro'
                need_version[role] = 'distro'
        else:
            larch, ldist = _find_arch_and_dist(ctx)
            sha1, base_url = teuthology.get_ceph_binary_url(
                package='kernel',
                branch=role_config.get('branch'),
                tag=role_config.get('tag'),
                sha1=role_config.get('sha1'),
                flavor='basic',
                format='deb',
                dist=ldist,
                arch=larch,
            )
            log.debug('sha1 for {role} is {sha1}'.format(role=role, sha1=sha1))
            ctx.summary['{role}-kernel-sha1'.format(role=role)] = sha1

            if need_to_install(ctx, role, sha1):
                version = sha1
                version_url = urlparse.urljoin(base_url, 'version')
                try:
                    version_fp = urllib2.urlopen(version_url)
                    version = version_fp.read().rstrip('\n')
                    version_fp.close()
                except urllib2.HTTPError:
                    log.debug(
                        'failed to get utsrelease string using url {url}'.
                        format(url=version_url))

                need_install[role] = sha1
                need_version[role] = version

        # enable or disable kdb if specified, otherwise do not touch
        if role_config.get('kdb') is not None:
            kdb[role] = role_config.get('kdb')

    if need_install:
        install_firmware(ctx, need_install)
        download_deb(ctx, need_install)
        install_and_reboot(ctx, need_install)
        wait_for_reboot(ctx, need_version, timeout)

    enable_disable_kdb(ctx, kdb)
Example #18
0
def task(ctx, config):
    """
    Make sure the specified kernel is installed.
    This can be a branch, tag, or sha1 of ceph-client.git.

    To install the kernel from the master branch on all hosts::

        kernel:
        tasks:
        - ceph:

    To wait 5 minutes for hosts to reboot::

        kernel:
          timeout: 300
        tasks:
        - ceph:

    To specify different kernels for each client::

        kernel:
          client.0:
            branch: foo
          client.1:
            tag: v3.0rc1
          client.2:
            sha1: db3540522e955c1ebb391f4f5324dff4f20ecd09
        tasks:
        - ceph:

    You can specify a branch, tag, or sha1 for all roles
    of a certain type (more specific roles override this)::

        kernel:
          client:
            tag: v3.0
          osd:
            branch: btrfs_fixes
          client.1:
            branch: more_specific_branch
          osd.3:
            branch: master

    To enable kdb::

        kernel:
          kdb: true

    :param ctx: Context
    :param config: Configuration
    """
    assert config is None or isinstance(config, dict), \
        "task kernel only supports a dictionary for configuration"

    timeout = 300
    if config is not None and 'timeout' in config:
        timeout = config.pop('timeout')

    config = normalize_config(ctx, config)
    validate_config(ctx, config)
    log.info('config %s' % config)

    need_install = {}  # sha1 to dl, or path to deb
    need_version = {}  # utsrelease or sha1
    kdb = {}
    for role, role_config in config.iteritems():
        if role_config.get('deb'):
            path = role_config.get('deb')
            match = re.search('\d+-g(\w{7})', path)
            if match:
                sha1 = match.group(1)
                log.info('kernel deb sha1 appears to be %s', sha1)
                if need_to_install(ctx, role, sha1):
                    need_install[role] = path
                    need_version[role] = sha1
            else:
                log.info('unable to extract sha1 from deb path, forcing install')
                assert False
        elif role_config.get('sha1') == 'distro':
            if need_to_install_distro(ctx, role):
                need_install[role] = 'distro'
                need_version[role] = 'distro'
        else:
            (role_remote,) = ctx.cluster.only(role).remotes.keys()
            larch = role_remote.arch
            package_type = role_remote.os.package_type
            system_type, system_ver = role_remote.os.name, role_remote.os.version
            if package_type == 'rpm':
                if '.' in system_ver:
                    system_ver = system_ver.split('.')[0]
                ldist = '{system_type}{system_ver}'.format(system_type=system_type, system_ver=system_ver)
            if package_type == 'deb':
                system_ver = role_remote.os.codename
                ldist = '{system_ver}'.format(system_ver=system_ver)
            sha1, base_url = teuthology.get_ceph_binary_url(
                package='kernel',
                branch=role_config.get('branch'),
                tag=role_config.get('tag'),
                sha1=role_config.get('sha1'),
                flavor='basic',
                format=package_type,
                dist=ldist,
                arch=larch,
                )
            log.debug('sha1 for {role} is {sha1}'.format(role=role, sha1=sha1))
            ctx.summary['{role}-kernel-sha1'.format(role=role)] = sha1

            if need_to_install(ctx, role, sha1):
                version = sha1
                version_url = urlparse.urljoin(base_url, 'version')
                try:
                    version_fp = urllib2.urlopen(version_url)
                    version = version_fp.read().rstrip('\n')
                    version_fp.close()
                except urllib2.HTTPError:
                    log.debug('failed to get utsrelease string using url {url}'.format(
                              url=version_url))

                need_install[role] = sha1
                need_version[role] = version

        # enable or disable kdb if specified, otherwise do not touch
        if role_config.get('kdb') is not None:
            kdb[role] = role_config.get('kdb')

    if need_install:
        install_firmware(ctx, need_install)
        download_kernel(ctx, need_install)
        install_and_reboot(ctx, need_install)
        wait_for_reboot(ctx, need_version, timeout)

    enable_disable_kdb(ctx, kdb)
Example #19
0
def download_kernel(ctx, config):
    """
    Supply each remote with a kernel package:
      - local kernels are copied over
      - gitbuilder kernels are downloaded
      - nothing is done for distro kernels

    :param ctx: Context
    :param config: Configuration
    """
    procs = {}
    for role, src in config.iteritems():
        needs_download = False

        if src == 'distro':
            # don't need to download distro kernels
            log.debug("src is distro, skipping download")
            continue

        (role_remote, ) = ctx.cluster.only(role).remotes.keys()
        if isinstance(src, dict):
            # we're downloading a kernel from koji, the src dict here
            # is the build_info retrieved from koji using get_koji_build_info
            build_id = src["id"]
            log.info(
                "Downloading kernel with build_id {build_id} on {role}...".
                format(build_id=build_id, role=role))
            needs_download = True
            baseurl = get_kojiroot_base_url(src)
            pkg_name = get_koji_package_name("kernel", src)
        elif src.find('/') >= 0:
            # local package - src is path
            log.info('Copying kernel package {path} to {role}...'.format(
                path=src, role=role))
            f = open(src, 'r')
            proc = role_remote.run(args=[
                'python',
                '-c',
                'import shutil, sys; shutil.copyfileobj(sys.stdin, file(sys.argv[1], "wb"))',
                remote_pkg_path(role_remote),
            ],
                                   wait=False,
                                   stdin=f)
            procs[role_remote.name] = proc
        else:
            # gitbuilder package - src is sha1
            log.info('Downloading kernel {sha1} on {role}...'.format(
                sha1=src, role=role))
            needs_download = True
            package_type = role_remote.os.package_type
            if package_type == 'rpm':
                system_type, system_ver = teuthology.get_system_type(
                    role_remote, distro=True, version=True)
                if '.' in system_ver:
                    system_ver = system_ver.split('.')[0]
                ldist = '{system_type}{system_ver}'.format(
                    system_type=system_type, system_ver=system_ver)
                larch = 'x86_64'
            elif package_type == 'deb':
                ldist, larch = role_remote.os.codename, role_remote.arch
            else:
                raise UnsupportedPackageTypeError(role_remote)

            _, baseurl = teuthology.get_ceph_binary_url(
                package='kernel',
                sha1=src,
                format=package_type,
                flavor='basic',
                arch=larch,
                dist=ldist,
            )

            pkg_name = gitbuilder_pkg_name(role_remote)

            log.info("fetching, gitbuilder baseurl is %s", baseurl)

        if needs_download:
            proc = role_remote.run(args=[
                'rm',
                '-f',
                remote_pkg_path(role_remote),
                run.Raw('&&'),
                'echo',
                pkg_name,
                run.Raw('|'),
                'wget',
                '-nv',
                '-O',
                remote_pkg_path(role_remote),
                '--base={url}'.format(url=baseurl),
                '--input-file=-',
            ],
                                   wait=False)
            procs[role_remote.name] = proc

    for name, proc in procs.iteritems():
        log.debug('Waiting for download/copy to %s to complete...', name)
        proc.wait()
Example #20
0
def task(ctx, config):
    """
    Make sure the specified kernel is installed.
    This can be a branch, tag, or sha1 of ceph-client.git.

    To install the kernel from the master branch on all hosts::

        kernel:
        tasks:
        - ceph:

    To wait 5 minutes for hosts to reboot::

        kernel:
          timeout: 300
        tasks:
        - ceph:

    To specify different kernels for each client::

        kernel:
          client.0:
            branch: foo
          client.1:
            tag: v3.0rc1
          client.2:
            sha1: db3540522e955c1ebb391f4f5324dff4f20ecd09
        tasks:
        - ceph:

    You can specify a branch, tag, or sha1 for all roles
    of a certain type (more specific roles override this)::

        kernel:
          client:
            tag: v3.0
          osd:
            branch: btrfs_fixes
          client.1:
            branch: more_specific_branch
          osd.3:
            branch: master
    """
    assert config is None or isinstance(config, dict), \
        "task kernel only supports a dictionary for configuration"

    timeout = 300
    if config is not None and 'timeout' in config:
        timeout = config.pop('timeout')

    config = normalize_config(ctx, config)
    validate_config(ctx, config)

    need_install = {}
    for role, role_config in config.iteritems():
        sha1, _ = teuthology.get_ceph_binary_url(
            branch=role_config.get('branch'),
            tag=role_config.get('tag'),
            sha1=role_config.get('sha1'),
            flavor='kernel',
            )
        log.debug('sha1 for {role} is {sha1}'.format(role=role, sha1=sha1))
        ctx.summary['{role}-kernel-sha1'.format(role=role)] = sha1
        if need_to_install(ctx, role, sha1):
            need_install[role] = sha1

    if need_install:
        install_and_reboot(ctx, need_install)
        wait_for_reboot(ctx, need_install, timeout)
Example #21
0
def binaries(ctx, config):
    path = config.get('path')
    tmpdir = None

    if path is None:
        # fetch from gitbuilder gitbuilder
        log.info('Fetching and unpacking ceph binaries from gitbuilder...')
        sha1, ceph_bindir_url = teuthology.get_ceph_binary_url(
            package='ceph',
            branch=config.get('branch'),
            tag=config.get('tag'),
            sha1=config.get('sha1'),
            flavor=config.get('flavor'),
            format=config.get('format'),
            dist=config.get('dist'),
            arch=config.get('arch'),
            )
        ctx.summary['ceph-sha1'] = sha1
        if ctx.archive is not None:
            with file(os.path.join(ctx.archive, 'ceph-sha1'), 'w') as f:
                f.write(sha1 + '\n')

        with parallel() as p:
            for remote in ctx.cluster.remotes.iterkeys():
                p.spawn(_download_binaries, remote, ceph_bindir_url)
    else:
        with tempfile.TemporaryFile(prefix='teuthology-tarball-', suffix='.tgz') as tar_fp:
            tmpdir = tempfile.mkdtemp(prefix='teuthology-tarball-')
            try:
                log.info('Installing %s to %s...' % (path, tmpdir))
                subprocess.check_call(
                    args=[
                        'make',
                        'install',
                        'DESTDIR={tmpdir}'.format(tmpdir=tmpdir),
                        ],
                    cwd=path,
                    )
                try:
                    os.symlink('.', os.path.join(tmpdir, 'usr', 'local'))
                except OSError as e:
                    if e.errno == errno.EEXIST:
                        pass
                    else:
                        raise
                log.info('Building ceph binary tarball from %s...', tmpdir)
                subprocess.check_call(
                    args=[
                        'tar',
                        'cz',
                        '.',
                        ],
                    cwd=tmpdir,
                    stdout=tar_fp,
                    )
            finally:
                shutil.rmtree(tmpdir, ignore_errors=True)
            log.info('Pushing tarball...')
            tar_fp.seek(0)
            writes = ctx.cluster.run(
                args=[
                    'install', '-d', '-m0755', '--', '/tmp/cephtest/binary',
                    run.Raw('&&'),
                    'tar', '-xzf', '-', '-C', '/tmp/cephtest/binary'
                    ],
                stdin=run.PIPE,
                wait=False,
                )
            teuthology.feed_many_stdins_and_close(tar_fp, writes)
            run.wait(writes)

    try:
        yield
    finally:
        log.info('Removing ceph binaries...')
        run.wait(
            ctx.cluster.run(
                args=[
                    'rm',
                    '-rf',
                    '--',
                    '/tmp/cephtest/binary',
                    ],
                wait=False,
                ),
            )
Example #22
0
def install_and_reboot(ctx, config):
    procs = {}
    for role, sha1 in config.iteritems():
        log.info('Installing kernel version {sha1} on {role}...'.format(sha1=sha1,
                                                                        role=role))
        (role_remote,) = ctx.cluster.only(role).remotes.keys()
        _, deb_url = teuthology.get_ceph_binary_url(sha1=sha1, flavor='kernel')
        log.info('fetching kernel from {url}'.format(url=deb_url))
        proc = role_remote.run(
            args=[
                'echo',
                'linux-image.deb',
                run.Raw('|'),
                'wget',
                '-nv',
                '-O',
                '/tmp/linux-image.deb',
                '--base={url}'.format(url=deb_url),
                '--input-file=-',
                run.Raw('&&'),
                'sudo',
                'dpkg',
                '-i',
                '/tmp/linux-image.deb',
                run.Raw('&&'),
                # and now extract the actual boot image name from the deb
                'dpkg-deb',
                '--fsys-tarfile',
                '/tmp/linux-image.deb',
                run.Raw('|'),
                'tar',
                '-t',
                '-v',
                '-f', '-',
                '--wildcards',
                '--',
                './boot/vmlinuz-*',
                run.Raw('|'),
                # we can only rely on mawk being installed, so just call it explicitly
                'mawk',
                # and use the image name to construct the content of
                # the grub menu entry, so we can default to it;
                # hardcoded to assume Ubuntu, English, etc.
                r'{sub("^\\./boot/vmlinuz-", "", $6); print "cat <<EOF\n" "set default=\"Ubuntu, with Linux " $6 "\"\n" "EOF"}',
                # make it look like an emacs backup file so
                # unfortunately timed update-grub runs don't pick it
                # up yet; use sudo tee so we are able to write to /etc
                run.Raw('|'),
                'sudo',
                'tee',
                '--',
                '/etc/grub.d/01_ceph_kernel.tmp~',
                run.Raw('>/dev/null'),
                run.Raw('&&'),
                'sudo',
                'chmod',
                'a+x',
                '--',
                '/etc/grub.d/01_ceph_kernel.tmp~',
                run.Raw('&&'),
                'sudo',
                'mv',
                '--',
                '/etc/grub.d/01_ceph_kernel.tmp~',
                '/etc/grub.d/01_ceph_kernel',
                run.Raw('&&'),
                'sudo',
                'update-grub',
                run.Raw('&&'),
                'rm',
                '/tmp/linux-image.deb',
                run.Raw('&&'),
                'sudo',
                'shutdown',
                '-r',
                'now',
                ],
            wait=False,
            )
        procs[role_remote.name] = proc

    for name, proc in procs.iteritems():
        log.debug('Waiting for install on %s to complete...', name)
        proc.exitstatus.get()
Example #23
0
def install_hadoop(ctx, config):
    testdir = teuthology.get_testdir(ctx)

    log.info("Downloading Hadoop...")
    hadoop_tarball = "{tdir}/hadoop.tar.gz".format(tdir=testdir)
    hadoops = ctx.cluster.only(teuthology.is_type('hadoop'))
    run.wait(
        hadoops.run(
            args=['wget', '-nv', '-O', hadoop_tarball, HADOOP_2x_URL],
            wait=False,
        ))

    log.info("Create directory for Hadoop install...")
    hadoop_dir = "{tdir}/hadoop".format(tdir=testdir)
    run.wait(hadoops.run(
        args=['mkdir', hadoop_dir],
        wait=False,
    ))

    log.info("Unpacking Hadoop...")
    run.wait(
        hadoops.run(
            args=[
                'tar', 'xzf', hadoop_tarball, '--strip-components=1', '-C',
                hadoop_dir
            ],
            wait=False,
        ))

    log.info("Removing Hadoop download...")
    run.wait(hadoops.run(
        args=['rm', hadoop_tarball],
        wait=False,
    ))

    log.info("Create Hadoop temporary directory...")
    hadoop_tmp_dir = "{tdir}/hadoop_tmp".format(tdir=testdir)
    run.wait(hadoops.run(
        args=['mkdir', hadoop_tmp_dir],
        wait=False,
    ))

    if not config.get('hdfs', False):
        log.info("Fetching cephfs-hadoop...")

        sha1, url = teuthology.get_ceph_binary_url(package="hadoop",
                                                   format="jar",
                                                   dist="precise",
                                                   arch="x86_64",
                                                   flavor="basic",
                                                   branch="master")

        run.wait(
            hadoops.run(
                args=[
                    'wget',
                    '-nv',
                    '-O',
                    "{tdir}/cephfs-hadoop.jar".format(tdir=testdir),  # FIXME
                    url + "/cephfs-hadoop-0.80.6.jar",  # FIXME
                ],
                wait=False,
            ))

        run.wait(
            hadoops.run(
                args=[
                    'mv',
                    "{tdir}/cephfs-hadoop.jar".format(tdir=testdir),
                    "{tdir}/hadoop/share/hadoop/common/".format(tdir=testdir),
                ],
                wait=False,
            ))

        # Copy JNI native bits. Need to do this explicitly because the
        # handling is dependent on the os-type.
        for remote in hadoops.remotes:
            libcephfs_jni_path = None
            if remote.os.package_type == 'rpm':
                libcephfs_jni_path = "/usr/lib64/libcephfs_jni.so.1.0.0"
            elif remote.os.package_type == 'deb':
                libcephfs_jni_path = "/usr/lib/jni/libcephfs_jni.so"
            else:
                raise UnsupportedPackageTypeError(remote)

            libcephfs_jni_fname = "libcephfs_jni.so"
            remote.run(args=[
                'cp',
                libcephfs_jni_path,
                "{tdir}/hadoop/lib/native/{fname}".format(
                    tdir=testdir, fname=libcephfs_jni_fname),
            ])

        run.wait(
            hadoops.run(
                args=[
                    'cp',
                    "/usr/share/java/libcephfs.jar",
                    "{tdir}/hadoop/share/hadoop/common/".format(tdir=testdir),
                ],
                wait=False,
            ))

    configure(ctx, config, hadoops)

    try:
        yield
    finally:
        run.wait(
            hadoops.run(
                args=['rm', '-rf', hadoop_dir, hadoop_tmp_dir],
                wait=False,
            ))
Example #24
0
def task(ctx, config):
    """
    Make sure the specified kernel is installed.
    This can be a branch, tag, or sha1 of ceph-client.git or a local
    kernel package.

    To install ceph-client.git branch (default: master)::

        kernel:
          branch: testing

    To install ceph-client.git tag::

        kernel:
          tag: v3.18

    To install ceph-client.git sha1::

        kernel:
          sha1: 275dd19ea4e84c34f985ba097f9cddb539f54a50

    To install from a koji build_id::

        kernel:
          koji: 416058

    To install from a koji task_id::

        kernel:
          koji_task: 9678206

    When installing from koji you also need to set the urls for koji hub
    and the koji root in your teuthology.yaml config file. These are shown
    below with their default values::

        kojihub_url: http://koji.fedoraproject.org/kojihub
        kojiroot_url: http://kojipkgs.fedoraproject.org/packages

    When installing from a koji task_id you also need to set koji_task_url,
    which is the base url used to download rpms from koji task results::

        koji_task_url: https://kojipkgs.fedoraproject.org/work/

    To install local rpm (target should be an rpm system)::

        kernel:
          rpm: /path/to/appropriately-named.rpm

    To install local deb (target should be a deb system)::

        kernel:
          deb: /path/to/appropriately-named.deb

    For rpm: or deb: to work it should be able to figure out sha1 from
    local kernel package basename, see get_sha1_from_pkg_name().  This
    means that you can't for example install a local tag - package built
    with upstream {rpm,deb}-pkg targets won't have a sha1 in its name.

    If you want to schedule a run and use a local kernel package, you
    have to copy the package over to a box teuthology workers are
    running on and specify a path to the package on that box.

    All of the above will install a specified kernel on all targets.
    You can specify different kernels for each role or for all roles of
    a certain type (more specific roles override less specific, see
    normalize_config() for details)::

        kernel:
          client:
            tag: v3.0
          osd:
            branch: btrfs_fixes
          client.1:
            branch: more_specific
          osd.3:
            branch: master

    To wait 3 minutes for hosts to reboot (default: 300)::

        kernel:
          timeout: 180

    To enable kdb::

        kernel:
          kdb: true

    :param ctx: Context
    :param config: Configuration
    """
    assert config is None or isinstance(config, dict), \
        "task kernel only supports a dictionary for configuration"

    timeout = 300
    if config is not None and 'timeout' in config:
        timeout = config.pop('timeout')

    config = normalize_config(ctx, config)
    validate_config(ctx, config)
    log.info('config %s' % config)

    need_install = {}  # sha1 to dl, or path to rpm or deb
    need_version = {}  # utsrelease or sha1
    kdb = {}

    remove_old_kernels(ctx)

    for role, role_config in config.iteritems():
        # gather information about this remote
        (role_remote,) = ctx.cluster.only(role).remotes.keys()
        system_type, system_ver = role_remote.os.name, role_remote.os.version
        if role_config.get('rpm') or role_config.get('deb'):
            # We only care about path - deb: vs rpm: is meaningless,
            # rpm: just happens to be parsed first.  Nothing is stopping
            # 'deb: /path/to/foo.rpm' and it will work provided remote's
            # os.package_type is 'rpm' and vice versa.
            path = role_config.get('rpm')
            if not path:
                path = role_config.get('deb')
            sha1 = get_sha1_from_pkg_name(path)
            assert sha1, "failed to extract commit hash from path %s" % path
            if need_to_install(ctx, role, sha1):
                need_install[role] = path
                need_version[role] = sha1
        elif role_config.get('sha1') == 'distro':
            version = need_to_install_distro(role_remote)
            if version:
                need_install[role] = 'distro'
                need_version[role] = version
        elif role_config.get("koji") or role_config.get('koji_task'):
            # installing a kernel from koji
            build_id = role_config.get("koji")
            task_id = role_config.get("koji_task")
            if role_remote.os.package_type != "rpm":
                msg = (
                    "Installing a kernel from koji is only supported "
                    "on rpm based systems. System type is {system_type}."
                )
                msg = msg.format(system_type=system_type)
                log.error(msg)
                ctx.summary["failure_reason"] = msg
                ctx.summary["status"] = "dead"
                raise ConfigError(msg)

            # FIXME: this install should probably happen somewhere else
            # but I'm not sure where, so we'll leave it here for now.
            install_package('koji', role_remote)

            if build_id:
                # get information about this build from koji
                build_info = get_koji_build_info(build_id, role_remote, ctx)
                version = "{ver}-{rel}.x86_64".format(
                    ver=build_info["version"],
                    rel=build_info["release"]
                )
            elif task_id:
                # get information about results of this task from koji
                task_result = get_koji_task_result(task_id, role_remote, ctx)
                # this is not really 'build_info', it's a dict of information
                # about the kernel rpm from the task results, but for the sake
                # of reusing the code below I'll still call it that.
                build_info = get_koji_task_rpm_info(
                    'kernel',
                    task_result['rpms']
                )
                # add task_id so we can know later that we're installing
                # from a task and not a build.
                build_info["task_id"] = task_id
                version = build_info["version"]

            if need_to_install(ctx, role, version):
                need_install[role] = build_info
                need_version[role] = version
        else:
            package_type = role_remote.os.package_type
            larch = role_remote.arch
            if package_type == 'rpm':
                if '.' in system_ver:
                    system_ver = system_ver.split('.')[0]
                ldist = '{system_type}{system_ver}'.format(system_type=system_type, system_ver=system_ver)
            if package_type == 'deb':
                system_ver = role_remote.os.codename
                ldist = '{system_ver}'.format(system_ver=system_ver)
            sha1, base_url = teuthology.get_ceph_binary_url(
                package='kernel',
                branch=role_config.get('branch'),
                tag=role_config.get('tag'),
                sha1=role_config.get('sha1'),
                flavor='basic',
                format=package_type,
                dist=ldist,
                arch=larch,
                )
            log.debug('sha1 for {role} is {sha1}'.format(role=role, sha1=sha1))
            ctx.summary['{role}-kernel-sha1'.format(role=role)] = sha1

            if need_to_install(ctx, role, sha1):
                version = sha1
                version_url = urlparse.urljoin(base_url, 'version')
                try:
                    version_fp = urllib2.urlopen(version_url)
                    version = version_fp.read().rstrip('\n')
                    version_fp.close()
                except urllib2.HTTPError:
                    log.debug('failed to get utsrelease string using url {url}'.format(
                              url=version_url))

                if not version:
                    raise VersionNotFoundError("{url} is empty!".format(
                        url=version_url))

                need_install[role] = sha1
                need_version[role] = version

        # enable or disable kdb if specified, otherwise do not touch
        if role_config.get('kdb') is not None:
            kdb[role] = role_config.get('kdb')

    if need_install:
        install_firmware(ctx, need_install)
        download_kernel(ctx, need_install)
        install_and_reboot(ctx, need_install)
        wait_for_reboot(ctx, need_version, timeout)

    enable_disable_kdb(ctx, kdb)