Package run :: Module build_on_pagure_commit
[hide private]
[frames] | no frames]

Source Code for Module run.build_on_pagure_commit

  1  #!/usr/bin/env python 
  2   
  3  import json 
  4  import pprint 
  5  import zmq 
  6  import sys 
  7  import os 
  8  import logging 
  9  import requests 
 10  import re 
 11   
 12  sys.path.append( 
 13      os.path.dirname(os.path.dirname(os.path.realpath(__file__))) 
 14  ) 
 15   
 16  from coprs import db, app 
 17  from coprs.logic.coprs_logic import CoprsLogic 
 18  from coprs.logic.builds_logic import BuildsLogic 
 19   
 20  TITO_TYPE = '3' 
 21  MOCK_SCM_TYPE = '4' 
 22   
 23  logging.basicConfig( 
 24      filename="{0}/build_on_pagure_commit.log".format(app.config.get("LOG_DIR")), 
 25      format='[%(asctime)s][%(levelname)6s]: %(message)s', 
 26      level=logging.DEBUG) 
 27  log = logging.getLogger(__name__) 
 28   
 29  PAGURE_BASE_URL = "https://pagure.io/" 
30 31 32 -class Package(object):
33 - def build(self):
34 raise NotImplemented()
35 36 @classmethod
37 - def new_from_db_row(cls, source_type, row):
38 try: 39 return { 40 TITO_TYPE: GitAndTitoPackage, 41 MOCK_SCM_TYPE: MockSCMPackage, 42 }[source_type](row) 43 except KeyError: 44 raise Exception('Unsupported package type {}'.format(source_type))
45 46 @classmethod
47 - def get_candidates_for_rebuild(cls, source_type, clone_url_subpart):
48 if db.engine.url.drivername == "sqlite": 49 placeholder = '?' 50 true = '1' 51 else: 52 placeholder = '%s' 53 true = 'true' 54 55 rows = db.engine.execute( 56 """ 57 SELECT package.id AS package_id, package.source_json AS source_json, package.copr_id AS copr_id 58 FROM package 59 WHERE package.source_type = '{0}' AND 60 package.webhook_rebuild = {1} AND 61 package.source_json ILIKE {placeholder} 62 """.format(source_type, true, placeholder=placeholder), '%'+clone_url_subpart+'%' 63 ) 64 return [Package.new_from_db_row(source_type, row) for row in rows]
65
66 67 -class GitAndTitoPackage(Package):
68 - def __init__(self, db_row):
69 source_json = json.loads(db_row.source_json) 70 self.pkg_id = db_row.package_id 71 self.git_url = source_json['git_url'] 72 self.git_branch = source_json['git_branch'] 73 self.git_dir = source_json['git_dir'] 74 self.tito_test = source_json['tito_test'] 75 self.copr_id = db_row.copr_id 76 self.copr = CoprsLogic.get_by_id(self.copr_id).first() 77 self.source_json = db_row.source_json
78
79 - def build(self):
80 BuildsLogic.create_new_from_tito(self.copr.user, self.copr, self.git_url, self.git_dir, self.git_branch, self.tito_test) 81 db.session.commit()
82
83 - def is_dir_in_commit(self, data, clone_url_subpart):
84 if not self.git_dir: 85 return True # simplest case 86 87 start_commit = data['msg']['start_commit'] 88 end_commit = data['msg']['end_commit'] 89 90 if start_commit != end_commit: 91 return True # more than one commit and no means to iterate over 92 93 raw_commit_url = PAGURE_BASE_URL + clone_url_subpart + '/raw/' + start_commit 94 r = requests.get(raw_commit_url) 95 if r.status_code != requests.codes.ok: 96 log.error("Bad http status {0} from url {1}".format(r.status_code, raw_commit_url)) 97 return False 98 99 for line in r.text.split('\n'): 100 match = re.search(r'^(\+\+\+|---) [ab]/(\w*)/.*$', line) 101 if match and match.group(2).lower() == self.git_dir.lower(): 102 return True 103 104 return False
105
106 107 -class MockSCMPackage(Package):
108 - def __init__(self, db_row):
109 source_json = json.loads(db_row.source_json) 110 self.pkg_id = db_row.package_id 111 self.scm_url = source_json['scm_url'] 112 self.scm_branch = source_json['scm_branch'] 113 self.scm_type = source_json['scm_type'] 114 self.spec = source_json['spec'] 115 self.copr_id = db_row.copr_id 116 self.copr = CoprsLogic.get_by_id(self.copr_id).first() 117 self.source_json = db_row.source_json
118
119 - def build(self):
120 BuildsLogic.create_new_from_mock(self.copr.user, self.copr, self.scm_type, self.scm_url, self.scm_branch, self.spec) 121 db.session.commit()
122
123 124 -def build_on_fedmsg_loop():
125 endpoint = 'tcp://hub.fedoraproject.org:9940' 126 topic = 'io.pagure.prod.pagure.git.receive' 127 128 ctx = zmq.Context() 129 s = ctx.socket(zmq.SUB) 130 s.connect(endpoint) 131 132 s.setsockopt(zmq.SUBSCRIBE, topic) 133 134 poller = zmq.Poller() 135 poller.register(s, zmq.POLLIN) 136 137 while True: 138 evts = poller.poll() # This blocks until a message arrives 139 topic, msg = s.recv_multipart() 140 data = json.loads(msg) 141 142 namespace = data['msg']['repo']['namespace'] 143 repo_name = data['msg']['repo']['name'] 144 branch = data['msg']['branch'] 145 146 if namespace: 147 clone_url_subpart = '/' + namespace + '/' + repo_name 148 else: 149 clone_url_subpart = '/' + repo_name 150 151 log.info("MSG:") 152 log.info("\tclone_url_subpart = {}".format(clone_url_subpart)) 153 log.info("\tbranch = {}".format(branch)) 154 155 for pkg in Package.get_candidates_for_rebuild(TITO_TYPE, clone_url_subpart): 156 log.info("Considering pkg id:{}, source_json:{}".format(pkg.pkg_id, pkg.source_json)) 157 if (pkg.git_url.endswith(clone_url_subpart) or pkg.git_url.endswith(clone_url_subpart+'.git')) \ 158 and (not pkg.git_branch or branch.endswith('/'+pkg.git_branch)) and pkg.is_dir_in_commit(data, clone_url_subpart): 159 log.info("\t -> rebuilding.") 160 pkg.build() 161 else: 162 log.info("\t -> skipping.") 163 164 for pkg in Package.get_candidates_for_rebuild(MOCK_SCM_TYPE, clone_url_subpart): 165 log.info("Considering pkg id:{}, source_json:{}".format(pkg.pkg_id, pkg.source_json)) 166 if (pkg.scm_url.endswith(clone_url_subpart) or pkg.scm_url.endswith(clone_url_subpart+'.git')) \ 167 and (not pkg.scm_branch or branch.endswith('/'+pkg.scm_branch)): 168 log.info("\t -> rebuilding.") 169 pkg.build() 170 else: 171 log.info("\t -> skipping.")
172 173 if __name__ == '__main__': 174 build_on_fedmsg_loop() 175