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 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)
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)