diff --git a/tests/unit/test_executor.py b/tests/unit/test_executor.py index 5ea65fa63e..0998886ffa 100755 --- a/tests/unit/test_executor.py +++ b/tests/unit/test_executor.py @@ -464,6 +464,14 @@ class TestGovernor(ZuulTestCase): self.executor_server.manageLoad() self.assertFalse(self.executor_server.accepting_work) + def test_pause_governor(self): + self.executor_server.manageLoad() + self.assertTrue(self.executor_server.accepting_work) + + self.executor_server.pause_sensor.pause = True + self.executor_server.manageLoad() + self.assertFalse(self.executor_server.accepting_work) + def waitForExecutorBuild(self, jobname): self.log.debug("Waiting for %s to start", jobname) timeout = time.time() + 30 diff --git a/zuul/executor/sensors/pause.py b/zuul/executor/sensors/pause.py new file mode 100644 index 0000000000..6127e4dd82 --- /dev/null +++ b/zuul/executor/sensors/pause.py @@ -0,0 +1,37 @@ +# Copyright 2018 BMW Car IT GmbH +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +import logging + +from zuul.executor.sensors import SensorInterface + + +class PauseSensor(SensorInterface): + log = logging.getLogger("zuul.executor.sensor.pause") + + def __init__(self): + self.pause = False + + def isOk(self): + if self.pause: + return False, 'paused' + else: + return True, 'running' + + def reportStats(self, statsd, base_key): + if self.pause: + value = 1 + else: + value = 0 + statsd.gauge(base_key + '.pause', value) diff --git a/zuul/executor/server.py b/zuul/executor/server.py index 1d035dc171..f58537d34d 100644 --- a/zuul/executor/server.py +++ b/zuul/executor/server.py @@ -26,6 +26,7 @@ import tempfile import threading import time import traceback + from zuul.lib.yamlutil import yaml from zuul.lib.config import get_default from zuul.lib.statsd import get_statsd @@ -39,6 +40,7 @@ import gear import zuul.merger.merger import zuul.ansible.logconfig from zuul.executor.sensors.cpu import CPUSensor +from zuul.executor.sensors.pause import PauseSensor from zuul.executor.sensors.startingbuilds import StartingBuildsSensor from zuul.executor.sensors.ram import RAMSensor from zuul.lib import commandsocket @@ -1868,9 +1870,11 @@ class ExecutorServer(object): self.stopJobDiskFull, self.merge_root) + self.pause_sensor = PauseSensor() cpu_sensor = CPUSensor(config) self.sensors = [ cpu_sensor, + self.pause_sensor, RAMSensor(config), StartingBuildsSensor(self, cpu_sensor.max_load_avg) ] @@ -2005,12 +2009,10 @@ class ExecutorServer(object): self.executor_thread.join() def pause(self): - # TODOv3: implement - pass + self.pause_sensor.pause = True def unpause(self): - # TODOv3: implement - pass + self.pause_sensor.pause = False def graceful(self): # TODOv3: implement