| ... | ... |
@@ -429,22 +429,6 @@ function lib_installed_from_git {
|
| 429 | 429 |
[[ -n $(pip list --format=columns 2>/dev/null | awk "/^$safe_name/ {print \$3}") ]]
|
| 430 | 430 |
} |
| 431 | 431 |
|
| 432 |
-# check that everything that's in LIBS_FROM_GIT was actually installed |
|
| 433 |
-# correctly, this helps double check issues with library fat fingering. |
|
| 434 |
-function check_libs_from_git {
|
|
| 435 |
- local lib="" |
|
| 436 |
- local not_installed="" |
|
| 437 |
- for lib in $(echo ${LIBS_FROM_GIT} | tr "," " "); do
|
|
| 438 |
- if ! lib_installed_from_git "$lib"; then |
|
| 439 |
- not_installed+=" $lib" |
|
| 440 |
- fi |
|
| 441 |
- done |
|
| 442 |
- # if anything is not installed, say what it is. |
|
| 443 |
- if [[ -n "$not_installed" ]]; then |
|
| 444 |
- die $LINENO "The following LIBS_FROM_GIT were not installed correct: $not_installed" |
|
| 445 |
- fi |
|
| 446 |
-} |
|
| 447 |
- |
|
| 448 | 432 |
# setup a library by name. If we are trying to use the library from |
| 449 | 433 |
# git, we'll do a git based install, otherwise we'll punt and the |
| 450 | 434 |
# library should be installed by a requirements pull from another |
| ... | ... |
@@ -555,6 +539,13 @@ function _setup_package_with_constraints_edit {
|
| 555 | 555 |
|
| 556 | 556 |
setup_package $project_dir "$flags" $extras |
| 557 | 557 |
|
| 558 |
+ # If this project is in LIBS_FROM_GIT, verify it was actually installed |
|
| 559 |
+ # correctly. This helps catch errors caused by constraints mismatches. |
|
| 560 |
+ if use_library_from_git "$project_dir"; then |
|
| 561 |
+ if ! lib_installed_from_git "$project_dir"; then |
|
| 562 |
+ die $LINENO "The following LIBS_FROM_GIT was not installed correctly: $project_dir" |
|
| 563 |
+ fi |
|
| 564 |
+ fi |
|
| 558 | 565 |
} |
| 559 | 566 |
|
| 560 | 567 |
# ``pip install -e`` the package, which processes the dependencies |
| ... | ... |
@@ -20,6 +20,14 @@ Write the local.conf file for use by devstack |
| 20 | 20 |
bash shell variables, and will be ordered so that variables used by |
| 21 | 21 |
later entries appear first. |
| 22 | 22 |
|
| 23 |
+ As a special case, the variable ``LIBS_FROM_GIT`` will be |
|
| 24 |
+ constructed automatically from the projects which appear in the |
|
| 25 |
+ ``required-projects`` list defined by the job. To instruct |
|
| 26 |
+ devstack to install a library from source rather than pypi, simply |
|
| 27 |
+ add that library to the job's ``required-projects`` list. To |
|
| 28 |
+ override the automatically-generated value, set ``LIBS_FROM_GIT`` |
|
| 29 |
+ in ``devstack_localrc`` to the desired value. |
|
| 30 |
+ |
|
| 23 | 31 |
.. zuul:rolevar:: devstack_local_conf |
| 24 | 32 |
:type: dict |
| 25 | 33 |
|
| ... | ... |
@@ -75,3 +83,7 @@ Write the local.conf file for use by devstack |
| 75 | 75 |
A dictionary mapping a plugin name to a git repo location. If the |
| 76 | 76 |
location is a non-empty string, then an ``enable_plugin`` line will |
| 77 | 77 |
be emmitted for the plugin name. |
| 78 |
+ |
|
| 79 |
+ If a plugin declares a dependency on another plugin (via |
|
| 80 |
+ ``plugin_requires`` in the plugin's settings file), this role will |
|
| 81 |
+ automatically emit ``enable_plugin`` lines in the correct order. |
| ... | ... |
@@ -207,17 +207,17 @@ class PluginGraph(DependencyGraph): |
| 207 | 207 |
class LocalConf(object): |
| 208 | 208 |
|
| 209 | 209 |
def __init__(self, localrc, localconf, base_services, services, plugins, |
| 210 |
- base_dir): |
|
| 210 |
+ base_dir, projects): |
|
| 211 | 211 |
self.localrc = [] |
| 212 | 212 |
self.meta_sections = {}
|
| 213 | 213 |
self.plugin_deps = {}
|
| 214 | 214 |
self.base_dir = base_dir |
| 215 |
+ self.projects = projects |
|
| 215 | 216 |
if plugins: |
| 216 | 217 |
self.handle_plugins(plugins) |
| 217 | 218 |
if services or base_services: |
| 218 | 219 |
self.handle_services(base_services, services or {})
|
| 219 |
- if localrc: |
|
| 220 |
- self.handle_localrc(localrc) |
|
| 220 |
+ self.handle_localrc(localrc) |
|
| 221 | 221 |
if localconf: |
| 222 | 222 |
self.handle_localconf(localconf) |
| 223 | 223 |
|
| ... | ... |
@@ -241,9 +241,22 @@ class LocalConf(object): |
| 241 | 241 |
self.localrc.append('enable_service {}'.format(k))
|
| 242 | 242 |
|
| 243 | 243 |
def handle_localrc(self, localrc): |
| 244 |
- vg = VarGraph(localrc) |
|
| 245 |
- for k, v in vg.getVars(): |
|
| 246 |
- self.localrc.append('{}={}'.format(k, v))
|
|
| 244 |
+ lfg = False |
|
| 245 |
+ if localrc: |
|
| 246 |
+ vg = VarGraph(localrc) |
|
| 247 |
+ for k, v in vg.getVars(): |
|
| 248 |
+ self.localrc.append('{}={}'.format(k, v))
|
|
| 249 |
+ if k == 'LIBS_FROM_GIT': |
|
| 250 |
+ lfg = True |
|
| 251 |
+ |
|
| 252 |
+ if not lfg and self.projects: |
|
| 253 |
+ required_projects = [] |
|
| 254 |
+ for project_name, project_info in self.projects.items(): |
|
| 255 |
+ if project_info.get('required'):
|
|
| 256 |
+ required_projects.append(project_info['short_name']) |
|
| 257 |
+ if required_projects: |
|
| 258 |
+ self.localrc.append('LIBS_FROM_GIT={}'.format(
|
|
| 259 |
+ ','.join(required_projects))) |
|
| 247 | 260 |
|
| 248 | 261 |
def handle_localconf(self, localconf): |
| 249 | 262 |
for phase, phase_data in localconf.items(): |
| ... | ... |
@@ -277,6 +290,7 @@ def main(): |
| 277 | 277 |
local_conf=dict(type='dict'), |
| 278 | 278 |
base_dir=dict(type='path'), |
| 279 | 279 |
path=dict(type='str'), |
| 280 |
+ projects=dict(type='dict'), |
|
| 280 | 281 |
) |
| 281 | 282 |
) |
| 282 | 283 |
|
| ... | ... |
@@ -286,7 +300,8 @@ def main(): |
| 286 | 286 |
p.get('base_services'),
|
| 287 | 287 |
p.get('services'),
|
| 288 | 288 |
p.get('plugins'),
|
| 289 |
- p.get('base_dir'))
|
|
| 289 |
+ p.get('base_dir'),
|
|
| 290 |
+ p.get('projects'))
|
|
| 290 | 291 |
lc.write(p['path']) |
| 291 | 292 |
|
| 292 | 293 |
module.exit_json() |
| ... | ... |
@@ -56,7 +56,8 @@ class TestDevstackLocalConf(unittest.TestCase): |
| 56 | 56 |
p.get('base_services'),
|
| 57 | 57 |
p.get('services'),
|
| 58 | 58 |
p.get('plugins'),
|
| 59 |
- p.get('base_dir'))
|
|
| 59 |
+ p.get('base_dir'),
|
|
| 60 |
+ p.get('projects'))
|
|
| 60 | 61 |
lc.write(p['path']) |
| 61 | 62 |
|
| 62 | 63 |
plugins = [] |
| ... | ... |
@@ -66,6 +67,7 @@ class TestDevstackLocalConf(unittest.TestCase): |
| 66 | 66 |
plugins.append(line.split()[1]) |
| 67 | 67 |
self.assertEqual(['bar', 'baz', 'foo'], plugins) |
| 68 | 68 |
|
| 69 |
+ |
|
| 69 | 70 |
def test_plugin_deps(self): |
| 70 | 71 |
"Test that plugins with dependencies work" |
| 71 | 72 |
os.makedirs(os.path.join(self.tmpdir, 'foo-plugin', 'devstack')) |
| ... | ... |
@@ -101,20 +103,80 @@ class TestDevstackLocalConf(unittest.TestCase): |
| 101 | 101 |
plugins=plugins, |
| 102 | 102 |
base_dir=self.tmpdir, |
| 103 | 103 |
path=os.path.join(self.tmpdir, 'test.local.conf')) |
| 104 |
+ |
|
| 105 |
+ def test_libs_from_git(self): |
|
| 106 |
+ "Test that LIBS_FROM_GIT is auto-generated" |
|
| 107 |
+ projects = {
|
|
| 108 |
+ 'git.openstack.org/openstack/nova': {
|
|
| 109 |
+ 'required': True, |
|
| 110 |
+ 'short_name': 'nova', |
|
| 111 |
+ }, |
|
| 112 |
+ 'git.openstack.org/openstack/oslo.messaging': {
|
|
| 113 |
+ 'required': True, |
|
| 114 |
+ 'short_name': 'oslo.messaging', |
|
| 115 |
+ }, |
|
| 116 |
+ 'git.openstack.org/openstack/devstack-plugin': {
|
|
| 117 |
+ 'required': False, |
|
| 118 |
+ 'short_name': 'devstack-plugin', |
|
| 119 |
+ }, |
|
| 120 |
+ } |
|
| 121 |
+ p = dict(base_services=[], |
|
| 122 |
+ base_dir='./test', |
|
| 123 |
+ path=os.path.join(self.tmpdir, 'test.local.conf'), |
|
| 124 |
+ projects=projects) |
|
| 104 | 125 |
lc = LocalConf(p.get('localrc'),
|
| 105 | 126 |
p.get('local_conf'),
|
| 106 | 127 |
p.get('base_services'),
|
| 107 | 128 |
p.get('services'),
|
| 108 | 129 |
p.get('plugins'),
|
| 109 |
- p.get('base_dir'))
|
|
| 130 |
+ p.get('base_dir'),
|
|
| 131 |
+ p.get('projects'))
|
|
| 110 | 132 |
lc.write(p['path']) |
| 111 | 133 |
|
| 112 |
- plugins = [] |
|
| 134 |
+ lfg = None |
|
| 113 | 135 |
with open(p['path']) as f: |
| 114 | 136 |
for line in f: |
| 115 |
- if line.startswith('enable_plugin'):
|
|
| 116 |
- plugins.append(line.split()[1]) |
|
| 117 |
- self.assertEqual(['foo', 'bar'], plugins) |
|
| 137 |
+ if line.startswith('LIBS_FROM_GIT'):
|
|
| 138 |
+ lfg = line.strip().split('=')[1]
|
|
| 139 |
+ self.assertEqual('nova,oslo.messaging', lfg)
|
|
| 140 |
+ |
|
| 141 |
+ def test_overridelibs_from_git(self): |
|
| 142 |
+ "Test that LIBS_FROM_GIT can be overridden" |
|
| 143 |
+ localrc = {'LIBS_FROM_GIT': 'oslo.db'}
|
|
| 144 |
+ projects = {
|
|
| 145 |
+ 'git.openstack.org/openstack/nova': {
|
|
| 146 |
+ 'required': True, |
|
| 147 |
+ 'short_name': 'nova', |
|
| 148 |
+ }, |
|
| 149 |
+ 'git.openstack.org/openstack/oslo.messaging': {
|
|
| 150 |
+ 'required': True, |
|
| 151 |
+ 'short_name': 'oslo.messaging', |
|
| 152 |
+ }, |
|
| 153 |
+ 'git.openstack.org/openstack/devstack-plugin': {
|
|
| 154 |
+ 'required': False, |
|
| 155 |
+ 'short_name': 'devstack-plugin', |
|
| 156 |
+ }, |
|
| 157 |
+ } |
|
| 158 |
+ p = dict(localrc=localrc, |
|
| 159 |
+ base_services=[], |
|
| 160 |
+ base_dir='./test', |
|
| 161 |
+ path=os.path.join(self.tmpdir, 'test.local.conf'), |
|
| 162 |
+ projects=projects) |
|
| 163 |
+ lc = LocalConf(p.get('localrc'),
|
|
| 164 |
+ p.get('local_conf'),
|
|
| 165 |
+ p.get('base_services'),
|
|
| 166 |
+ p.get('services'),
|
|
| 167 |
+ p.get('plugins'),
|
|
| 168 |
+ p.get('base_dir'),
|
|
| 169 |
+ p.get('projects'))
|
|
| 170 |
+ lc.write(p['path']) |
|
| 171 |
+ |
|
| 172 |
+ lfg = None |
|
| 173 |
+ with open(p['path']) as f: |
|
| 174 |
+ for line in f: |
|
| 175 |
+ if line.startswith('LIBS_FROM_GIT'):
|
|
| 176 |
+ lfg = line.strip().split('=')[1]
|
|
| 177 |
+ self.assertEqual('oslo.db', lfg)
|
|
| 118 | 178 |
|
| 119 | 179 |
def test_plugin_circular_deps(self): |
| 120 | 180 |
"Test that plugins with circular dependencies fail" |
| ... | ... |
@@ -1398,11 +1398,6 @@ fi |
| 1398 | 1398 |
# Check the status of running services |
| 1399 | 1399 |
service_check |
| 1400 | 1400 |
|
| 1401 |
-# ensure that all the libraries we think we installed from git, |
|
| 1402 |
-# actually were. |
|
| 1403 |
-check_libs_from_git |
|
| 1404 |
- |
|
| 1405 |
- |
|
| 1406 | 1401 |
# Configure nova cellsv2 |
| 1407 | 1402 |
# ---------------------- |
| 1408 | 1403 |
|