def process_pipelines_for(self, project): pipelines = self.pipeline_repository.get_all_pipelines_for(project) for pipeline in pipelines: for i in range(len(pipeline.items)): if i < len(pipeline.items) - 1: if pipeline.items[i].project.id == project.id: print "Adding project %d to the queue because it's in the same pipeline as project %s" % (pipeline.items[i+1].project.id, pipeline.items[i].project.name) SkinkContext.current().build_queue.append(pipeline.items[i+1].project.id)
def process_monitored_projects(self): ctx = SkinkContext.current() while(not self.should_die): try: monitored_projects = self.project_repository.get_projects_to_monitor() if not monitored_projects and ctx.scm_verbose: print "No projects found for monitoring..." for project in monitored_projects: if project.id in ctx.projects_being_built: continue if project.id in ctx.build_queue: continue if ctx.scm_verbose: print "Polling %s..." % project.name if self.scm.does_project_need_update(project): if ctx.scm_verbose: print "Adding project %s(%d) to the queue due to remote changes." % (project.name, project.id) ctx.build_queue.append(project.id) else: if ctx.scm_verbose: print "Project %s is already up-to-date" % project.name time.sleep(2) time.sleep(ctx.polling_interval) except Exception: cherrypy.engine.exit() raise
def verify_and_create(cls): ctx = SkinkContext.current() metadata.bind = ctx.db_connection metadata.bind.echo = ctx.db_verbose setup_all() if not cls.is_db_created(): create_all()
def current_status(self, **data): ctx = SkinkContext.current() result = {} result["project"] = ctx.current_project and ctx.current_project.name or "" result["project_id"] = ctx.current_project and ctx.current_project.id or "" result["command"] = ctx.current_command result["log"] = ctx.current_log and u"<br />".join(unicode(ctx.current_log).splitlines()[-30:]) or "" return demjson.encode(result)
def build_status(self, **data): ctx = SkinkContext.current() projects = self.repository.get_all() projects_being_built = [int(project_id) for project_id in ctx.projects_being_built] result = {} for project in projects: if project.id in projects_being_built: result[project.id] = "BUILDING" else: result[project.id] = (project.builds is not None and len(project.builds) > 0) and "BUILT" or "UNKNOWN" return "\n".join(["%s=%s" % (k, v) for k, v in result.items()])
def run_migrations(drop_db=False): ctx = SkinkContext.current() config = InPlaceConfig(db_host=ctx.db_host, db_user=ctx.db_user, db_password=ctx.db_pass, db_name=ctx.db_name, migrations_dir=join(root_path, "db")) config.put("schema_version", None) config.put("show_sql", False) config.put("show_sql_only", False) config.put("new_migration", None) config.put("drop_db_first", drop_db) Main(config).execute()
def start(cls): ctx = SkinkContext.current() Db.verify_and_create() cherrypy.config.update({ 'server.socket_host': ctx.host, 'server.socket_port': ctx.port, 'request.base': ctx.root, 'tools.encode.on': True, 'tools.encode.encoding': 'utf-8', 'tools.decode.on': True, 'tools.trailing_slash.on': True, 'tools.staticdir.root': join(root_path, "skink/"), 'tools.ElixirTransaction.on': True, 'log.screen': ctx.webserver_verbose, 'tools.sessions.on': True }) conf = { '/': { 'request.dispatch': cls.__setup_routes(), }, '/media': { 'tools.staticdir.on': True, 'tools.staticdir.dir': 'media' } } app = cherrypy.tree.mount(None, config=conf) #starting cherrypy plugins build_path = join(root_path, SkinkContext.current().build_path) builder_plugin = BuilderPlugin(cherrypy.engine, BuildService()) monitor_plugin = MonitorPlugin(cherrypy.engine, ProjectRepository(), GitRepository(build_path)) builder_plugin.subscribe() monitor_plugin.subscribe() cherrypy.quickstart(app)
def process_build_queue(self): ctx = SkinkContext.current() while not self.should_die: try: self.do_log("Polling Queue for projects to build...") if ctx.build_queue: item = ctx.build_queue.pop() self.do_log("Found %s to build. Building..." % item) try: self.build_service.build_project(item) except Exception: elixir.session.rollback() raise elixir.session.commit() self.do_log("Project %s finished building." % item) time.sleep(ctx.build_polling_interval) except Exception: cherrypy.engine.exit() raise
def do_login(self, cancel, data): if cherrypy.request.method == "POST": ctx = SkinkContext.current() if cancel: raise cherrypy.HTTPRedirect("/") username = data["username"] password = data["password"] if username != ctx.username or password != ctx.password: return template.render(authenticated=self.authenticated, errors=["Invalid username or password!"]) cherrypy.session["authenticated"] = True raise cherrypy.HTTPRedirect("/") errors = [] if data.has_key("login_error"): errors.append(data["login_error"]) return template.render(authenticated=self.authenticated(), errors=errors)
def raiseEvent(cls, event, *args, **kwargs): for plugin in SkinkContext.current().plugins: if hasattr(plugin, event): method = getattr(plugin, event) method(*args, **kwargs)
def do_log(self, message): ctx = SkinkContext.current() if ctx.build_verbose: print message
def log(self, message): ctx = SkinkContext.current() if ctx.scm_verbose: print message
def build(self, project_id): print "Adding project %s to the queue" % project_id SkinkContext.current().build_queue.append(project_id) raise cherrypy.HTTPRedirect("/project/%s" % project_id)
def __init__(self, repository=None, pipeline_repository=None, scm=None, executer=None, base_path=join(root_path, SkinkContext.current().build_path)): self.repository = repository if not repository: self.repository = ProjectRepository() self.pipeline_repository = pipeline_repository if not pipeline_repository: self.pipeline_repository = PipelineRepository() self.scm = scm if not scm: self.scm = GitRepository(base_path) self.executer = executer if not executer: self.executer = ShellExecuter() self.base_path = base_path
def finish_execute(self, executer): ctx = SkinkContext.current() ctx.current_command = None ctx.current_start_time = None ctx.current_project = None ctx.current_log = None
def execute_beat(self, executer): ctx = SkinkContext.current() ctx.current_command = executer.command ctx.current_log = executer.result.log
def start_execute(self, executer): ctx = SkinkContext.current() ctx.current_command = executer.command ctx.current_start_time = time.time() ctx.current_project = self.current_project ctx.current_log = None
def build_project(self, project_id): ctx = SkinkContext.current() log = ["Build started at %s" % datetime.now()] status = BuildService.Failure scm_status = ScmResult.Failed project = self.repository.get(project_id) PluginEvents.on_before_build(project) ctx.projects_being_built.append(project_id) last_build_number = project.get_last_build_number() build = Build() build.date = datetime.now() build.status = status build.scm_status = scm_status build.log = "" build.project = project scm_creation_result = self.scm.create_or_update(project) build.scm_status = scm_creation_result.status if scm_creation_result.status == ScmResult.Failed: log.append(scm_creation_result.log) status = BuildService.Failure else: log.append("Downloaded code from %s (%s)" % (project.scm_repository, scm_creation_result.status)) execute_result = self.executer.execute(project.build_script, scm_creation_result.repository_path, timeout=ctx.build_timeout) log.append("Executed %s" % project.build_script) log.append("Exit Code: %s" % execute_result.exit_code) log.append("Run Log:") log.append(execute_result.run_log) status = execute_result.exit_code == 0 and BuildService.Success or BuildService.Failure for command in project.tabs: build_tab = BuildTab(name=command.name, command=command.command, content_type=command.content_type, build=build) result = self.executer.execute(command.command, scm_creation_result.repository_path) build_tab.log = result.run_log for file_locator in project.file_locators: file_locator_path = join(self.base_path, project.name, file_locator.locator) print "Finding files for locator %s" % file_locator_path files = glob.glob(file_locator_path) print "%d files found" % len(files) for f in files: print "Adding file %s" % f filename = split(f)[-1] stream = open(f, 'rb') content = stream.read() stream.close() build_file = BuildFile(name=filename, original_path=f, content=content, build=build) build.number = last_build_number + 1 build.status = status build.log = "\n".join(log) build.commit_number = force_unicode(scm_creation_result.last_commit["commit_number"]) build.commit_author = force_unicode(scm_creation_result.last_commit["author"]) build.commit_committer = force_unicode(scm_creation_result.last_commit["committer"]) build.commit_author_date = scm_creation_result.last_commit["author_date"] build.commit_committer_date = scm_creation_result.last_commit["committer_date"] build.commit_text = force_unicode(scm_creation_result.last_commit["subject"]) self.repository.update(project, project.tabs, [locator.locator for locator in project.file_locators]) ctx.projects_being_built.remove(project_id) if (build.status == BuildService.Success): PluginEvents.on_build_successful(project, build) self.process_pipelines_for(project) else: PluginEvents.on_build_failed(project, build) return build
#!/usr/bin/env python # -*- coding:utf-8 -*- import os import sys from os.path import dirname, abspath, join root_path = abspath(join(dirname(__file__), "../../")) sys.path.insert(0, root_path) from skink.imports import * from skink.context import SkinkContext current_template = SkinkContext.current().current_template template_path = join(root_path, 'skink','templates', current_template) loader = TemplateLoader( template_path, auto_reload=True ) def output(filename, method='html', encoding='utf-8', **options): """Decorator for exposed methods to specify what template they should use for rendering, and which serialization method and options should be applied. """ def decorate(func): def wrapper(*args, **kwargs): cherrypy.thread_data.template = loader.load(filename) opt = options.copy() if method == 'html': opt.setdefault('doctype', 'html') serializer = get_serializer(method, **opt)