1
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
51
52
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
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
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
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
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
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
206 """ Return status of build """
207 (ret, value) = _fetch_status(build_id)
208 print(value)
209
211 """ Cancel specified build_id """
212 user = get_user()
213 copr_api_url = get_api_url()
214
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
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