예제 #1
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)
예제 #2
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)
 def test_templatetransformation_from_string(self):
     ddt = DoubleDelimiterTemplate("asd@{pippo}@xyz@pluto@what")
     result = ddt.safe_substitute({"pippo": "v1", "pluto": "v2"})
     self.assertEquals("asdv1xyzv2what", result)
예제 #4
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)
 def test_templatetransformation_from_unicode(self):
     ddt = DoubleDelimiterTemplate(u"ààasd@{pippo}@xyz@pluto@what")
     result = ddt.safe_substitute({u"pippo": u"v1", u"pluto": u"v2ù"})
     self.assertEquals(u"ààasdv1xyzv2ùwhat", result)
 def test_template_ignores_single_at(self):
     ddt = DoubleDelimiterTemplate("* Wed Sep 26 2012 Ryan O'Hara <*****@*****.**> - 1.2.7-3")
     result = ddt.substitute({})
     self.assertEquals("* Wed Sep 26 2012 Ryan O'Hara <*****@*****.**> - 1.2.7-3", result)
예제 #7
0
 def test_templatetransformation_from_string(self):
     ddt = DoubleDelimiterTemplate("asd@{pippo}@xyz@pluto@what")
     result = ddt.safe_substitute({"pippo": "v1", "pluto": "v2"})
     self.assertEquals("asdv1xyzv2what", result)
예제 #8
0
 def test_templatetransformation_from_unicode(self):
     ddt = DoubleDelimiterTemplate(u"ààasd@{pippo}@xyz@pluto@what")
     result = ddt.safe_substitute({u"pippo": u"v1", u"pluto": u"v2ù"})
     self.assertEquals(u"ààasdv1xyzv2ùwhat", result)
예제 #9
0
 def test_template_ignores_single_at(self):
     ddt = DoubleDelimiterTemplate("* Wed Sep 26 2012 Ryan O'Hara <*****@*****.**> - 1.2.7-3")
     result = ddt.substitute({})
     self.assertEquals("* Wed Sep 26 2012 Ryan O'Hara <*****@*****.**> - 1.2.7-3", result)