def downloadsources(source_directory, specfile):
    _logger.info("Downloading additional sources")
    spectool = which("spectool")
    if spectool is None:
        _logger.warning("spectool not found in path, will use bundled version; it might not work")
        spectool = getpath("drb/builddeps/spectool")
    sp("{0} --get-files --directory {1} {2}".format(spectool, source_directory, specfile))
Esempio n. 2
0
def short_test():
    # TODO: run unitests as well here
    click.echo("Starting short self test. Requires networking and may take a bit of time especially at the first run, because data will be downloaded")

    dockerexec = which("docker")
    testpath = getpath("drb/test")
    result = sp("{dockerexec} run --rm -v {testpath}:/testpath phusion/baseimage /bin/bash -c 'cat /testpath/everythinglooksgood.txt'", **locals())
    if result.strip() != "everything looks good":
        click.echo("Basic self test failed: docker run failed. Checklist:\n\nVerify the docker service is running\n"
                   "Verify the 'docker' group exists and your user belongs to it\n"
                   "If you had to add the group, verify you've restarted the 'docker' service after such addition\n"
                   "Verify you've logged out+in after adding your user to the group\n"
                   "Verify selinux is disabled\n"
                   "Verify your disk has enough free space\n"
                   "Error:\n%s\n" % result)
        sys.exit(1)

    tmpdir = mkdtemp()
    try:
        downloadsources(tmpdir, getpath("drb/test/spectooltest.spec"))
        if not os.path.exists(os.path.join(tmpdir, "README.md")):
            click.echo("Basic self test failed, could not download sources; probably a spectool issue (missing perl or wrong version?)")
            sys.exit(1)
    finally:
        shutil.rmtree(tmpdir)

    for fn in os.listdir(getpath("drb/dockerscripts")):
        if not os.access(os.path.join(getpath("drb/dockerscripts"), fn), os.X_OK):
            click.echo("File {0} is not executable, probably an install error has happened. Make sure you're using a recent python+virtualenv".format(fn))
            sys.exit(1)

    click.echo("Short self test succeeded.")
Esempio n. 3
0
def srcrpm(image,
           srcrpm,
           target_directory,
           additional_docker_options,
           verify_signature=False,
           bash_on_failure=False,
           sign_with=None,
           always_pull=False):
    _logger.info("Now building %(srcrpm)s on image %(image)s", locals())
    if not os.path.exists(target_directory):
        os.mkdir(target_directory)

    dockerexec = which("docker")
    dockerscripts = getpath("drb/dockerscripts")
    srpms_temp = tempfile.mkdtemp("SRPMS")
    shutil.copy(srcrpm, srpms_temp)
    internal_docker_options = set()
    srcrpm_basename = os.path.basename(srcrpm)
    uid = os.getuid()
    gid = os.getgid()
    rpmbuild_options = "" if verify_signature else "--nosignature"

    bashonfail = ""
    if bash_on_failure:
        internal_docker_options.add("-i")
        internal_docker_options.add("-t")
        bashonfail = "bashonfail"

    internal_docker_options = " ".join(internal_docker_options)
    encoded_signature = provide_encoded_signature(sign_with)

    if always_pull:
        pull(dockerexec, image)

    serialized_options = serialize({
        "CALLING_UID": uid,
        "CALLING_GID": gid,
        "BASH_ON_FAIL": bashonfail,
        "RPMBUILD_OPTIONS": rpmbuild_options,
        "SRCRPM": srcrpm_basename,
        "GPG_PRIVATE_KEY": encoded_signature
    })

    try:
        additional_docker_options = internal_docker_options + " ".join(
            additional_docker_options)
        srpms_inner_dir = sp(
            "{dockerexec} run {image} rpm --eval %{{_srcrpmdir}}",
            **locals()).strip()
        rpms_inner_dir = sp("{dockerexec} run {image} rpm --eval %{{_rpmdir}}",
                            **locals()).strip()
        sp(
            "{dockerexec} run {additional_docker_options} -v {dockerscripts}:/dockerscripts -v {srpms_temp}:{srpms_inner_dir} -v {target_directory}:{rpms_inner_dir}"
            " -w /dockerscripts {image} ./rpmbuild-srcrpm-in-docker.sh {serialized_options}",
            **locals())
    finally:
        shutil.rmtree(srpms_temp)
