WIP: Start implementation of the build manager/controller. This code is not yet working completely.
This commit is contained in:
parent
2ccbea95a5
commit
eacf3f01d2
9 changed files with 576 additions and 0 deletions
0
buildman/manager/__init__.py
Normal file
0
buildman/manager/__init__.py
Normal file
36
buildman/manager/basemanager.py
Normal file
36
buildman/manager/basemanager.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
class BaseManager(object):
|
||||
""" Base for all worker managers. """
|
||||
def __init__(self, register_component, unregister_component, job_complete_callback):
|
||||
self.register_component = register_component
|
||||
self.unregister_component = unregister_component
|
||||
self.job_complete_callback = job_complete_callback
|
||||
|
||||
def shutdown(self):
|
||||
""" Indicates that the build controller server is in a shutdown state and that no new jobs
|
||||
or workers should be performed. Existing workers should be cleaned up once their jobs
|
||||
have completed
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def schedule(self, job_item):
|
||||
""" Schedules a queue item to be built. Returns True if the item was properly scheduled
|
||||
and False if all workers are busy.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def initialize(self):
|
||||
""" Runs any initialization code for the manager. Called once the server is in a ready state.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def build_component_disposed(self, build_component, timed_out):
|
||||
""" Method invoked whenever a build component has been disposed. The timed_out boolean indicates
|
||||
whether the component's heartbeat timed out.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def job_completed(self, job_item, job_status, build_component):
|
||||
""" Method invoked once a job_item has completed, in some manner. The job_status will be
|
||||
one of: incomplete, error, complete. If incomplete, the job should be requeued.
|
||||
"""
|
||||
raise NotImplementedError
|
65
buildman/manager/enterprise.py
Normal file
65
buildman/manager/enterprise.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
import logging
|
||||
import uuid
|
||||
|
||||
from buildman.manager.basemanager import BaseManager
|
||||
from buildman.basecomponent import BaseComponent
|
||||
from buildman.buildcomponent import BuildComponent
|
||||
|
||||
from trollius.coroutines import From
|
||||
|
||||
REGISTRATION_REALM = 'registration'
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class DynamicRegistrationComponent(BaseComponent):
|
||||
""" Component session that handles dynamic registration of the builder components. """
|
||||
|
||||
def onConnect(self):
|
||||
self.join(REGISTRATION_REALM)
|
||||
|
||||
def onJoin(self, details):
|
||||
logger.debug('Registering registration method')
|
||||
yield From(self.register(self._worker_register, u'io.quay.buildworker.register'))
|
||||
|
||||
def _worker_register(self):
|
||||
realm = self.parent_manager.add_build_component()
|
||||
logger.debug('Registering new build component+worker with realm %s', realm)
|
||||
return realm
|
||||
|
||||
|
||||
class EnterpriseManager(BaseManager):
|
||||
""" Build manager implementation for the Enterprise Registry. """
|
||||
build_components = []
|
||||
shutting_down = False
|
||||
|
||||
def initialize(self):
|
||||
# Add a component which is used by build workers for dynamic registration. Unlike
|
||||
# production, build workers in enterprise are long-lived and register dynamically.
|
||||
self.register_component(REGISTRATION_REALM, DynamicRegistrationComponent)
|
||||
|
||||
def add_build_component(self):
|
||||
# Generate a new unique realm ID for the build worker.
|
||||
realm = str(uuid.uuid4())
|
||||
component = self.register_component(realm, BuildComponent, token="")
|
||||
self.build_components.append(component)
|
||||
return realm
|
||||
|
||||
def schedule(self, job_item):
|
||||
if self.shutting_down:
|
||||
return False
|
||||
|
||||
for component in self.build_components:
|
||||
if component.is_ready():
|
||||
component.start_build(job_item)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def shutdown(self):
|
||||
self.shutting_down = True
|
||||
|
||||
def job_completed(self, job_item, job_status, build_component):
|
||||
self.job_complete_callback(job_item, job_status)
|
||||
|
||||
def component_disposed(self, build_component, timed_out):
|
||||
self.build_components.remove(build_component)
|
||||
|
Reference in a new issue