Compare commits

..

6 Commits

Author SHA1 Message Date
Matthew Johnson 82f816a731 Release v1.0.3
This release adds the "-C/--cleanup" flag to clean up the mock chroots
after a build. It also ensures that mock will build unique chroots for
each build, useful for automation environments where autospec is run in
parallel.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-10-11 15:43:31 -07:00
Matthew Johnson 6576660c5e Enable sudo in travis and fix linter error
Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-10-11 15:38:14 -07:00
Matthew Johnson 91df2fc823 Add argument to make mock clean up after itself
Add -C/--cleanup to tell mock to clean up the chroot after it completes
the build. This is useful for wrapping programs which run several
instances of autospec automatically. Use this flag to determine when we
actually need a unique uniqueext (automation environments) and when
those uniquexts can be reused (developer running one-offs).

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-10-11 15:38:14 -07:00
Matthew Johnson 8b56c225b1 Create mock chroot with a unique uniqueext
This prevents collisions when two instances are trying to build the same
package in parallel. Unit tests added as well.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-10-11 15:38:14 -07:00
Matthew Johnson e621984478 Release v1.0.2
Allow users to specify requires that are not dropped during existence
detection and os-packages list checking.

Signed-off-by: Matthew Johnson <matthew.johnson@intel.com>
2017-10-10 14:41:21 -07:00
William Douglas fa1e7951fe Allow manual override of requires
Allow developers to specify Requres that will not be dropped during
existence detection normally done for auto-detecting runtime
requirements.
2017-10-10 14:40:50 -07:00
7 changed files with 88 additions and 10 deletions
+1
View File
@@ -1,4 +1,5 @@
language: python
sudo: enabled
python:
- "3.6"
# command to run tests
+4 -1
View File
@@ -137,6 +137,9 @@ def main():
parser.add_argument("--non_interactive", action="store_true",
default=False,
help="Disable interactive mode for package verification")
parser.add_argument("-C", "--cleanup", dest="cleanup", action="store_true",
default=False,
help="Clean up mock chroot after building the package")
args = parser.parse_args()
if len(args.archives) % 2 != 0:
parser.error(argparse.ArgumentTypeError(
@@ -196,7 +199,7 @@ def main():
specfile.write_spec(build.download_path)
while 1:
build.package(filemanager)
build.package(filemanager, args.cleanup)
filemanager.load_specfile(specfile)
specfile.write_spec(build.download_path)
filemanager.newfiles_printed = 0
+52 -5
View File
@@ -25,6 +25,7 @@ import tarball
import os
import grp
import shutil
import subprocess
import config
import util
@@ -36,6 +37,7 @@ base_path = None
output_path = None
download_path = None
mock_cmd = '/usr/bin/mock'
uniqueext = ''
def setup_workingdir(workingdir):
@@ -164,6 +166,36 @@ def parse_build_results(filename, returncode, filemanager):
success = 1
def reserve_path(path):
try:
subprocess.check_output(['sudo', 'mkdir', path], stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as err:
out = err.output.decode('utf-8')
return "File exists" not in out
return True
def get_uniqueext(dirn, dist, name):
"""
Find a unique name to create mock chroot without reusing an old one
"""
# Default to tarball name
resultsdir = os.path.join(dirn, "{}-{}".format(dist, name))
if reserve_path(resultsdir):
return name
# Find a unique extension by checking if it exists in /var/lib/mock
# Increment the pathname until an unused path is found
resultsdir += "-1"
seq = 1
while not reserve_path(resultsdir):
seq += 1
resultsdir = resultsdir.replace("-{}".format(seq - 1), "-{}".format(seq))
return "{}-{}".format(name, seq)
def set_mock():
global mock_cmd
# get group list of current user
@@ -173,20 +205,35 @@ def set_mock():
mock_cmd = 'sudo /usr/bin/mock'
def package(filemanager):
def package(filemanager, cleanup=False):
global round
global uniqueext
round = round + 1
set_mock()
print("Building package " + tarball.name + " round", round)
# call(mock_cmd + " -q -r clear --scrub=cache")
# call(mock_cmd + " -q -r clear --scrub=all")
# determine uniqueext only once
if cleanup:
uniqueext = uniqueext or get_uniqueext("/var/lib/mock", "clear", tarball.name)
cleanup_flag = "--cleanup-after"
else:
uniqueext = tarball.name
cleanup_flag = "--no-cleanup-after"
print("{} mock chroot at /var/lib/mock/clear-{}".format(tarball.name, uniqueext))
shutil.rmtree('{}/results'.format(download_path), ignore_errors=True)
os.makedirs('{}/results'.format(download_path))
util.call(mock_cmd + " -r clear --buildsrpm --sources=./ --spec={0}.spec --uniqueext={0} --result=results/ --no-cleanup-after".format(tarball.name),
util.call("{} -r clear --buildsrpm --sources=./ --spec={}.spec "
"--uniqueext={} --result=results/ {}"
.format(mock_cmd, tarball.name, uniqueext, cleanup_flag),
logfile="%s/mock_srpm.log" % download_path, cwd=download_path)
util.call("rm -f results/build.log", cwd=download_path)
srcrpm = "results/%s-%s-%s.src.rpm" % (tarball.name, tarball.version, tarball.release)
returncode = util.call(mock_cmd + " -r clear --result=results/ %s --enable-plugin=ccache --uniqueext=%s --no-cleanup-after" % (srcrpm, tarball.name),
returncode = util.call("{} -r clear --result=results/ {} "
"--enable-plugin=ccache --uniqueext={} {}"
.format(mock_cmd, srcrpm, uniqueext, cleanup_flag),
logfile="%s/mock_build.log" % download_path, check=False, cwd=download_path)
# sanity check the build log
if not os.path.exists(download_path + "/results/build.log"):
+2 -2
View File
@@ -72,7 +72,7 @@ def add_buildreq(req):
return new
def add_requires(req):
def add_requires(req, override=False):
"""
Add req to the global requires set if it is present in buildreqs and
os_packages and is not banned.
@@ -84,7 +84,7 @@ def add_requires(req):
new = False
if req in banned_requires:
return False
if req not in buildreqs and req not in config.os_packages:
if req not in buildreqs and req not in config.os_packages and not override:
if req:
print("requirement '{}' not found is buildreqs or os_packages, skipping".format(req))
return False
+1 -1
View File
@@ -577,7 +577,7 @@ def parse_config_files(path, bump, filemanager):
content = read_conf_file(os.path.join(path, "requires_add"))
for extra in content:
print("Adding additional runtime requirement: %s." % extra)
buildreq.add_requires(extra)
buildreq.add_requires(extra, override=True)
content = read_conf_file(os.path.join(path, "excludes"))
for exclude in content:
+1 -1
View File
@@ -1,7 +1,7 @@
from setuptools import setup, find_packages
import sys, os
version = "1.0.1"
version = "1.0.3"
def readme():
with open("README.rst") as f:
+27
View File
@@ -1,4 +1,6 @@
import unittest
import tempfile
import os
from unittest.mock import patch, mock_open
import build
import files
@@ -376,6 +378,31 @@ class TestBuildpattern(unittest.TestCase):
self.assertEqual(build.mock_cmd, '/usr/bin/mock')
def test_get_uniqueext_first(self):
"""
Test get_uniqueext() with no collisions
"""
with tempfile.TemporaryDirectory() as tmpd:
self.assertEqual(build.get_uniqueext(tmpd, "test", "pkg"), "pkg")
def test_get_uniqueext_second(self):
"""
Test get_uniqueext() with one collision
"""
with tempfile.TemporaryDirectory() as tmpd:
os.mkdir(os.path.join(tmpd, "test-pkg"))
self.assertEqual(build.get_uniqueext(tmpd, "test", "pkg"), "pkg-1")
def test_get_uniqueext_third(self):
"""
Test get_uniqueext() with two collisions
"""
with tempfile.TemporaryDirectory() as tmpd:
os.mkdir(os.path.join(tmpd, "test-pkg"))
os.mkdir(os.path.join(tmpd, "test-pkg-1"))
self.assertEqual(build.get_uniqueext(tmpd, "test", "pkg"), "pkg-2")
if __name__ == '__main__':
unittest.main(buffer=True)