Esempio n. 4
0
def dir(imagetag, source_directory, additional_docker_options):
    """Builds a binary RPM from a directory.

    IMAGETAG should be a docker image id or a repository:tag,
    e.g something like a682b68bbaba or alanfranz/drb-epel-6-x86-64:latest

    SOURCE_DIRECTORY should be a directory containing the .spec or the
    .spectemplate file and all the source files and patches referenced
    in such spec.

    ADDITIONAL_DOCKER_OPTIONS whatever is passed will be forwarded
    straight to docker. PLEASE REMEMBER to insert a double dash (--)
    before the first additional options, otherwise it will be mistaken
    for a docker-rpm-builder option.

    example:

    docker-rpm-builder dir a682b68bbaba . -- --dns=10.2.0.1

    """

    # TODO: let spectemplate and/or spec be optional parameters
    # TODO: let the user choose $-delimited templates
    deletespec = False
    spectemplates = glob.glob1(source_directory, "*.spectemplate")
    specfiles = glob.glob1(source_directory, "*.spec")
    if len(spectemplates) > 1:
        raise ValueError("More than one spectemplate found in source directory")

    if spectemplates:
        if specfiles:
            raise ValueError("Found both .spec and .spectemplate in source directory.")
        spectemplate = spectemplates[0]
        template = DoubleDelimiterTemplate(codecs.open(spectemplate, "rb", "utf-8").read())
        with_substitutions = template.substitute(os.environ)
        finalspec = os.path.splitext(spectemplate)[0] + ".spec"
        with codecs.open(finalspec, "wb", "utf-8") as f:
            f.write(with_substitutions)
        specfiles.append(finalspec)
        deletespec = True

    if not specfiles or len(specfiles) > 1:
        raise ValueError("No specfiles or more than one specfile in source directory")

    specfile = specfiles[0]

    # FIXME: delete written specfile if using a spectemplate
    logging.info("Now building project from %s on image %s", source_directory, imagetag)
    # TODO: let this be something more configurable and/or injected
    dockerexec = which("docker")
    try:
        sp("{0} run -v {1}:/dockerscripts -v {2}:/src -w /dockerscripts {3} ./rpmbuild-in-docker.sh {4}:{5} {6}",
           dockerexec, getpath("drb/dockerscripts"), source_directory, imagetag, os.getuid(), os.getgid(), " ".join(additional_docker_options))
    finally:
        if deletespec:
            os.unlink(specfile)
def downloadsources(source_directory, specfile):
    _logger.info("Downloading additional sources")
    spectool = which("spectool")
    if spectool is None:
        _logger.warning(
            "spectool not found in path, will use bundled version; it might not work"
        )
        spectool = getpath("drb/builddeps/spectool")
    sp("{0} --get-files --directory {1} {2}".format(spectool, source_directory,
                                                    specfile))
Esempio n. 6
0
def srcrpm(image, srcrpm, target_directory, additional_docker_options, verify_signature, bash_on_failure,
           sign_with, always_pull, target_ownership):
    uid, gid = parse_ownership(target_ownership)

    _logger.info("Now building %(srcrpm)s on image %(image)s", locals())
    if not os.path.exists(target_directory):
        os.mkdir(target_directory)

    dockerexec = which("docker")
    dockerscripts = getpath("drb/dockerscripts")
    srpms_temp = tempfile.mkdtemp("SRPMS")
    shutil.copy(srcrpm, srpms_temp)
    internal_docker_options = set()
    srcrpm_basename = os.path.basename(srcrpm)

    rpmbuild_options = "" if verify_signature else "--nosignature"

    bashonfail = ""
    spawn_func = sp
    if bash_on_failure:
        internal_docker_options.add("-i")
        internal_docker_options.add("-t")
        bashonfail = "bashonfail"
        spawn_func = spawn_interactive

    internal_docker_options = " ".join(internal_docker_options)
    encoded_signature = provide_encoded_signature(sign_with)

    if always_pull:
        pull(dockerexec, image)

    serialized_options = serialize({"CALLING_UID": uid, "CALLING_GID": gid, "BASH_ON_FAIL":bashonfail, "RPMBUILD_OPTIONS": rpmbuild_options, "SRCRPM": srcrpm_basename,
                                    "GPG_PRIVATE_KEY": encoded_signature})

    try:
        additional_docker_options = internal_docker_options + " ".join(additional_docker_options)
        srpms_inner_dir = sp("{dockerexec} run --rm {image} rpm --eval %{{_srcrpmdir}}", **locals()).strip()
        rpms_inner_dir = sp("{dockerexec} run --rm {image} rpm --eval %{{_rpmdir}}", **locals()).strip()
        spawn_func("{dockerexec} run {additional_docker_options} -v {dockerscripts}:/dockerscripts -v {srpms_temp}:{srpms_inner_dir} -v {target_directory}:{rpms_inner_dir}"
           " -w /dockerscripts {image} ./rpmbuild-srcrpm-in-docker.sh {serialized_options}", **locals())
    finally:
        shutil.rmtree(srpms_temp)
