Browse Source

Don't exclude config if excluded in earlier tenant

Consider the following scenario where tenant-one includes org/project1
without any config. Zuul currently doesn't load the config of
org/project1 in tenant-two as well.

- tenant:
    name: tenant-one
    source:
      gerrit:
        untrusted-projects:
          - org/project1:
              include: []

- tenant:
    name: tenant-two
    source:
      gerrit:
        untrusted-projects:
          - org/project1

This is caused because we cache an empty config if we exclude all
config from the repo the same way as if the repo wouldn't have any
config. This causes the cat job to be skipped when loading
tenant-two. This can be solved by marking the empty config that will
be cached as 'this has no config because it has been skipped'. Then we
can detect that case and still trigger a cat job if we need the config
in a later tenant.

Change-Id: I1e7e68f11ca4fb7d1e52eee6d4c9a9d8331b012c
changes/46/636146/2
Tobias Henkel 2 years ago
parent
commit
fac26fb890
No known key found for this signature in database GPG Key ID: 3750DEC158E5FA2
5 changed files with 49 additions and 4 deletions
  1. +21
    -0
      tests/fixtures/config/tenant-parser/exclude-all.yaml
  2. +3
    -0
      tests/fixtures/config/tenant-parser/git/org_project5/.zuul.yaml
  3. +16
    -0
      tests/unit/test_configloader.py
  4. +4
    -3
      zuul/configloader.py
  5. +5
    -1
      zuul/model.py

+ 21
- 0
tests/fixtures/config/tenant-parser/exclude-all.yaml View File

@ -0,0 +1,21 @@
- tenant:
name: tenant-one
source:
gerrit:
config-projects:
- common-config
untrusted-projects:
- org/project1:
include: []
- org/project2
- tenant:
name: tenant-two
source:
gerrit:
config-projects:
- common-config
untrusted-projects:
- org/project1
- org/project2
- org/project5

+ 3
- 0
tests/fixtures/config/tenant-parser/git/org_project5/.zuul.yaml View File

@ -0,0 +1,3 @@
- job:
name: project5-job
parent: project1-job

+ 16
- 0
tests/unit/test_configloader.py View File

@ -312,6 +312,22 @@ class TestTenantUnprotectedBranches(TenantParserTestCase):
self.assertIsNone(tpc[project_name].exclude_unprotected_branches)
class TestTenantExcludeAll(TenantParserTestCase):
tenant_config_file = 'config/tenant-parser/exclude-all.yaml'
def test_tenant_exclude_all(self):
"""
Tests that excluding all configuration of project1 in tenant-one
doesn't remove the configuration of project1 in tenant-two.
"""
# The config in org/project5 depends on config in org/project1 so
# validate that there are no config errors in that tenant.
tenant_two = self.sched.abide.tenants.get('tenant-two')
self.assertEquals(
len(tenant_two.layout.loading_errors), 0,
"No error should have been accumulated")
class TestSplitConfig(ZuulTestCase):
tenant_config_file = 'config/split-config/main.yaml'


+ 4
- 3
zuul/configloader.py View File

@ -1563,8 +1563,9 @@ class TenantParser(object):
# in-repo configuration apply only to that branch.
branches = tenant.getProjectBranches(project)
for branch in branches:
if abide.getUnparsedConfig(project.canonical_name,
branch):
unparsed_config = abide.getUnparsedConfig(
project.canonical_name, branch)
if unparsed_config and not unparsed_config.load_skipped:
# We already have this branch cached.
continue
if not tpc.load_classes:
@ -1573,7 +1574,7 @@ class TenantParser(object):
# data so we know we've looked at this branch.
abide.cacheUnparsedConfig(
project.canonical_name,
branch, model.UnparsedConfig())
branch, model.UnparsedConfig(load_skipped=True))
continue
job = self.merger.getFiles(
project.source.connection.connection_name,


+ 5
- 1
zuul/model.py View File

@ -3215,7 +3215,7 @@ class UnparsedAbideConfig(object):
class UnparsedConfig(object):
"""A collection of yaml lists that has not yet been parsed into objects."""
def __init__(self):
def __init__(self, load_skipped=False):
self.pragmas = []
self.pipelines = []
self.jobs = []
@ -3225,6 +3225,10 @@ class UnparsedConfig(object):
self.secrets = []
self.semaphores = []
# This indicates wether this is empty because we skipped loading
# earlier because all config items have been excluded.
self.load_skipped = load_skipped
def copy(self, trusted=None):
# If trusted is not None, update the source context of each
# object in the copy.


Loading…
Cancel
Save