Introduce upper constraints

This is a global setting that will apply across every project, a
constraint on the versions of things that can be installed via pip.

This is a first pass, adding basic functionality, by allowing a list
of constraint URLs to be provided. Future iterations of this feature may be
tied to a "superrepo" that contains all the projects _and_ the
constraints for those projects all in one place.

Change-Id: Ib5c2dd441b9294b775e755e595486a671d8de57f
This commit is contained in:
Jesse Keating 2016-06-09 13:08:31 -07:00
parent 6b40cee8bf
commit cd07f9bcd3
4 changed files with 49 additions and 5 deletions

View File

@ -18,6 +18,8 @@ import logging
import os
import threading
import requests
from giftwrap.gerrit import GerritReview
from stevedore.driver import DriverManager
from stevedore.extension import ExtensionManager
@ -36,6 +38,7 @@ class Builder(object):
self._temp_src_dir = None
self._spec = spec
self._thread_exit = []
self.constraints = []
@staticmethod
def builder_names(ext_mgr=None):
@ -55,6 +58,31 @@ class Builder(object):
"Error was: %s", e)
return []
def _get_constraints(self):
cfiles = []
cfilenum = 0
try:
for constraint_url in self._spec.settings.constraints:
response = requests.get(constraint_url)
# Raise an error if we got a bad URL
response.raise_for_status()
constraints = response.text.encode('utf-8')
cfilepath = os.path.join(self._temp_dir,
'constraints-%s.txt' % cfilenum)
with open(cfilepath, 'w') as cfile:
cfile.write(constraints)
cfiles.append(cfilepath)
cfilenum += 1
return cfiles
except Exception as e:
raise Exception("Unable to construct constraints. Error: %s" % e)
def _build_project(self, project):
try:
self._prepare_project_build(project)
@ -105,6 +133,9 @@ class Builder(object):
self._temp_src_dir = os.path.join(self._temp_dir, 'src')
LOG.debug("Temporary working directory: %s", self._temp_dir)
# get constraints paths
self.constraints = self._get_constraints()
threads = []
for project in spec.projects:
if spec.settings.parallel_build:

View File

@ -84,8 +84,11 @@ class DockerBuilder(Builder):
def _install_pip_dependencies(self, venv_path, dependencies):
pip_path = self._get_venv_pip_path(venv_path)
install = "install"
for constraint in self.constraints:
install = "%s -c %s" % (install, constraint)
for dependency in dependencies:
self._execute("%s install %s" % (pip_path, dependency))
self._execute("%s %s %s" % (pip_path, install, dependency))
def _copy_sample_config(self, src_clone_dir, project):
src_config = os.path.join(src_clone_dir, 'etc')
@ -96,7 +99,10 @@ class DockerBuilder(Builder):
def _install_project(self, venv_path, src_clone_dir):
pip_path = self._get_venv_pip_path(venv_path)
self._execute("%s install %s" % (pip_path, src_clone_dir))
install = "install"
for constraint in self.constraints:
install = "%s -c %s" % (install, constraint)
self._execute("%s %s %s" % (pip_path, install, src_clone_dir))
def _finalize_project_build(self, project):
self._commands.append("rm -rf %s" % self._temp_dir)

View File

@ -70,8 +70,11 @@ class PackageBuilder(Builder):
def _install_pip_dependencies(self, venv_path, dependencies):
pip_path = self._get_venv_pip_path(venv_path)
install = "install"
for constraint in self.constraints:
install = "%s -c %s" % (install, constraint)
for dependency in dependencies:
self._execute("%s install %s" % (pip_path, dependency))
self._execute("%s %s %s" % (pip_path, install, dependency))
def _copy_sample_config(self, src_clone_dir, project):
src_config = os.path.join(src_clone_dir, 'etc')
@ -87,7 +90,10 @@ class PackageBuilder(Builder):
def _install_project(self, venv_path, src_clone_dir):
pip_path = self._get_venv_pip_path(venv_path)
self._execute("%s install %s" % (pip_path, src_clone_dir))
install = "install"
for constraint in self.constraints:
install = "%s -c %s" % (install, constraint)
self._execute("%s %s %s" % (pip_path, install, src_clone_dir))
def _finalize_project_build(self, project):
# build the package

View File

@ -31,7 +31,7 @@ class Settings(object):
package_name_format=None, version=None,
base_path=None, install_path=None, gerrit_dependencies=True,
force_overwrite=False, output_dir=None, include_config=True,
parallel_build=True):
parallel_build=True, constraints=[]):
if not version:
raise Exception("'version' is a required settings")
self.build_type = build_type
@ -44,6 +44,7 @@ class Settings(object):
self._output_dir = output_dir
self.include_config = include_config
self.parallel_build = parallel_build
self.constraints = constraints
@property
def package_name_format(self):