diff options
-rw-r--r-- | releasenotes/notes/520-windows-7737f20c23b0afee.yaml | 7 | ||||
-rw-r--r-- | releasenotes/notes/project-regex-update-dcc183d923a6acdd.yaml | 8 | ||||
-rw-r--r-- | tests/fixtures/config/two-tenant/exclude-all.yaml | 20 | ||||
-rw-r--r-- | tests/unit/test_scheduler.py | 52 | ||||
-rw-r--r-- | zuul/ansible/base/callback/zuul_json.py | 8 | ||||
-rw-r--r-- | zuul/manager/__init__.py | 6 | ||||
-rw-r--r-- | zuul/model.py | 17 | ||||
-rw-r--r-- | zuul/scheduler.py | 6 | ||||
-rw-r--r-- | zuul/zk/event_queues.py | 2 |
9 files changed, 109 insertions, 17 deletions
diff --git a/releasenotes/notes/520-windows-7737f20c23b0afee.yaml b/releasenotes/notes/520-windows-7737f20c23b0afee.yaml new file mode 100644 index 000000000..2a50111a3 --- /dev/null +++ b/releasenotes/notes/520-windows-7737f20c23b0afee.yaml @@ -0,0 +1,7 @@ +--- +fixes: + - | + An issue introduced in Zuul version 5.2.0 which could cause jobs + running on Windows nodes to fail with the error `Could not find + imported module support code for 'Ansible.ModuleUtils.Legacy'"` + has been corrected. diff --git a/releasenotes/notes/project-regex-update-dcc183d923a6acdd.yaml b/releasenotes/notes/project-regex-update-dcc183d923a6acdd.yaml new file mode 100644 index 000000000..87c0e3fb1 --- /dev/null +++ b/releasenotes/notes/project-regex-update-dcc183d923a6acdd.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + Project name regex handling has been updated to return all possible + matches. Previously if there were collisions with short names it was an + error. The point of the regex system is to simplify configuration and + apply configs to all projects that match. Collisions don't impact this + behavior so we don't need to raise an error in these cases. diff --git a/tests/fixtures/config/two-tenant/exclude-all.yaml b/tests/fixtures/config/two-tenant/exclude-all.yaml new file mode 100644 index 000000000..60938c366 --- /dev/null +++ b/tests/fixtures/config/two-tenant/exclude-all.yaml @@ -0,0 +1,20 @@ +- tenant: + name: tenant-one + source: + gerrit: + config-projects: + - common-config + untrusted-projects: + - org/project1 + - org/project2: + include: [] + +- tenant: + name: tenant-two + source: + gerrit: + config-projects: + - common-config + untrusted-projects: + - org/project1 + - org/project2 diff --git a/tests/unit/test_scheduler.py b/tests/unit/test_scheduler.py index c596028de..3cb2507c4 100644 --- a/tests/unit/test_scheduler.py +++ b/tests/unit/test_scheduler.py @@ -8375,6 +8375,58 @@ class TestPipelineSupersedes(ZuulTestCase): ], ordered=False) +class TestSchedulerExcludeAll(ZuulTestCase): + tenant_config_file = 'config/two-tenant/exclude-all.yaml' + + def test_skip_reconfig_exclude_all(self): + """Test that we don't trigger a reconfiguration for a tenant + when the changed project excludes all config.""" + config = textwrap.dedent( + """ + - job: + name: project2-test + parent: test + + - project: + check: + jobs: + - project2-test + """) + file_dict = {'zuul.yaml': config} + A = self.fake_gerrit.addFakeChange('org/project2', 'master', 'A', + files=file_dict) + self.fake_gerrit.addEvent(A.getPatchsetCreatedEvent(1)) + self.waitUntilSettled() + self.assertHistory([ + dict(name='project2-test', result='SUCCESS', changes='1,1'), + ]) + + sched = self.scheds.first.sched + tenant_one_layout_state = sched.local_layout_state["tenant-one"] + tenant_two_layout_state = sched.local_layout_state["tenant-two"] + + A.setMerged() + self.fake_gerrit.addEvent(A.getChangeMergedEvent()) + self.waitUntilSettled() + + # We don't expect a reconfiguration for tenant-one as it excludes + # all config of org/project2. + self.assertEqual(sched.local_layout_state["tenant-one"], + tenant_one_layout_state) + # As tenant-two includes the config from org/project2, the merge of + # change A should have triggered a reconfig. + self.assertGreater(sched.local_layout_state["tenant-two"], + tenant_two_layout_state) + + B = self.fake_gerrit.addFakeChange('org/project2', 'master', 'B') + self.fake_gerrit.addEvent(B.getPatchsetCreatedEvent(1)) + self.waitUntilSettled() + self.assertHistory([ + dict(name='project2-test', result='SUCCESS', changes='1,1'), + dict(name='project2-test', result='SUCCESS', changes='2,1'), + ]) + + class TestReportBuildPage(ZuulTestCase): tenant_config_file = 'config/build-page/main.yaml' diff --git a/zuul/ansible/base/callback/zuul_json.py b/zuul/ansible/base/callback/zuul_json.py index 6b8b957bb..1d7059871 100644 --- a/zuul/ansible/base/callback/zuul_json.py +++ b/zuul/ansible/base/callback/zuul_json.py @@ -220,13 +220,17 @@ orig_find_plugin = PluginLoader.find_plugin def mp_get(self, name, *args, **kwargs): - name = name.rsplit('.', 1)[-1] + if (name.startswith('ansible.builtin.') or + name.startswith('ansible.legacy.')): + name = name.rsplit('.', 1)[-1] ret = orig_get(self, name, *args, **kwargs) return ret def mp_find_plugin(self, name, *args, **kwargs): - name = name.rsplit('.', 1)[-1] + if (name.startswith('ansible.builtin.') or + name.startswith('ansible.legacy.')): + name = name.rsplit('.', 1)[-1] ret = orig_find_plugin(self, name, *args, **kwargs) return ret diff --git a/zuul/manager/__init__.py b/zuul/manager/__init__.py index 84897b3df..418274859 100644 --- a/zuul/manager/__init__.py +++ b/zuul/manager/__init__.py @@ -1583,9 +1583,9 @@ class PipelineManager(metaclass=ABCMeta): request_id, cached=True) if not node_request: continue - if node_request.fulfilled: - # If the node request is already fulfilled, there is no - # need to update the relative priority. + if node_request.state != model.STATE_REQUESTED: + # If the node request was locked and accepted by a + # provider, we can no longer update the relative priority. continue if node_request.relative_priority != priority: self.sched.nodepool.reviseRequest( diff --git a/zuul/model.py b/zuul/model.py index f5604f196..888575393 100644 --- a/zuul/model.py +++ b/zuul/model.py @@ -7467,8 +7467,7 @@ class Tenant(object): :arg str regex: The regex to match :returns: A list of tuples (trusted, project) describing the found - projects. Raises an exception if the same project name is found - several times across multiple hostnames. + projects. """ matcher = re2.compile(regex) @@ -7476,18 +7475,12 @@ class Tenant(object): result = [] for name, hostname_dict in self.projects.items(): - if matcher.fullmatch(name): - # validate that this match is unambiguous - values = list(hostname_dict.values()) - if len(values) > 1: - raise Exception("Project name '%s' is ambiguous, " - "please fully qualify the project " - "with a hostname. Valid hostnames " - "are %s." % (name, hostname_dict.keys())) - projects.append(values[0]) + projects.extend(hostname_dict.values()) else: - # try to match canonical project names + # It is possible for the regex to match specific connection + # prefixes. Check these more specific names if we didn't add + # all of the possible canonical names already. for project in hostname_dict.values(): if matcher.fullmatch(project.canonical_name): projects.append(project) diff --git a/zuul/scheduler.py b/zuul/scheduler.py index efc7711a2..04b6b0f45 100644 --- a/zuul/scheduler.py +++ b/zuul/scheduler.py @@ -2178,6 +2178,12 @@ class Scheduler(threading.Thread): reconfigure_tenant = False + # If all config classes are excluded for this project we don't need + # to trigger a reconfiguration. + tpc = tenant.project_configs.get(project.canonical_name) + if tpc and not tpc.load_classes: + reconfigure_tenant = False + # But if the event is that branch protection status has # changed, do reconfigure. if (event.isBranchProtectionChanged()): diff --git a/zuul/zk/event_queues.py b/zuul/zk/event_queues.py index 06127b041..0e5cba987 100644 --- a/zuul/zk/event_queues.py +++ b/zuul/zk/event_queues.py @@ -47,6 +47,8 @@ MANAGEMENT_EVENT_TYPE_MAP = { "PromoteEvent": model.PromoteEvent, "ReconfigureEvent": model.ReconfigureEvent, "TenantReconfigureEvent": model.TenantReconfigureEvent, + "PipelinePostConfigEvent": model.PipelinePostConfigEvent, + "PipelineSemaphoreReleaseEvent": model.PipelineSemaphoreReleaseEvent, } # /zuul/events/tenant TENANT_ROOT |