Module manage
[hide private]
[frames] | no frames]

Source Code for Module manage

  1  #!/usr/bin/python 
  2   
  3  import argparse 
  4  import os 
  5  import subprocess 
  6  import datetime 
  7  import sqlalchemy 
  8  import time 
  9   
 10  import flask 
 11  from flask_script import Manager, Command, Option, Group 
 12   
 13  from coprs import app 
 14  from coprs import db 
 15  from coprs import exceptions 
 16  from coprs import models 
 17  from coprs.logic import coprs_logic, packages_logic, actions_logic, builds_logic 
 18  from coprs.views.misc import create_user_wrapper 
 19  from coprs.whoosheers import CoprWhoosheer 
 20  from run import generate_repo_packages 
 21  from sqlalchemy import or_ 
 22   
 23   
24 -class TestCommand(Command):
25
26 - def run(self, test_args):
27 os.environ["COPRS_ENVIRON_UNITTEST"] = "1" 28 if not (("COPR_CONFIG" in os.environ) and os.environ["COPR_CONFIG"]): 29 os.environ["COPR_CONFIG"] = "/etc/copr/copr_unit_test.conf" 30 os.environ["PYTHONPATH"] = "." 31 return subprocess.call(["/usr/bin/python", "-m", "pytest"] + (test_args or []))
32 33 option_list = ( 34 Option("-a", 35 dest="test_args", 36 nargs=argparse.REMAINDER), 37 )
38 39
40 -class CreateSqliteFileCommand(Command):
41 42 """ 43 Create the sqlite DB file (not the tables). 44 Used for alembic, "create_db" does this automatically. 45 """ 46
47 - def run(self):
48 if flask.current_app.config["SQLALCHEMY_DATABASE_URI"].startswith("sqlite"): 49 # strip sqlite:/// 50 datadir_name = os.path.dirname( 51 flask.current_app.config["SQLALCHEMY_DATABASE_URI"][10:]) 52 if not os.path.exists(datadir_name): 53 os.makedirs(datadir_name)
54 55
56 -class CreateDBCommand(Command):
57 58 """ 59 Create the DB schema 60 """ 61
62 - def run(self, alembic_ini=None):
63 CreateSqliteFileCommand().run() 64 db.create_all() 65 66 # load the Alembic configuration and generate the 67 # version table, "stamping" it with the most recent rev: 68 from alembic.config import Config 69 from alembic import command 70 alembic_cfg = Config(alembic_ini) 71 command.stamp(alembic_cfg, "head") 72 73 # Functions are not covered by models.py, and no migrations are run 74 # by command.stamp() above. Create functions explicitly: 75 builds_logic.BuildsLogic.init_db()
76 77 option_list = ( 78 Option("--alembic", 79 "-f", 80 dest="alembic_ini", 81 help="Path to the alembic configuration file (alembic.ini)", 82 required=True), 83 )
84 85
86 -class DropDBCommand(Command):
87 88 """ 89 Delete DB 90 """ 91
92 - def run(self):
93 db.drop_all()
94 95
96 -class ChrootCommand(Command):
97
98 - def print_invalid_format(self, chroot_name):
99 print( 100 "{0} - invalid chroot format, must be '{release}-{version}-{arch}'." 101 .format(chroot_name))
102
103 - def print_already_exists(self, chroot_name):
104 print("{0} - already exists.".format(chroot_name))
105
106 - def print_doesnt_exist(self, chroot_name):
107 print("{0} - chroot doesn\"t exist.".format(chroot_name))
108 109 option_list = ( 110 Option("chroot_names", 111 help="Chroot name, e.g. fedora-18-x86_64.", 112 nargs="+"), 113 )
114 115
116 -class CreateChrootCommand(ChrootCommand):
117 118 "Creates a mock chroot in DB" 119
120 - def run(self, chroot_names):
129 130
131 -class RawhideToReleaseCommand(Command):
132 133 option_list = ( 134 Option("rawhide_chroot", help="Rawhide chroot name, e.g. fedora-rawhide-x86_64."), 135 Option("dest_chroot", help="Destination chroot, e.g. fedora-24-x86_64."), 136 ) 137
138 - def run(self, rawhide_chroot, dest_chroot):
139 mock_chroot = coprs_logic.MockChrootsLogic.get_from_name(dest_chroot).first() 140 if not mock_chroot: 141 print("Given chroot does not exist. Please run:") 142 print(" sudo python manage.py create_chroot {}".format(dest_chroot)) 143 return 144 145 mock_rawhide_chroot = coprs_logic.MockChrootsLogic.get_from_name(rawhide_chroot).first() 146 if not mock_rawhide_chroot: 147 print("Given rawhide chroot does not exist. Didnt you mistyped?:") 148 print(" {}".format(rawhide_chroot)) 149 return 150 151 for copr in coprs_logic.CoprsLogic.get_all(): 152 if not self.has_rawhide(copr): 153 continue 154 155 data = {"copr": copr.name, 156 "user": copr.user.name, 157 "rawhide_chroot": rawhide_chroot, 158 "dest_chroot": dest_chroot, 159 "builds": []} 160 161 for package in packages_logic.PackagesLogic.get_all(copr.id): 162 last_build = package.last_build(successful=True) 163 if last_build: 164 data["builds"].append(last_build.result_dir_name) 165 166 # rbc means rawhide_build_chroot (we needed short variable) 167 rbc = builds_logic.BuildChrootsLogic.get_by_build_id_and_name(last_build.id, rawhide_chroot).first() 168 dbc = builds_logic.BuildChrootsLogic.get_by_build_id_and_name(last_build.id, dest_chroot).first() 169 if rbc and not dbc: 170 dest_build_chroot = models.BuildChroot(**rbc.to_dict()) 171 dest_build_chroot.mock_chroot_id = mock_chroot.id 172 dest_build_chroot.mock_chroot = mock_chroot 173 db.session.add(dest_build_chroot) 174 175 if len(data["builds"]): 176 actions_logic.ActionsLogic.send_rawhide_to_release(data) 177 self.turn_on_the_chroot_for_copr(copr, rawhide_chroot, mock_chroot) 178 179 db.session.commit()
180
181 - def turn_on_the_chroot_for_copr(self, copr, rawhide_name, mock_chroot):
182 rawhide_chroot = coprs_logic.CoprChrootsLogic.get_by_name_safe(copr, rawhide_name) 183 dest_chroot = coprs_logic.CoprChrootsLogic.get_by_name_safe(copr, mock_chroot.name) 184 185 if not rawhide_chroot or dest_chroot: 186 return 187 188 create_kwargs = { 189 "buildroot_pkgs": rawhide_chroot.buildroot_pkgs, 190 "comps": rawhide_chroot.comps, 191 "comps_name": rawhide_chroot.comps_name, 192 } 193 coprs_logic.CoprChrootsLogic.create_chroot(copr.user, copr, mock_chroot, **create_kwargs)
194
195 - def has_rawhide(self, copr):
196 return any(filter(lambda ch: ch.os_version == "rawhide", copr.mock_chroots))
197 198
199 -class BackendRawhideToReleaseCommand(RawhideToReleaseCommand):
200 201 "Copy backend data of the latest successful rawhide builds into a new chroot" 202
203 - def run(self, rawhide_chroot, dest_chroot):
204 for copr in coprs_logic.CoprsLogic.get_all(): 205 if not self.has_rawhide(copr): 206 continue 207 208 data = {"copr": copr.name, 209 "user": copr.owner_name, 210 "rawhide_chroot": rawhide_chroot, 211 "dest_chroot": dest_chroot, 212 "builds": []} 213 214 for package in packages_logic.PackagesLogic.get_all(copr.id): 215 last_build = package.last_build(successful=True) 216 if last_build: 217 data["builds"].append(last_build.result_dir_name) 218 219 if len(data["builds"]): 220 actions_logic.ActionsLogic.send_rawhide_to_release(data) 221 print("Created copy action from {}/{} to {}/{}" 222 .format(copr.full_name, rawhide_chroot, copr.full_name, dest_chroot)) 223 224 db.session.commit()
225
226 -class AlterChrootCommand(ChrootCommand):
227 228 "Activates or deactivates a chroot" 229
230 - def run(self, chroot_names, action):
231 activate = (action == "activate") 232 for chroot_name in chroot_names: 233 try: 234 coprs_logic.MockChrootsLogic.edit_by_name( 235 chroot_name, activate) 236 db.session.commit() 237 except exceptions.MalformedArgumentException: 238 self.print_invalid_format(chroot_name) 239 except exceptions.NotFoundException: 240 self.print_doesnt_exist(chroot_name)
241 242 option_list = ChrootCommand.option_list + ( 243 Option("--action", 244 "-a", 245 dest="action", 246 help="Action to take - currently activate or deactivate", 247 choices=["activate", "deactivate"], 248 required=True), 249 )
250 251
252 -class DropChrootCommand(ChrootCommand):
253 254 "Activates or deactivates a chroot" 255
256 - def run(self, chroot_names):
265 266
267 -class DisplayChrootsCommand(Command):
268 269 "Displays current mock chroots" 270
271 - def run(self, active_only):
272 for ch in coprs_logic.MockChrootsLogic.get_multiple( 273 active_only=active_only).all(): 274 275 print(ch.name)
276 277 option_list = ( 278 Option("--active-only", 279 "-a", 280 dest="active_only", 281 help="Display only active chroots", 282 required=False, 283 action="store_true", 284 default=False), 285 )
286 287
288 -class AddDebugUserCommand(Command):
289 290 """ 291 Adds user for debug/testing purpose. 292 You shouldn't use this on production instance 293 """ 294
295 - def run(self, name, mail, **kwargs):
296 user = User(username=name, mail=mail) 297 298 if kwargs["admin"]: 299 user.admin = True 300 if kwargs["no_admin"]: 301 user.admin = False 302 if kwargs["proven"]: 303 user.proven = True 304 if kwargs["no_proven"]: 305 user.proven = False 306 # 307 # if kwargs["api_token"]: 308 # user.api_token = kwargs["api_token"] 309 # user.api_token_expiration = datetime.date(2030, 1, 1) 310 # if kwargs["api_login"]: 311 # user.api_token = kwargs["api_login"] 312 # 313 314 db.session.add(create_user_wrapper(user, mail)) 315 db.session.commit()
316 317 option_list = ( 318 Option("name"), 319 Option("mail"), 320 Option("--api_token", default=None, required=False), 321 Option("--api_login", default=None, required=False), 322 Group( 323 Option("--admin", 324 action="store_true"), 325 Option("--no-admin", 326 action="store_true"), 327 exclusive=True 328 ), 329 Group( 330 Option("--proven", 331 action="store_true"), 332 Option("--no-proven", 333 action="store_true"), 334 exclusive=True 335 ), 336 )
337 338
339 -class AlterUserCommand(Command):
340
341 - def run(self, name, **kwargs):
342 user = models.User.query.filter( 343 models.User.username == name).first() 344 if not user: 345 print("No user named {0}.".format(name)) 346 return 347 348 if kwargs["admin"]: 349 user.admin = True 350 if kwargs["no_admin"]: 351 user.admin = False 352 if kwargs["proven"]: 353 user.proven = True 354 if kwargs["no_proven"]: 355 user.proven = False 356 357 db.session.add(user) 358 db.session.commit()
359 360 option_list = ( 361 Option("name"), 362 Group( 363 Option("--admin", 364 action="store_true"), 365 Option("--no-admin", 366 action="store_true"), 367 exclusive=True 368 ), 369 Group( 370 Option("--proven", 371 action="store_true"), 372 Option("--no-proven", 373 action="store_true"), 374 exclusive=True 375 ) 376 )
377 378
379 -class FailBuildCommand(Command):
380 381 """ 382 Marks build as failed on all its non-finished chroots 383 """ 384 385 option_list = [Option("build_id")] 386
387 - def run(self, build_id, **kwargs):
388 try: 389 builds_logic.BuildsLogic.mark_as_failed(build_id) 390 print("Marking non-finished chroots of build {} as failed".format(build_id)) 391 db.session.commit() 392 393 except (sqlalchemy.exc.DataError, sqlalchemy.orm.exc.NoResultFound) as e: 394 print("Error: No such build {}".format(build_id)) 395 return 1
396 397
398 -class UpdateIndexesCommand(Command):
399 """ 400 recreates whoosh indexes for all projects 401 """ 402
403 - def run(self):
404 writer = CoprWhoosheer.index.writer() 405 for copr in coprs_logic.CoprsLogic.get_all(): 406 CoprWhoosheer.delete_copr(writer, copr) 407 writer.commit(optimize=True) 408 409 writer = CoprWhoosheer.index.writer() 410 writer.schema = CoprWhoosheer.schema 411 writer.commit(optimize=True) 412 413 writer = CoprWhoosheer.index.writer() 414 for copr in coprs_logic.CoprsLogic.get_all(): 415 CoprWhoosheer.insert_copr(writer, copr) 416 writer.commit(optimize=True)
417 418
419 -class UpdateIndexesQuickCommand(Command):
420 """ 421 Recreates whoosh indexes for projects for which 422 indexed data were updated in last n minutes. 423 Doesn't update schema. 424 """ 425 426 option_list = [Option("minutes_passed")] 427
428 - def run(self, minutes_passed):
429 writer = CoprWhoosheer.index.writer() 430 query = db.session.query(models.Copr).filter( 431 models.Copr.latest_indexed_data_update >= time.time()-int(minutes_passed)*60 432 ) 433 for copr in query.all(): 434 CoprWhoosheer.update_copr(writer, copr) 435 writer.commit()
436 437
438 -class GenerateRepoPackagesCommand(Command):
439 """ 440 go through all coprs and create configuration rpm packages 441 for them, if they don't already have it 442 """ 443
444 - def run(self):
446 447 448 manager = Manager(app) 449 manager.add_command("test", TestCommand()) 450 manager.add_command("create_sqlite_file", CreateSqliteFileCommand()) 451 manager.add_command("create_db", CreateDBCommand()) 452 manager.add_command("drop_db", DropDBCommand()) 453 manager.add_command("create_chroot", CreateChrootCommand()) 454 manager.add_command("alter_chroot", AlterChrootCommand()) 455 manager.add_command("display_chroots", DisplayChrootsCommand()) 456 manager.add_command("drop_chroot", DropChrootCommand()) 457 manager.add_command("alter_user", AlterUserCommand()) 458 manager.add_command("add_debug_user", AddDebugUserCommand()) 459 manager.add_command("fail_build", FailBuildCommand()) 460 manager.add_command("update_indexes", UpdateIndexesCommand()) 461 manager.add_command("update_indexes_quick", UpdateIndexesQuickCommand()) 462 manager.add_command("generate_repo_packages", GenerateRepoPackagesCommand()) 463 manager.add_command("rawhide_to_release", RawhideToReleaseCommand()) 464 manager.add_command("backend_rawhide_to_release", BackendRawhideToReleaseCommand()) 465 466 if __name__ == "__main__": 467 manager.run() 468