Esempio n. 7
0
def short_test():
    # TODO: run unitests as well here
    click.echo(
        "Starting short self test. Requires networking and may take a bit of time especially at the first run, because data will be downloaded"
    )

    dockerexec = which("docker")
    testpath = getpath("drb/test")
    result = sp(
        "{dockerexec} run --rm -v {testpath}:/testpath phusion/baseimage /bin/bash -c 'cat /testpath/everythinglooksgood.txt'",
        **locals())
    if result.strip() != "everything looks good":
        click.echo(
            "Basic self test failed: docker run failed. Checklist:\n\nVerify the docker service is running\n"
            "Verify the 'docker' group exists and your user belongs to it\n"
            "If you had to add the group, verify you've restarted the 'docker' service after such addition\n"
            "Verify you've logged out+in after adding your user to the group\n"
            "Verify selinux is disabled\n"
            "Verify your disk has enough free space\n"
            "Error:\n%s\n" % result)
        sys.exit(1)

    tmpdir = mkdtemp()
    try:
        downloadsources(tmpdir, getpath("drb/test/spectooltest.spec"))
        if not os.path.exists(os.path.join(tmpdir, "README.md")):
            click.echo(
                "Basic self test failed, could not download sources; probably a spectool issue (missing perl or wrong version?)"
            )
            sys.exit(1)
    finally:
        shutil.rmtree(tmpdir)

    for fn in os.listdir(getpath("drb/dockerscripts")):
        if not os.access(os.path.join(getpath("drb/dockerscripts"), fn),
                         os.X_OK):
            click.echo(
                "File {0} is not executable, probably an install error has happened. Make sure you're using a recent python+virtualenv"
                .format(fn))
            sys.exit(1)

    click.echo("Short self test succeeded.")
Esempio n. 8
0
def short_test():
    # TODO: run unitests as well here
    click.echo("Starting short self test")

    dockerexec = which("docker")
    result = sp(
        "{dockerexec} run phusion/baseimage /bin/bash -c 'echo everything looks good'",
        **locals())
    if result.strip() != "everything looks good":
        click.echo("Basic self test failed: docker run failed:\n'%s'" % result)
        sys.exit(1)

    spectoolout = sp("{0} -h 2>&1".format(getpath("drb/builddeps/spectool")))
    if not "Usage: spectool [<options>] <specfile>" in spectoolout:
        click.echo(
            "Basic self test failed, could not run spectool (missing perl?)\n%s"
            % spectoolout)
        sys.exit(1)

    click.echo("Short self test succeeded.")
Esempio n. 9
0
def dir(image,
        source_directory,
        target_directory,
        additional_docker_options,
        download_sources=False,
        bash_on_failure=False,
        sign_with=None,
        always_pull=False):

    # TODO: let spectemplate and/or spec be optional parameters
    # TODO: let the user choose $-delimited templates
    deletespec = False
    spectemplates = [
        os.path.join(source_directory, fn)
        for fn in glob.glob1(source_directory, "*.spectemplate")
    ]
    specfiles = [
        os.path.join(source_directory, fn)
        for fn in glob.glob1(source_directory, "*.spec")
    ]
    if len(spectemplates) > 1:
        raise ValueError(
            "More than one spectemplate found in source directory")

    if not os.path.exists(target_directory):
        os.mkdir(target_directory)

    if spectemplates:
        if specfiles:
            raise ValueError(
                "Found both .spec and .spectemplate in source directory.")
        spectemplate = spectemplates[0]
        template = DoubleDelimiterTemplate(
            codecs.open(spectemplate, "rb", "utf-8").read())
        with_substitutions = template.substitute(os.environ)
        finalspec = os.path.splitext(spectemplate)[0] + ".spec"
        with codecs.open(finalspec, "wb", "utf-8") as f:
            f.write(with_substitutions)
        specfiles.append(finalspec)
        deletespec = True

    if not specfiles or len(specfiles) > 1:
        raise ValueError(
            "No specfiles or more than one specfile in source directory")

    specfile = specfiles[0]

    if download_sources:
        _logger.info("Downloading additional sources")
        sp("{0} --get-files --directory {1} {2}".format(
            getpath("drb/builddeps/spectool"), source_directory, specfile))

    _logger.info("Now building project from %s on image %s", source_directory,
                 image)
    dockerexec = which("docker")

    bashonfail = "dontspawn"
    bashonfail_options = ""
    if bash_on_failure:
        bashonfail = "bashonfail"
        bashonfail_options = "-i -t"

    sign_with_encoded = provide_encoded_signature(sign_with)

    if always_pull:
        pull(dockerexec, image)
    uid = os.getuid()
    gid = os.getgid()

    serialized_options = serialize({
        "CALLING_UID": uid,
        "CALLING_GID": gid,
        "BASH_ON_FAIL": bashonfail,
        "GPG_PRIVATE_KEY": sign_with_encoded
    })

    try:
        additional_docker_options = " ".join(additional_docker_options)
        dockerscripts = getpath("drb/dockerscripts")
        rpms_inner_dir = sp("{dockerexec} run {image} rpm --eval %{{_rpmdir}}",
                            **locals()).strip()
        sources_inner_dir = sp(
            "{dockerexec} run {image} rpm --eval %{{_sourcedir}}",
            **locals()).strip()
        sp(
            "{dockerexec} run {additional_docker_options} -v {dockerscripts}:/dockerscripts -v {source_directory}:{sources_inner_dir} -v {target_directory}:{rpms_inner_dir} {bashonfail_options} -w /dockerscripts {image}  ./rpmbuild-dir-in-docker.sh {serialized_options}",
            **locals())
    finally:
        if deletespec:
            os.unlink(specfile)
