class BuildbotDynamicResourse(Resource): logger = Logger() def __init__(self, master, parent_service: "BuildbotDynamicService"): super().__init__(master) self.parent_service = parent_service def reconfigResource(self, new_config): pass # TODO: add self.master.www.assertUserAllowed(...) def render_GET(self, request: Request): def cb(_): data = self.parent_service.get_projects() return defer.succeed(json.dumps(data).encode()) return self.asyncRenderHelper(request, cb) def render_POST(self, request: Request): def cb(req): param_names = Project._fields params = [req.args.get(pname.encode()) for pname in param_names] if any([param is None for param in params]): raise Error(http.BAD_REQUEST, ("Missing some of %s: %s" % (param_names, params)).encode()) data = self.parent_service.add_project( Project._make([param[0].decode() for param in params])) return defer.succeed(json.dumps(data).encode()) return self.asyncRenderHelper(request, cb)
# but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02110-1301, USA. from buildbot.config import BuilderConfig from buildbot.plugins import steps, util from buildbot.process.factory import BuildFactory from buildbot.util.logger import Logger from twisted.internet import defer log = Logger() @defer.inlineCallbacks def canStartBuild(builder, wfb, request): """Ensure we can run simultaneous builds on a stage.""" log.debug('Checking if we can start...') simultaneous_builds = request.properties.getProperty('simultaneous_builds') if simultaneous_builds: try: simultaneous_builds = int(simultaneous_builds) except ValueError: # When the object can be casted into an int ignore the value return True log.debug('%d simultaneous builds are allowed' % simultaneous_builds) name = request.properties.getProperty('virtual_builder_name',
from buildbot.process.results import Results from buildbot.process.results import SUCCESS, WARNINGS, FAILURE, EXCEPTION from buildbot.util.logger import Logger from dockermap.api import DockerClientWrapper from twisted.internet import reactor from twisted.python.log import PythonLoggingObserver from .builders import DockerBuilder from .configs import Config, MasterConfig from .utils import Matching, Filter, ensure_deferred from .docker import ImageCollection from .master import TestMaster logging.basicConfig() logger = logging.getLogger(__name__) logger_ = Logger() # twisted's logger # TODO(kszucs): try to use asyncio reactor with uvloop instead of the default # twisted one class UrsabotConfigErrors(click.ClickException): def __init__(self, wrapped): assert isinstance(wrapped, ConfigErrors) self.wrapped = wrapped def show(self): click.echo(click.style('Configuration Errors:', fg='red'), err=True) for e in self.wrapped.errors: click.echo(click.style(f' - {e}'), err=True)
from buildbot.process.results import FAILURE from buildbot.process.results import RETRY from buildbot.process.results import SKIPPED from buildbot.process.results import SUCCESS from buildbot.process.results import WARNINGS from buildbot.reporters.base import ReporterBase from buildbot.reporters.generators.build import BuildStartEndStatusGenerator from buildbot.reporters.message import MessageFormatterRenderable from buildbot.util import giturlparse from buildbot.util import httpclientservice from buildbot.process.results import statusToString from buildbot.reporters import http, utils from buildbot.util.logger import Logger logger = Logger() STATUS_EMOJIS = { "success": ":sunglassses:", "warnings": ":meow_wow:", "failure": ":skull:", "skipped": ":slam:", "exception": ":skull:", "retry": ":facepalm:", "cancelled": ":slam:", } STATUS_COLORS = { "success": "#36a64f", "warnings": "#fc8c03", "failure": "#fc0303", "skipped": "#fc8c03",
class BuildbotDynamicService(BuildbotService): logger = Logger() name = "Buildbot Dynamic Service" course_name_key = "course_name" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.course_name = None self.course_name_sha512 = None self.project_list_storage = None def reconfigService(self, *args, **kwargs) -> Deferred: self.course_name = kwargs[self.course_name_key] self.course_name_sha512 = name2sha512(self.course_name) self.project_list_storage = "%s.json" % self.course_name_sha512 root = self.master.www.apps.get("base").resource root.putChild(self.course_name_sha512.encode(), BuildbotDynamicResourse(self.master, self)) return super().reconfigService(self.name, *args, **kwargs) def checkConfig(self, *args, **kwargs) -> None: super().checkConfig(BuildbotDynamicService.name, *args, **kwargs) if self.course_name_key not in kwargs: error("No 'course_name' set for BuildbotDynamicService") course_name = kwargs[self.course_name_key] course_name_sha512 = name2sha512(course_name) project_list_storage = "%s.json" % course_name_sha512 if not isfile(project_list_storage): error("File '%s' does not exist" % project_list_storage) def add_project(self, project: Project) -> ProjectList: projects = self.get_projects() if project.name in projects: raise DuplicateProjectException( "Project '%s' already exists in: %s" % (project.name, projects)) new_project = { project.name: { "name": project.name, "url": project.url, "type": project.type } } projects.update(new_project) with open(self.project_list_storage, "wt") as f: json.dump(projects, f) self.master.reconfig() return projects def get_projects(self) -> ProjectList: with open(self.project_list_storage, "rt") as f: try: data = json.load(f) except json.JSONDecodeError as e: self.logger.error("Error when decoding '%s': %s" % (self.project_list_storage, e.msg)) data = {} return data