Compare commits

..

4 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
5 changed files with 85 additions and 7 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"):
+1 -1
View File
@@ -1,7 +1,7 @@
from setuptools import setup, find_packages
import sys, os
version = "1.0.2"
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)