mirror of
https://github.com/rpm-software-management/tito.git
synced 2025-02-24 04:32:46 +00:00
Prototype mock builder and yum releaser.
Still with configuration hard coded, but demonstrates building via mock, and then assembling built packages into a yum repository.
This commit is contained in:
parent
fd4af9ef85
commit
7b449a2d7b
3 changed files with 150 additions and 24 deletions
|
@ -69,14 +69,14 @@ class Builder(object):
|
|||
for options in pkg_config.options(section):
|
||||
if not self.config.has_section(section):
|
||||
self.config.add_section(section)
|
||||
self.config.set(section, options,
|
||||
self.config.set(section, options,
|
||||
pkg_config.get(section, options))
|
||||
|
||||
if self.config.has_section("requirements"):
|
||||
if self.config.has_option("requirements", "tito"):
|
||||
if loose_version(self.config.get("requirements", "tito")) > \
|
||||
loose_version(require('tito')[0].version):
|
||||
print("Error: tito version %s or later is needed to build this project." %
|
||||
print("Error: tito version %s or later is needed to build this project." %
|
||||
self.config.get("requirements", "tito"))
|
||||
print("Your version: %s" % require('tito')[0].version)
|
||||
sys.exit(-1)
|
||||
|
@ -112,7 +112,7 @@ class Builder(object):
|
|||
# Set to true if we've already created a tgz:
|
||||
self.ran_tgz = False
|
||||
|
||||
# Used to make sure we only modify the spec file for a test build
|
||||
# Used to make sure we only modify the spec file for a test build
|
||||
# once. The srpm method may be called multiple times during koji
|
||||
# releases to create the proper disttags, but we only want to modify
|
||||
# the spec file once.
|
||||
|
@ -198,7 +198,7 @@ class Builder(object):
|
|||
|
||||
cmd = ('LC_ALL=C rpmbuild --define "_source_filedigest_algorithm md5" --define'
|
||||
' "_binary_filedigest_algorithm md5" %s %s %s --nodeps -bs %s' % (
|
||||
self.rpmbuild_options, self._get_rpmbuild_dir_options(),
|
||||
self.rpmbuild_options, self._get_rpmbuild_dir_options(),
|
||||
define_dist, self.spec_file))
|
||||
output = run_command(cmd)
|
||||
print(output)
|
||||
|
@ -219,7 +219,7 @@ class Builder(object):
|
|||
define_dist = "--define 'dist %s'" % self.dist
|
||||
cmd = ('LC_ALL=C rpmbuild --define "_source_filedigest_algorithm md5" '
|
||||
'--define "_binary_filedigest_algorithm md5" %s %s %s --clean '
|
||||
'-ba %s' % (self.rpmbuild_options,
|
||||
'-ba %s' % (self.rpmbuild_options,
|
||||
self._get_rpmbuild_dir_options(), define_dist, self.spec_file))
|
||||
try:
|
||||
output = run_command(cmd)
|
||||
|
@ -690,7 +690,7 @@ class UpstreamBuilder(NoTgzBuilder):
|
|||
def patch_upstream(self):
|
||||
"""
|
||||
Generate patches for any differences between our tag and the
|
||||
upstream tag, and apply them into an exported copy of the
|
||||
upstream tag, and apply them into an exported copy of the
|
||||
spec file.
|
||||
"""
|
||||
patch_filename = "%s-to-%s-%s.patch" % (self.upstream_tag,
|
||||
|
@ -699,14 +699,14 @@ class UpstreamBuilder(NoTgzBuilder):
|
|||
patch_filename)
|
||||
patch_dir = self.git_root
|
||||
if self.relative_project_dir != "/":
|
||||
patch_dir = os.path.join(self.git_root,
|
||||
patch_dir = os.path.join(self.git_root,
|
||||
self.relative_project_dir)
|
||||
os.chdir(patch_dir)
|
||||
debug("patch dir = %s" % patch_dir)
|
||||
print("Generating patch [%s]" % patch_filename)
|
||||
debug("Patch: %s" % patch_file)
|
||||
patch_command = "git diff --relative %s..%s > %s" % \
|
||||
(self.upstream_tag, self.git_commit_id,
|
||||
(self.upstream_tag, self.git_commit_id,
|
||||
patch_file)
|
||||
debug("Generating patch with: %s" % patch_command)
|
||||
output = run_command(patch_command)
|
||||
|
@ -772,3 +772,70 @@ class UpstreamBuilder(NoTgzBuilder):
|
|||
class SatelliteBuilder(UpstreamBuilder):
|
||||
pass
|
||||
|
||||
|
||||
class MockBuilder(Builder):
|
||||
"""
|
||||
Uses the mock tool to create a chroot for building packages for a different
|
||||
OS version than you may be currently using.
|
||||
"""
|
||||
|
||||
def __init__(self, name=None, version=None, tag=None, build_dir=None,
|
||||
pkg_config=None, global_config=None, user_config=None, options=None):
|
||||
|
||||
Builder.__init__(self, name=name, version=version, tag=tag,
|
||||
build_dir=build_dir, pkg_config=pkg_config,
|
||||
global_config=global_config, user_config=user_config,
|
||||
options=options)
|
||||
|
||||
self.mock_tag = "fedora-15-x86_64"
|
||||
#self.mock_tag = "epel-6-x86_64"
|
||||
#self.mock_tag = "fedora-14-x86_64"
|
||||
#self.mock_tag = "epel-5-x86_64"
|
||||
|
||||
# TODO: error out if mock package is not installed
|
||||
|
||||
def _rpm(self):
|
||||
"""
|
||||
Uses the SRPM
|
||||
Override the base builder rpm method.
|
||||
"""
|
||||
|
||||
print("Creating rpms for %s-%s in mock: %s" % (
|
||||
self.project_name, self.display_version, self.mock_tag))
|
||||
if not self.srpm_location:
|
||||
self.srpm()
|
||||
print("Using srpm: %s" % self.srpm_location)
|
||||
self._build_in_mock()
|
||||
|
||||
def _build_in_mock(self):
|
||||
print("Initializing mock:\n")
|
||||
output = run_command("mock -r %s --init" % self.mock_tag)
|
||||
print output
|
||||
print("\nInstalling deps:\n")
|
||||
output = run_command("mock -r %s --installdeps %s" % (
|
||||
self.mock_tag, self.srpm_location))
|
||||
print output
|
||||
#print("\nCopying:\n")
|
||||
#output = run_command("mock -r %s --copyin %s /tmp" % (
|
||||
# self.mock_tag, self.srpm_location))
|
||||
#print output
|
||||
print("\nRebuilding:\n")
|
||||
output = run_command('mock -r %s --rebuild %s' %
|
||||
(self.mock_tag, self.srpm_location))
|
||||
print output
|
||||
print("\nCopying resulting rpms:\n")
|
||||
mock_output_dir = os.path.join(self.rpmbuild_dir, "mockoutput")
|
||||
output = run_command("mock -r %s --copyout /builddir/build/RPMS/ %s" %
|
||||
(self.mock_tag, mock_output_dir))
|
||||
print output
|
||||
|
||||
# Copy everything mock wrote out to /tmp/tito:
|
||||
files = os.listdir(mock_output_dir)
|
||||
run_command("cp %s/*.rpm %s" %
|
||||
(mock_output_dir, self.rpmbuild_basedir))
|
||||
print
|
||||
print("Wrote:")
|
||||
for rpm in files:
|
||||
rpm_path = os.path.join(self.rpmbuild_basedir, rpm)
|
||||
print(" %s" % rpm_path)
|
||||
self.artifacts.append(rpm_path)
|
||||
|
|
|
@ -127,7 +127,7 @@ class BaseCliModule(object):
|
|||
default=False)
|
||||
|
||||
default_output_dir = lookup_build_dir(self.user_config)
|
||||
self.parser.add_option("-o", "--output", dest="output_dir",
|
||||
self.parser.add_option("-o", "--output", dest="output_dir",
|
||||
metavar="OUTPUTDIR", default=default_output_dir,
|
||||
help="Path to write temp files, tarballs and rpms to. "
|
||||
"(default %s)"
|
||||
|
@ -154,7 +154,7 @@ class BaseCliModule(object):
|
|||
# Check if global config defines a custom lib dir:
|
||||
if self.global_config.has_option(GLOBALCONFIG_SECTION,
|
||||
"lib_dir"):
|
||||
lib_dir = self.global_config.get(GLOBALCONFIG_SECTION,
|
||||
lib_dir = self.global_config.get(GLOBALCONFIG_SECTION,
|
||||
"lib_dir")
|
||||
if lib_dir[0] != '/':
|
||||
# Looks like a relative path, assume from the git root:
|
||||
|
@ -228,7 +228,7 @@ class BaseCliModule(object):
|
|||
else:
|
||||
# HACK: Check for legacy build.py.props naming, needed to support
|
||||
# older tags:
|
||||
current_props_file = os.path.join(os.getcwd(),
|
||||
current_props_file = os.path.join(os.getcwd(),
|
||||
"build.py.props")
|
||||
if (os.path.exists(current_props_file)):
|
||||
properties_file = current_props_file
|
||||
|
@ -309,7 +309,7 @@ class BuildModule(BaseCliModule):
|
|||
help="Build srpm")
|
||||
self.parser.add_option("--rpm", dest="rpm", action="store_true",
|
||||
help="Build rpm")
|
||||
self.parser.add_option("-i", "--install", dest="auto_install",
|
||||
self.parser.add_option("-i", "--install", dest="auto_install",
|
||||
action="store_true", default=False,
|
||||
help="Install any binary rpms being built. (WARNING: " + \
|
||||
"uses sudo rpm -Uvh --force)")
|
||||
|
@ -326,7 +326,7 @@ class BuildModule(BaseCliModule):
|
|||
"(i.e. spacewalk-java-0.4.0-1)")
|
||||
|
||||
self.parser.add_option("--release", dest="release",
|
||||
action="store_true", help="DEPRECATED: please use 'tito release' instead.")
|
||||
action="store_true", help="DEPRECATED: please use 'tito release' instead.")
|
||||
|
||||
self.parser.add_option("--list-tags", dest="list_tags",
|
||||
action="store_true",
|
||||
|
@ -430,6 +430,7 @@ class ReleaseModule(BaseCliModule):
|
|||
'cvs': 'tito.release.CvsReleaser',
|
||||
'koji': 'tito.release.KojiReleaser',
|
||||
'fedora-git': 'tito.release.FedoraGitReleaser',
|
||||
'yum-mock': 'tito.release.YumRepoMockReleaser'
|
||||
}
|
||||
|
||||
# Load all custom releasers configured:
|
||||
|
@ -510,7 +511,7 @@ class TagModule(BaseCliModule):
|
|||
help=("Automatically accept the generated changelog."))
|
||||
|
||||
self.parser.add_option("--auto-changelog-message",
|
||||
dest="auto_changelog_msg", metavar="MESSAGE",
|
||||
dest="auto_changelog_msg", metavar="MESSAGE",
|
||||
help=("Use MESSAGE as the default changelog message for "
|
||||
"new packages"))
|
||||
|
||||
|
@ -667,7 +668,7 @@ class ReportModule(BaseCliModule):
|
|||
continue
|
||||
f = open(os.path.join(package_metadata_dir, md_file))
|
||||
(version, relative_dir) = f.readline().strip().split(" ")
|
||||
|
||||
|
||||
# Hack for single project git repos:
|
||||
if relative_dir == '/':
|
||||
relative_dir = ""
|
||||
|
|
|
@ -22,6 +22,9 @@ import pyfedpkg
|
|||
import tempfile
|
||||
import subprocess
|
||||
|
||||
from tempfile import mkdtemp
|
||||
from shutil import rmtree, copy
|
||||
|
||||
from tito.common import *
|
||||
|
||||
DEFAULT_KOJI_OPTS = "build --nowait"
|
||||
|
@ -36,7 +39,7 @@ class Releaser(object):
|
|||
def __init__(self, name=None, version=None, tag=None, build_dir=None,
|
||||
pkg_config=None, global_config=None, user_config=None):
|
||||
|
||||
# While we create a builder here, we don't actually call run on it
|
||||
# While we create a builder here, we don't actually call run on it
|
||||
# unless the releaser needs to:
|
||||
self.builder = create_builder(name, tag,
|
||||
version, None, pkg_config,
|
||||
|
@ -158,11 +161,71 @@ class Releaser(object):
|
|||
return new_files, copied_files, old_files
|
||||
|
||||
|
||||
class YumRepoMockReleaser(Releaser):
|
||||
"""
|
||||
A releaser which will rsync down a yum repo, build the desired packages,
|
||||
plug them in, update the repodata, and push the yum repo back out.
|
||||
|
||||
Building of the packages is done via mock.
|
||||
|
||||
WARNING: This will not work in all
|
||||
situations, depending on the current OS, and the mock target you
|
||||
are attempting to use.
|
||||
"""
|
||||
|
||||
def __init__(self, name=None, version=None, tag=None, build_dir=None,
|
||||
pkg_config=None, global_config=None, user_config=None):
|
||||
Releaser.__init__(self, name, version, tag, build_dir, pkg_config,
|
||||
global_config, user_config)
|
||||
|
||||
self.build_dir = build_dir
|
||||
|
||||
# Override to use the mock builder:
|
||||
from tito.builder import MockBuilder
|
||||
self.builder = MockBuilder(name=name, tag=tag, version=version,
|
||||
options=None,
|
||||
pkg_config=pkg_config,
|
||||
build_dir=build_dir,
|
||||
global_config=global_config,
|
||||
user_config=user_config)
|
||||
|
||||
def release(self, dry_run=False):
|
||||
# Should this run?
|
||||
self.builder.tgz()
|
||||
self.builder.srpm()
|
||||
self.builder._rpm()
|
||||
self.builder.cleanup()
|
||||
|
||||
print "RPMS:"
|
||||
print self.builder.artifacts
|
||||
|
||||
# TODO: username
|
||||
rsync_location = "fedorapeople.org:/srv/repos/candlepin/subscription-manager/fedora-15/x86_64/"
|
||||
# Make a temp directory to sync the existing repo contents into:
|
||||
yum_temp_dir = mkdtemp(dir=self.build_dir, prefix="tito-yumrepo-")
|
||||
debug("Copying existing yum repo to:: %s" % yum_temp_dir)
|
||||
run_command("rsync -avtz %s %s" % (rsync_location, yum_temp_dir))
|
||||
|
||||
for artifact in self.builder.artifacts:
|
||||
if artifact.endswith(".rpm") and not artifact.endswith(".src.rpm"):
|
||||
copy(artifact, yum_temp_dir)
|
||||
print("Copied %s to yum repo." % artifact)
|
||||
|
||||
os.chdir(yum_temp_dir)
|
||||
output = run_command("createrepo ./")
|
||||
print output
|
||||
|
||||
|
||||
# TODO: Cleanup
|
||||
#rmtree(yum_temp_dir)
|
||||
|
||||
|
||||
|
||||
class FedoraGitReleaser(Releaser):
|
||||
|
||||
def __init__(self, name=None, version=None, tag=None, build_dir=None,
|
||||
pkg_config=None, global_config=None, user_config=None):
|
||||
Releaser.__init__(self, name, version, tag, build_dir, pkg_config,
|
||||
Releaser.__init__(self, name, version, tag, build_dir, pkg_config,
|
||||
global_config, user_config)
|
||||
|
||||
self.git_branches = []
|
||||
|
@ -209,8 +272,6 @@ class FedoraGitReleaser(Releaser):
|
|||
|
||||
main_branch = self.git_branches[0]
|
||||
|
||||
|
||||
|
||||
os.chdir(project_checkout)
|
||||
(status, diff_output) = commands.getstatusoutput("git diff --cached")
|
||||
|
||||
|
@ -278,9 +339,6 @@ class FedoraGitReleaser(Releaser):
|
|||
sys.stderr.write(" Output: %s" % output)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
|
||||
|
||||
def _can_build_in_git(self):
|
||||
"""
|
||||
Return True if this repo and branch is configured to build in
|
||||
|
@ -356,7 +414,7 @@ class CvsReleaser(Releaser):
|
|||
|
||||
def __init__(self, name=None, version=None, tag=None, build_dir=None,
|
||||
pkg_config=None, global_config=None, user_config=None):
|
||||
Releaser.__init__(self, name, version, tag, build_dir, pkg_config,
|
||||
Releaser.__init__(self, name, version, tag, build_dir, pkg_config,
|
||||
global_config, user_config)
|
||||
|
||||
# Configure CVS variables if possible. Will check later that
|
||||
|
@ -616,7 +674,7 @@ class KojiReleaser(Releaser):
|
|||
|
||||
def __init__(self, name=None, version=None, tag=None, build_dir=None,
|
||||
pkg_config=None, global_config=None, user_config=None):
|
||||
Releaser.__init__(self, name, version, tag, build_dir, pkg_config,
|
||||
Releaser.__init__(self, name, version, tag, build_dir, pkg_config,
|
||||
global_config, user_config)
|
||||
|
||||
self.only_tags = self.builder.only_tags
|
||||
|
|
Loading…
Add table
Reference in a new issue