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

Source Code for Module run.generate_repo_packages

  1  #!/usr/bin/python 
  2  # -*- coding: utf-8 -*- 
  3   
  4  # RUN 
  5  #     cd frontend/coprs_frontend 
  6  #     COPR_CONFIG=../config/copr_devel.conf python run/generate_repo_packages.py 
  7   
  8   
  9  from __future__ import print_function 
 10  from __future__ import unicode_literals 
 11  from __future__ import division 
 12  from __future__ import absolute_import 
 13   
 14  import requests 
 15  import os 
 16  import shutil 
 17  import subprocess 
 18  import logging 
 19  from six.moves.urllib.parse import urljoin 
 20   
 21  here = os.path.dirname(os.path.realpath(__file__)) 
 22  import sys 
 23  sys.path.append(os.path.dirname(here)) 
 24   
 25  from coprs import app 
 26  from coprs.logic.coprs_logic import CoprsLogic 
 27   
 28   
 29  # ---------------------------------------------------------------------------------------------------------------------- 
 30   
 31  hostname = app.config["PUBLIC_COPR_HOSTNAME"] 
 32  scheme = app.config["ENFORCE_PROTOCOL_FOR_FRONTEND_URL"] if "ENFORCE_PROTOCOL_FOR_FRONTEND_URL" in app.config else "http" 
 33   
 34  FRONTEND_URL = "{}://{}".format(scheme, hostname) 
 35  FRONTEND_DIR = os.path.dirname(here) 
 36  PACKAGES_DIR = os.path.join(app.config["DATA_DIR"], "repo-rpm-packages") 
 37  RPMBUILD = os.path.join(os.path.expanduser("~"), "rpmbuild") 
 38  LOG_FILE = "/var/log/copr-frontend/repo-packages.log" 
 39   
 40  VERSION = 1 
 41  RELEASE = 1 
 42   
 43   
 44  # ---------------------------------------------------------------------------------------------------------------------- 
 45   
 46  log = logging.getLogger(__name__) 
47 48 49 -class RepoRpmBuilder(object):
50 51 RPM_NAME_FORMAT = "copr-repo-{}-{}-{}-{}-1-1.noarch.rpm" 52 SPEC_NAME = "copr-repo-package.spec" 53
54 - def __init__(self, user, copr, chroot, topdir=RPMBUILD, packagesdir=PACKAGES_DIR):
55 self.user = user # Name of the user 56 self.copr = copr # Name of the copr 57 self.chroot = chroot # MockChroot object 58 self.topdir = topdir # rpmbuild directory (default $HOME/rpmbuild) 59 self.packagesdir = packagesdir # Directory where to store the rpm packages
60 61 @property
62 - def rpm_name(self):
63 version = self.chroot.os_version 64 # All Fedora releases except for rawhide has same .repo file 65 if self.chroot.os_release == "fedora" and self.chroot.os_version.isdigit(): 66 version = "all" 67 return self.RPM_NAME_FORMAT.format(self.user, self.copr, self.chroot.os_release, version)
68 69 @property
70 - def repo_name(self):
71 return "{}-{}-{}-{}.repo"\ 72 .format(self.user, self.copr, self.chroot.os_release, self.chroot.os_version)
73
74 - def has_repo_package(self):
75 return os.path.isfile(os.path.join(self.packagesdir, self.rpm_name))
76
77 - def get_repofile(self):
78 api = "coprs/{}/{}/repo/{}/{}".format(self.user, self.copr, self.chroot.name_release, self.repo_name) 79 url = urljoin(FRONTEND_URL, api) 80 r = requests.get(url) 81 if r.status_code != 200: 82 raise RuntimeError("Can't get {}".format(url)) 83 return r.content
84
85 - def generate_repo_package(self):
86 87 shutil.copyfile(os.path.join(FRONTEND_DIR, "coprs/templates/coprs/", self.SPEC_NAME), 88 os.path.join(self.topdir, "SPECS", self.SPEC_NAME)) 89 90 with open(os.path.join(self.topdir, "SOURCES", self.repo_name), "w") as f: 91 f.writelines(self.get_repofile()) 92 93 defines = [ 94 "-D", "_topdir {}".format(self.topdir), 95 "-D", "_rpmdir {}".format(self.packagesdir), 96 "-D", "_rpmfilename {}".format(self.rpm_name), 97 "-D", "pkg_name {}".format("copr-repo-{}-{}".format(self.user, self.copr)), 98 "-D", "pkg_version {}".format(VERSION), 99 "-D", "pkg_release {}".format(RELEASE), 100 "-D", "user {}".format(self.user), 101 "-D", "copr {}".format(self.copr), 102 "-D", "chroot {}".format("{}-{}".format(self.chroot.os_release, self.chroot.os_version)), 103 "-D", "repofile {}".format("_copr_{}-{}.repo".format(self.user, self.copr)), 104 ] 105 106 command = ["rpmbuild", "-ba"] + defines + [os.path.join(self.topdir, "SPECS", self.SPEC_NAME)] 107 process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 108 out, err = process.communicate() 109 110 if process.returncode != 0: 111 raise RuntimeError("Failed rpmbuild for: {}\n{}".format(self.repo_name, err))
112
113 114 # ---------------------------------------------------------------------------------------------------------------------- 115 116 117 -def all_coprs():
118 return CoprsLogic.get_all()
119
120 121 # ---------------------------------------------------------------------------------------------------------------------- 122 123 -def prepare_rpmbuild_directory():
124 dirs = ["BUILD", "RPMS", "SOURCES", "SPECS", "SRPMS"] 125 for d in dirs: 126 d = os.path.join(RPMBUILD, d) 127 if not os.path.exists(d): 128 os.makedirs(d)
129
130 131 -def prepare_packages_directory():
132 if not os.path.exists(PACKAGES_DIR): 133 os.makedirs(PACKAGES_DIR)
134
135 136 -def unique_chroots(copr):
137 d = {} 138 for chroot in copr.active_chroots: 139 d[chroot.name_release] = chroot 140 return d.values()
141
142 143 -def main():
144 prepare_rpmbuild_directory() 145 prepare_packages_directory() 146 147 for copr in all_coprs(): 148 for chroot in unique_chroots(copr): 149 builder = RepoRpmBuilder(user=copr.user.name, copr=copr.name, chroot=chroot) 150 151 if builder.has_repo_package(): 152 log.info("Skipping {}".format(builder.repo_name)) 153 continue 154 155 try: 156 builder.generate_repo_package() 157 log.info("Created RPM package for: {}".format(builder.repo_name)) 158 159 except RuntimeError as e: 160 log.error(e.message)
161 162 163 if __name__ == "__main__": 164 try: 165 logging.getLogger("requests").setLevel(logging.WARNING) 166 logging.basicConfig( 167 filename=LOG_FILE, 168 format='[%(asctime)s][%(levelname)6s]: %(message)s', 169 level=logging.INFO) 170 main() 171 except KeyboardInterrupt: 172 pass 173