Esempio n. 10
0
def dir(image, source_directory, target_directory, additional_docker_options, download_sources,
        bash_on_failure, sign_with, always_pull, target_ownership):
    # TODO: let spectemplate and/or spec be optional parameters
    # TODO: let the user choose $-delimited templates
    uid, gid = parse_ownership(target_ownership)

    deletespec = False
    spectemplates = [os.path.join(source_directory, fn) for fn in glob.glob1(source_directory, "*.spectemplate")]
    specfiles = [os.path.join(source_directory, fn) for fn in glob.glob1(source_directory, "*.spec")]
    if len(spectemplates) > 1:
        raise ValueError("More than one spectemplate found in source directory")

    if not os.path.exists(target_directory):
        os.mkdir(target_directory)

    if spectemplates:
        if specfiles:
            raise ValueError("Found both .spec and .spectemplate in source directory.")
        spectemplate = spectemplates[0]
        template = DoubleDelimiterTemplate(codecs.open(spectemplate, "rb", "utf-8").read())
        with_substitutions = template.substitute(os.environ)
        finalspec = os.path.splitext(spectemplate)[0] + ".spec"
        with codecs.open(finalspec, "wb", "utf-8") as f:
            f.write(with_substitutions)
        specfiles.append(finalspec)
        deletespec = True

    if not specfiles or len(specfiles) > 1:
        raise ValueError("No specfiles or more than one specfile in source directory")

    specfile = specfiles[0]

    if download_sources:
        downloadsources(source_directory, specfile)

    _logger.info("Now building project from %s on image %s", source_directory, image)
    dockerexec = which("docker")

    bashonfail = "dontspawn"
    bashonfail_options = ""
    spawn_func = sp
    if bash_on_failure:
        bashonfail = "bashonfail"
        bashonfail_options = "-i -t"
        spawn_func = spawn_interactive

    sign_with_encoded = provide_encoded_signature(sign_with)

    if always_pull:
        pull(dockerexec, image)

    serialized_options = serialize({"CALLING_UID": uid, "CALLING_GID": gid, "BASH_ON_FAIL":bashonfail, "GPG_PRIVATE_KEY": sign_with_encoded})

    try:
        additional_docker_options = " ".join(additional_docker_options)
        dockerscripts = getpath("drb/dockerscripts")
        rpms_inner_dir = sp("{dockerexec} run --rm {image} rpm --eval %{{_rpmdir}}", **locals()).strip()
        sources_inner_dir = sp("{dockerexec} run --rm {image} rpm --eval %{{_sourcedir}}", **locals()).strip()
        spawn_func("{dockerexec} run {additional_docker_options} -v {dockerscripts}:/dockerscripts -v {source_directory}:{sources_inner_dir} -v {target_directory}:{rpms_inner_dir} {bashonfail_options} -w /dockerscripts {image}  ./rpmbuild-dir-in-docker.sh {serialized_options}", **locals())
    finally:
        if deletespec:
            os.unlink(specfile)