load_from_disk.py 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. #!/usr/bin/env python
  2. import argparse
  3. import requests
  4. import os
  5. from sqlalchemy.exc import SQLAlchemyError
  6. if 'PAGURE_CONFIG' not in os.environ \
  7. and os.path.exists('/etc/pagure/pagure.cfg'):
  8. print 'Using configuration file `/etc/pagure/pagure.cfg`'
  9. os.environ['PAGURE_CONFIG'] = '/etc/pagure/pagure.cfg'
  10. import pagure
  11. import pagure.lib
  12. import pagure.lib.model
  13. def get_poc_of_pkgs(debug=False):
  14. """ Retrieve a dictionary giving the point of contact of each package
  15. in pkgdb.
  16. """
  17. if debug:
  18. print 'Querying pkgdb'
  19. PKGDB_URL = 'https://admin.stg.fedoraproject.org/pkgdb/api/'
  20. req = requests.get(PKGDB_URL + 'bugzilla').text
  21. if debug:
  22. print 'Pkgdb data retrieved, getting POC'
  23. pkgs = {}
  24. for line in req.split('\n'):
  25. line = line.strip()
  26. if not line or line.startswith('#'):
  27. continue
  28. line = line.split('|')
  29. if len(line) < 4:
  30. continue
  31. pkgs[line[1]] = line[3]
  32. return pkgs
  33. def main(folder, debug=False):
  34. """
  35. Logic:
  36. - Query the list of maintainer/PoC from pkgdb
  37. - Browse the directory
  38. - For each git in the directory, create the project with the correct POC
  39. """
  40. pocs = get_poc_of_pkgs(debug=debug)
  41. if debug:
  42. print 'Adding the user to the DB'
  43. for user in sorted(set(pocs.values())):
  44. if debug:
  45. print user
  46. try:
  47. pagure.lib.set_up_user(
  48. session=pagure.SESSION,
  49. username=user,
  50. fullname=user,
  51. default_email='%s@fedoraproject.org' % user,
  52. keydir=pagure.APP.config.get('GITOLITE_KEYDIR', None),
  53. )
  54. pagure.SESSION.commit()
  55. except SQLAlchemyError as err:
  56. pagure.SESSION.rollback()
  57. print 'ERROR with user %s' % user
  58. print err
  59. for project in sorted(os.listdir(folder)):
  60. if debug:
  61. print project
  62. if not project.endswith('.git'):
  63. if debug:
  64. print ' -skip: not a git repository'
  65. continue
  66. if project.split('.git')[0] not in pocs:
  67. if debug:
  68. print ' -skip: no pocs'
  69. continue
  70. try:
  71. name = project.split('.git')[0]
  72. orig_name = name
  73. name = 'rpms/%s' % name
  74. if name in pagure.APP.config['BLACKLISTED_PROJECTS']:
  75. raise pagure.exceptions.RepoExistsException(
  76. 'No project "%s" are allowed to be created due to potential '
  77. 'conflicts in URLs with pagure itself' % name
  78. )
  79. user_obj = pagure.lib.get_user(pagure.SESSION, pocs[orig_name])
  80. allowed_prefix = pagure.APP.config[
  81. 'ALLOWED_PREFIX'] + [grp for grp in user_obj.groups]
  82. first_part, _, second_part = name.partition('/')
  83. if second_part and first_part not in allowed_prefix:
  84. raise pagure.exceptions.PagureException(
  85. 'The prefix of your project must be in the list of allowed '
  86. 'prefixes set by the admins of this pagure instance, or the name '
  87. 'of a group of which you are a member.'
  88. )
  89. gitfolder = pagure.APP.config['GIT_FOLDER']
  90. docfolder = pagure.APP.config['DOCS_FOLDER']
  91. ticketfolder = pagure.APP.config['TICKETS_FOLDER']
  92. requestfolder = pagure.APP.config['REQUESTS_FOLDER']
  93. gitrepo = os.path.join(gitfolder, '%s.git' % name)
  94. project = pagure.lib.model.Project(
  95. name=name,
  96. description=None,
  97. url=None,
  98. avatar_email=None,
  99. user_id=user_obj.id,
  100. parent_id=None,
  101. hook_token=pagure.lib.login.id_generator(40)
  102. )
  103. pagure.SESSION.add(project)
  104. # Make sure we won't have SQLAlchemy error before we create the repo
  105. pagure.SESSION.flush()
  106. http_clone_file = os.path.join(gitrepo, 'git-daemon-export-ok')
  107. if not os.path.exists(http_clone_file):
  108. with open(http_clone_file, 'w') as stream:
  109. pass
  110. docrepo = os.path.join(docfolder, project.path)
  111. if os.path.exists(docrepo):
  112. shutil.rmtree(gitrepo)
  113. raise pagure.exceptions.RepoExistsException(
  114. 'The docs repo "%s" already exists' % project.path
  115. )
  116. pygit2.init_repository(docrepo, bare=True)
  117. ticketrepo = os.path.join(ticketfolder, project.path)
  118. if os.path.exists(ticketrepo):
  119. shutil.rmtree(gitrepo)
  120. shutil.rmtree(docrepo)
  121. raise pagure.exceptions.RepoExistsException(
  122. 'The tickets repo "%s" already exists' % project.path
  123. )
  124. pygit2.init_repository(
  125. ticketrepo, bare=True,
  126. mode=pygit2.C.GIT_REPOSITORY_INIT_SHARED_GROUP)
  127. requestrepo = os.path.join(requestfolder, project.path)
  128. if os.path.exists(requestrepo):
  129. shutil.rmtree(gitrepo)
  130. shutil.rmtree(docrepo)
  131. shutil.rmtree(ticketrepo)
  132. raise pagure.exceptions.RepoExistsException(
  133. 'The requests repo "%s" already exists' % project.path
  134. )
  135. pygit2.init_repository(
  136. requestrepo, bare=True,
  137. mode=pygit2.C.GIT_REPOSITORY_INIT_SHARED_GROUP)
  138. pagure.SESSION.commit()
  139. except pagure.exceptions.PagureException as err:
  140. print 'ERROR with project %s' % project
  141. print err
  142. except SQLAlchemyError as err: # pragma: no cover
  143. pagure.SESSION.rollback()
  144. print 'ERROR (DB) with project %s' % project
  145. print err
  146. if __name__ == '__main__':
  147. parser = argparse.ArgumentParser(
  148. description='Script creating projects on pagure based on the git '
  149. 'repos present in the specified folder and the pkgdb information.'
  150. )
  151. parser.add_argument(
  152. 'folder',
  153. help='Folder containing all the git repos of the projects to create')
  154. parser.add_argument(
  155. '--debug', dest='debug', action='store_true', default=False,
  156. help='Print the debugging output')
  157. args = parser.parse_args()
  158. main(args.folder, debug=args.debug)