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