Package copr_cli :: Module subcommands
[hide private]
[frames] | no frames]

Source Code for Module copr_cli.subcommands

  1  #-*- coding: UTF-8 -*- 
  2   
  3  """ 
  4  Function actually doing the work of calling the API and handling the 
  5  output. 
  6  """ 
  7   
  8  import ConfigParser 
  9  import datetime 
 10  import json 
 11  import os 
 12  import re 
 13  import requests 
 14  import sys 
 15  import time 
 16   
 17  import copr_exceptions 
 18   
 19   
20 -def _get_data(req, user, copr=None):
21 """ Wrapper around response from server 22 23 checks data and raises a CoprCliRequestException with nice error message 24 or CoprCliUnknownResponseException in case of some some error. 25 Otherwise return json object. 26 """ 27 if "<title>Sign in Coprs</title>" in req.text: 28 raise copr_exceptions.CoprCliRequestException("Invalid API token\n") 29 return 30 31 if req.status_code == 404: 32 if copr is None: 33 raise copr_exceptions.CoprCliRequestException( 34 "User {0} is unknown.\n".format(user["username"])) 35 else: 36 raise copr_exceptions.CoprCliRequestException( 37 "Project {0}/{1} not found.\n".format( 38 user["username"], copr)) 39 try: 40 output = json.loads(req.text) 41 except ValueError: 42 raise copr_exceptions.CoprCliUnknownResponseException( 43 "Unknown response from the server.") 44 if req.status_code != 200: 45 raise copr_exceptions.CoprCliRequestException(output["error"]) 46 47 if output is None: 48 raise copr_exceptions.CoprCliUnknownResponseException( 49 "No response from the server.") 50 return output
51 52
53 -def get_user():
54 """ Retrieve the user information from the config file. """ 55 config = ConfigParser.ConfigParser() 56 if not config.read( 57 os.path.join(os.path.expanduser("~"), ".config", "copr")): 58 raise copr_exceptions.CoprCliNoConfException( 59 "No configuration file '~/.config/copr' found. " 60 "See man copr-cli for more information") 61 try: 62 username = config.get("copr-cli", "username", None) 63 login = config.get("copr-cli", "login", None) 64 token = config.get("copr-cli", "token", None) 65 except ConfigParser.Error as err: 66 raise copr_exceptions.CoprCliConfigException( 67 "Bad configuration file: {0}".format(err)) 68 return {"username": username, "token": token, "login": login}
69 70
71 -def get_api_url():
72 """ Retrieve the user information from the config file. """ 73 config = ConfigParser.ConfigParser() 74 config.read( 75 os.path.join(os.path.expanduser("~"), ".config", "copr") 76 ) 77 78 # Default copr_url: 79 copr_url = "http://copr.fedoraproject.org/" 80 if (config.has_section("copr-cli") and 81 config.has_option("copr-cli", "copr_url")): 82 83 copr_url = config.get("copr-cli", "copr_url") 84 return "{0}/api".format(copr_url)
85 86
87 -def listcoprs(username=None):
88 """ List all the copr of a user. """ 89 user = {} 90 if not username: 91 user = get_user() 92 del(user["token"]) 93 94 if username: 95 user["username"] = username 96 97 copr_api_url = get_api_url() 98 url = "{0}/coprs/{1}/".format(copr_api_url, user["username"]) 99 100 req = requests.get(url) 101 output = _get_data(req, user) 102 if output is None: 103 return 104 elif "repos" in output: 105 PAD = " " * 2 106 if output["repos"]: 107 for repo in output["repos"]: 108 print("Name: {0}".format(repo["name"])) 109 110 if "description" in repo: 111 desc = repo["description"] 112 print(PAD + "Description: {0}".format(desc)) 113 114 if "yum_repos" in repo: 115 yum_repos = repo["yum_repos"] 116 print(PAD + "Yum repo(s):") 117 for k in sorted(yum_repos.keys()): 118 print(PAD * 2 + "{0}: {1}".format(k, yum_repos[k])) 119 120 if "additional_repos" in repo: 121 add_repos = repo["additional_repos"] 122 print(PAD + "Additional repos: {0}".format(add_repos)) 123 124 if "instructions" in repo: 125 instructions = repo["instructions"] 126 print(PAD + "Instructions: {0}".format(instructions)) 127 else: 128 print("No copr retrieved for user: '{0}'".format( 129 user["username"])) 130 else: 131 print("Un-expected data returned, please report this issue")
132 133
134 -def create(name, chroots=[], description=None, instructions=None, 135 repos=None, initial_pkgs=None):
136 """ Create a new copr. """ 137 if chroots is None: 138 raise copr_exceptions.CoprCliRequestException( 139 "At least one chroot must be selected") 140 141 user = get_user() 142 copr_api_url = get_api_url() 143 URL = "{0}/coprs/{1}/new/".format(copr_api_url, user["username"]) 144 145 if type(repos) == list(): 146 repos = " ".join(repos) 147 148 if type(initial_pkgs) == list(): 149 initial_pkgs = " ".join(initial_pkgs) 150 151 data = {"name": name, 152 "repos": repos, 153 "initial_pkgs": initial_pkgs, 154 "description": description, 155 "instructions": instructions 156 } 157 for chroot in chroots: 158 data[chroot] = "y" 159 160 req = requests.post(URL, 161 auth=(user["login"], user["token"]), 162 data=data) 163 output = _get_data(req, user) 164 if output is not None: 165 print(output["message"])
166 167
168 -def delete(copr):
169 """ Delete the entire project. 170 """ 171 user = get_user() 172 username = user["username"] 173 174 copr_api_url = get_api_url() 175 URL = "{0}/coprs/{1}/{2}/delete/".format( 176 copr_api_url, 177 username, 178 copr) 179 180 data = {"verify": "yes"} 181 182 req = requests.post(URL, 183 auth=(user["login"], user["token"]), 184 data=data) 185 output = _get_data(req, user, copr)
186 187
188 -def _fetch_status(build_id):
189 user = get_user() 190 copr_api_url = get_api_url() 191 URL = "{0}/coprs/build_status/{1}/".format( 192 copr_api_url, 193 build_id) 194 195 req = requests.get(URL, auth=(user["login"], user["token"])) 196 output = _get_data(req, user) 197 if output is None: 198 return (False, "Error occurred.") 199 elif "status" in output: 200 return (True, output["status"]) 201 else: 202 return (False, output["error"])
203 204
205 -def status(build_id):
206 """ Return status of build """ 207 (ret, value) = _fetch_status(build_id) 208 print(value)
209
210 -def cancel(build_id):
211 """ Cancel specified build_id """ 212 user = get_user() 213 copr_api_url = get_api_url() 214 #/coprs/rhscl/nodejs010/cancel_build/4060/ 215 URL = "{0}/coprs/cancel_build/{1}/".format( 216 copr_api_url, 217 build_id) 218 req = requests.post(URL, auth=(user["login"], user["token"])) 219 output = _get_data(req, user) 220 if output is None: 221 return (False, "Error occurred.") 222 elif "status" in output: 223 return (True, output["status"]) 224 else: 225 return (False, output["error"])
226
227 -def build(copr, pkgs, memory, timeout, wait=True, result=None, chroots=None):
228 """ Build a new package into a given copr. 229 230 Result is dictionary where is returned "errmsg" in case of error. 231 And "id" and "status" otherwise. 232 """ 233 user = get_user() 234 username = user["username"] 235 236 # if you specify copr as username/foo, retrieve and cut username 237 m = re.match(r"(.+)/(.+)", copr) 238 if m: 239 username = m.group(1) 240 copr = m.group(2) 241 242 copr_api_url = get_api_url() 243 URL = "{0}/coprs/{1}/{2}/new_build/".format( 244 copr_api_url, 245 username, 246 copr) 247 248 data = {"pkgs": " ".join(pkgs), 249 "memory": memory, 250 "timeout": timeout 251 } 252 253 if chroots is not None: 254 for chroot in chroots: 255 data[chroot] = "y" 256 257 req = requests.post(URL, 258 auth=(user["login"], user["token"]), 259 data=data) 260 output = _get_data(req, user, copr) 261 print("{1}:\n {0} build(s) were added successfully\n".format(len(output["ids"]), copr)) 262 263 if wait: 264 print("Watching build(s): (this may be safely interrupted)") 265 prevstatus = {} 266 failed_ids = [] 267 for id in output["ids"]: 268 prevstatus[id] = None 269 if result is not None: 270 result[id] = {} 271 try: 272 while True: 273 for id in output["ids"]: 274 (ret, status) = _fetch_status(id) 275 if not ret: 276 errmsg = " Build {1}: Unable to get build status: {0}".format(status,id) 277 if result is not None: 278 result[id]['errmsg'] = errmsg 279 raise copr_exceptions.CoprCliRequestException(errmsg) 280 281 now = datetime.datetime.now() 282 if prevstatus[id] != status: 283 print(" {0} Build {2}: {1}".format(now.strftime("%H:%M:%S"), status, id)) 284 prevstatus[id] = status 285 286 if status in ["succeeded", "skipped", "failed", "canceled"]: 287 if result is not None: 288 result[id]['status'] = status 289 if status in ["failed"]: 290 failed_ids.append(id) 291 output["ids"].remove(id) 292 293 if status == "unknown": 294 raise copr_exceptions.CoprCliBuildException( 295 "Unknown status.") 296 297 if not output["ids"]: 298 break 299 time.sleep(60) 300 301 if failed_ids: 302 raise copr_exceptions.CoprCliBuildException( 303 "Build(s) {0} failed.".format( 304 ", ".join(str(x) for x in failed_ids))) 305 306 except KeyboardInterrupt: 307 pass
308