Add repos.git support to lorax-composer builds

This hooks up creation of the rpm to the build, adds it to the
kickstart, and passes the url to Anaconda. The dnf repo with the rpms is
created under the results directory so it will be included when
downloading the build's results.
This commit is contained in:
Brian C. Lane 2019-02-06 16:44:51 -08:00
parent f6f2308765
commit cd8c884adb
4 changed files with 88 additions and 7 deletions

View File

@ -139,6 +139,10 @@ Requires: python3-gevent
Requires: anaconda-tui >= 29.19-1 Requires: anaconda-tui >= 29.19-1
Requires: qemu-img Requires: qemu-img
Requires: tar Requires: tar
Requires: python3-rpmfluff
Requires: git
Requires: xz
Requires: createrepo_c
%{?systemd_requires} %{?systemd_requires}
BuildRequires: systemd BuildRequires: systemd

View File

@ -45,6 +45,7 @@ from pykickstart.parser import KickstartParser
from pykickstart.version import makeVersion from pykickstart.version import makeVersion
from pylorax import ArchData, find_templates, get_buildarch from pylorax import ArchData, find_templates, get_buildarch
from pylorax.api.gitrpm import create_gitrpm_repo
from pylorax.api.projects import projects_depsolve, projects_depsolve_with_size, dep_nevra from pylorax.api.projects import projects_depsolve, projects_depsolve_with_size, dep_nevra
from pylorax.api.projects import ProjectsError from pylorax.api.projects import ProjectsError
from pylorax.api.recipes import read_recipe_and_id from pylorax.api.recipes import read_recipe_and_id
@ -421,6 +422,9 @@ def start_build(cfg, dnflock, gitlock, branch, recipe_name, compose_type, test_m
if not repos: if not repos:
raise RuntimeError("No enabled repos, canceling build.") raise RuntimeError("No enabled repos, canceling build.")
# Create the git rpms, if any, and return the path to the repo under results_dir
gitrpm_repo = create_gitrpm_repo(results_dir, recipe)
# Create the final kickstart with repos and package list # Create the final kickstart with repos and package list
ks_path = joinpaths(results_dir, "final-kickstart.ks") ks_path = joinpaths(results_dir, "final-kickstart.ks")
with open(ks_path, "w") as f: with open(ks_path, "w") as f:
@ -432,6 +436,10 @@ def start_build(cfg, dnflock, gitlock, branch, recipe_name, compose_type, test_m
log.debug("repo composer-%s = %s", idx, ks_repo) log.debug("repo composer-%s = %s", idx, ks_repo)
f.write('repo --name="composer-%s" %s\n' % (idx, ks_repo)) f.write('repo --name="composer-%s" %s\n' % (idx, ks_repo))
if gitrpm_repo:
log.debug("repo gitrpms = %s", gitrpm_repo)
f.write('repo --name="gitrpms" --baseurl="file://%s"\n' % gitrpm_repo)
# Setup the disk for booting # Setup the disk for booting
# TODO Add GPT and UEFI boot support # TODO Add GPT and UEFI boot support
f.write('clearpart --all --initlabel\n') f.write('clearpart --all --initlabel\n')
@ -443,6 +451,12 @@ def start_build(cfg, dnflock, gitlock, branch, recipe_name, compose_type, test_m
for d in deps: for d in deps:
f.write(dep_nevra(d)+"\n") f.write(dep_nevra(d)+"\n")
# Include the rpms from the gitrpm repo directory
if gitrpm_repo:
for rpm in glob(os.path.join(gitrpm_repo, "*.rpm")):
f.write(os.path.basename(rpm)[:-4]+"\n")
f.write("%end\n") f.write("%end\n")
add_customizations(f, recipe) add_customizations(f, recipe)

View File

@ -29,6 +29,7 @@ import subprocess
import tempfile import tempfile
import time import time
from pylorax.sysutils import joinpaths
def get_repo_description(gitRepo): def get_repo_description(gitRepo):
""" Return a description including the git repo and reference """ Return a description including the git repo and reference
@ -56,26 +57,26 @@ class GitArchiveTarball:
The result is in RPMNAME.tar.xz under the sourcesDir The result is in RPMNAME.tar.xz under the sourcesDir
""" """
# Clone the repository into a temporary location # Clone the repository into a temporary location
cmd = ["git", "clone", self._gitRepo["repo"], os.path.join(sourcesDir, "gitrepo")] cmd = ["git", "clone", self._gitRepo["repo"], joinpaths(sourcesDir, "gitrepo")]
log.debug(cmd) log.debug(cmd)
subprocess.check_call(cmd) subprocess.check_call(cmd)
oldcwd = os.getcwd() oldcwd = os.getcwd()
try: try:
os.chdir(os.path.join(sourcesDir, "gitrepo")) os.chdir(joinpaths(sourcesDir, "gitrepo"))
# Configure archive to create a .tar.xz # Configure archive to create a .tar.xz
cmd = ["git", "config", "tar.tar.xz.command", "xz -c"] cmd = ["git", "config", "tar.tar.xz.command", "xz -c"]
log.debug(cmd) log.debug(cmd)
subprocess.check_call(cmd) subprocess.check_call(cmd)
cmd = ["git", "archive", "--prefix", self._gitRepo["rpmname"] + "/", "-o", os.path.join(sourcesDir, self.sourceName), self._gitRepo["ref"]] cmd = ["git", "archive", "--prefix", self._gitRepo["rpmname"] + "/", "-o", joinpaths(sourcesDir, self.sourceName), self._gitRepo["ref"]]
log.debug(cmd) log.debug(cmd)
subprocess.check_call(cmd) subprocess.check_call(cmd)
finally: finally:
# Cleanup even if there was an error # Cleanup even if there was an error
os.chdir(oldcwd) os.chdir(oldcwd)
shutil.rmtree(os.path.join(sourcesDir, "gitrepo")) shutil.rmtree(joinpaths(sourcesDir, "gitrepo"))
class GitRpmBuild(SimpleRpmBuild): class GitRpmBuild(SimpleRpmBuild):
"""Build an rpm containing files from a git repository""" """Build an rpm containing files from a git repository"""
@ -91,7 +92,7 @@ class GitRpmBuild(SimpleRpmBuild):
""" """
if not self._base_dir: if not self._base_dir:
self._base_dir = tempfile.mkdtemp(prefix="lorax-git-rpm.") self._base_dir = tempfile.mkdtemp(prefix="lorax-git-rpm.")
return os.path.join(self._base_dir, "rpmbuild") return joinpaths(self._base_dir, "rpmbuild")
def cleanup_tmpdir(self): def cleanup_tmpdir(self):
"""Remove the temporary directory and all of its contents """Remove the temporary directory and all of its contents
@ -169,3 +170,33 @@ def make_git_rpm(gitRepo, dest):
gitRpm.cleanup_tmpdir() gitRpm.cleanup_tmpdir()
return os.path.basename(rpmfile) return os.path.basename(rpmfile)
# Create the git rpms, if any, and return the path to the repo under results_dir
def create_gitrpm_repo(results_dir, recipe):
"""Create a dnf repository with the rpms from the recipe
:param results_dir: Path to create the repository under
:type results_dir: str
:param recipe: The recipe to get the repos.git entries from
:type recipe: Recipe
:returns: Path to the dnf repository or ""
:rtype: str
This function creates a dnf repository directory at results_dir+"repo/",
creates rpms for all of the repos.git entries in the recipe, runs createrepo_c
on the dnf repository so that Anaconda can use it, and returns the path to the
repository to the caller.
"""
if "repos" not in recipe or "git" not in recipe["repos"]:
return ""
gitrepo = joinpaths(results_dir, "repo/")
if not os.path.exists(gitrepo):
os.makedirs(gitrepo)
for r in recipe["repos"]["git"]:
make_git_rpm(r, gitrepo)
cmd = ["createrepo_c", gitrepo]
log.debug(cmd)
subprocess.check_call(cmd)
return gitrepo

View File

@ -24,8 +24,8 @@ import tarfile
import tempfile import tempfile
import unittest import unittest
from pylorax.api.gitrpm import GitArchiveTarball, make_git_rpm from pylorax.api.gitrpm import GitArchiveTarball, make_git_rpm, create_gitrpm_repo
from pylorax.sysutils import joinpaths
def _setup_git_repo(self): def _setup_git_repo(self):
"""Setup a git repo in a tmpdir, storing details into self """Setup a git repo in a tmpdir, storing details into self
@ -261,3 +261,35 @@ class GitRpmTest(unittest.TestCase):
self._check_rpm(git_repo["repos"]["git"][0], rpm_dir, rpm_file, "second") self._check_rpm(git_repo["repos"]["git"][0], rpm_dir, rpm_file, "second")
finally: finally:
shutil.rmtree(rpm_dir) shutil.rmtree(rpm_dir)
def gitrpm_repo_test(self):
"""Test creating a dnf repo of the git rpms"""
recipe = toml.loads("""
[[repos.git]]
rpmname="repo-test-alpha"
rpmversion="1.1.0"
rpmrelease="1"
summary="Testing the git rpm code"
repo="file://%s"
ref="v1.1.0"
destination="/srv/testing-alpha/"
[[repos.git]]
rpmname="repo-test-beta"
rpmversion="1.0.0"
rpmrelease="1"
summary="Testing the git rpm code"
repo="file://%s"
ref="v1.0.0"
destination="/srv/testing-beta/"
""" % (self.repodir, self.repodir))
try:
temp_dir = tempfile.mkdtemp(prefix="git-rpm-test.")
repo_dir = create_gitrpm_repo(temp_dir, recipe)
self.assertTrue(len(repo_dir) > 0)
self.assertTrue(os.path.exists(joinpaths(repo_dir, "repo-test-alpha-1.1.0-1.noarch.rpm")))
self.assertTrue(os.path.exists(joinpaths(repo_dir, "repo-test-beta-1.0.0-1.noarch.rpm")))
finally:
shutil.rmtree(temp_dir)