1
2
3 """
4 Function actually doing the work of calling the API and handling the
5 output.
6 """
7
8 import os
9 import sys
10 import time
11 import json
12 import datetime
13 import ConfigParser
14
15 import requests
16
17 import copr_exceptions
18
19
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 %s is unknown.\n" % user['username'])
33 else:
34 sys.stderr.write("Project %s/%s not found.\n" % (user['username'], copr))
35 return
36 try:
37 output = json.loads(req.text)
38 except ValueError:
39 sys.stderr.write("Unknown response from server.\n")
40 return
41 if req.status_code != 200:
42 sys.stderr.write("Something went wrong:\n {0}\n".format(output['error']))
43 return
44 return output
45
47 """ Retrieve the user information from the config file. """
48 config = ConfigParser.ConfigParser()
49 if not config.read(
50 os.path.join(os.path.expanduser('~'), '.config', 'copr')):
51 raise copr_exceptions.CoprCliNoConfException(
52 'No configuration file "~/.config/copr" found. '
53 'See man copr-cli for more information')
54 try:
55 username = config.get('copr-cli', 'username', None)
56 login = config.get('copr-cli', 'login', None)
57 token = config.get('copr-cli', 'token', None)
58 except ConfigParser.Error, err:
59 raise copr_exceptions.CoprCliConfigException(
60 'Bad configuration file: %s' % err)
61 return {'username': username, 'token': token, 'login': login}
62
63
65 """ Retrieve the user information from the config file. """
66 config = ConfigParser.ConfigParser()
67 config.read(
68 os.path.join(os.path.expanduser('~'), '.config', 'copr')
69 )
70
71
72 copr_url = 'https://copr.fedoraproject.org/'
73 if config.has_section('copr-cli') and config.has_option('copr-cli', 'copr_url'):
74 copr_url = config.get('copr-cli', 'copr_url')
75 return '%s/api' % copr_url
76
77
79 """ List all the copr of a user. """
80 user = {}
81 if not username:
82 user = get_user()
83 del(user['token'])
84
85 if username:
86 user['username'] = username
87
88 copr_api_url = get_api_url()
89 url = '{0}/coprs/{1}/'.format(copr_api_url, user['username'])
90
91 req = requests.get(url)
92 output = _get_data(req, user)
93 if output is None:
94 return
95 elif 'repos' in output:
96 if output['repos']:
97 for repo in output['repos']:
98 print 'Name: {0}'.format(repo['name'])
99
100 if 'description' in repo:
101 desc = repo['description']
102 print ' ' * 2, 'Description: {0}'.format(desc)
103
104 if 'yum_repos' in repo:
105 yum_repos = repo['yum_repos']
106 print ' ' * 2, 'Yum repo(s):'
107 for k in sorted(yum_repos.keys()):
108 print ' ' * 4, '{0}: {1}'.format(k, yum_repos[k])
109
110 if 'additional_repos' in repo:
111 add_repos = repo['additional_repos']
112 print ' ' * 2, 'Additional repos: {0}'.format(add_repos)
113
114 if 'instructions' in repo:
115 instructions = repo['instructions']
116 print ' ' * 2, 'Instructions: {0}'.format(instructions)
117 else:
118 print 'No copr retrieved for user: "{0}"'.format(
119 user['username'])
120 else:
121 print 'Un-expected data returned, please report this issue'
122
123
124 -def create(name, chroots=[], description=None, instructions=None,
125 repos=None, initial_pkgs=None):
126 """ Create a new copr. """
127 if chroots is None:
128 print "Error: At least one chroot must be selected"
129 sys.exit(1)
130 user = get_user()
131 copr_api_url = get_api_url()
132 URL = '{0}/coprs/{1}/new/'.format(copr_api_url, user['username'])
133
134 if type(repos) == list():
135 repos = ' '.join(repos)
136
137 if type(initial_pkgs) == list():
138 initial_pkgs = ' '.join(initial_pkgs)
139
140 data = {'name': name,
141 'repos': repos,
142 'initial_pkgs': initial_pkgs,
143 'description': description,
144 'instructions': instructions
145 }
146 for chroot in chroots:
147 data[chroot] = 'y'
148
149 req = requests.post(URL,
150 auth=(user['login'], user['token']),
151 data=data)
152 output = _get_data(req, user)
153 if output is not None:
154 print output['message']
155
157 user = get_user()
158 copr_api_url = get_api_url()
159 URL = '{0}/coprs/build_status/{1}/'.format(
160 copr_api_url,
161 build_id)
162
163 req = requests.get(URL, auth=(user['login'], user['token']))
164 output = _get_data(req, user)
165 if output is None:
166 return (False, 'Error occurred.')
167 elif 'status' in output:
168 return (True, output['status'])
169 else:
170 return (False, output['error'])
171
172
177
178
179 -def build(copr, pkgs, memory, timeout, wait=True):
180 """ Build a new package into a given copr. """
181 user = get_user()
182 copr_api_url = get_api_url()
183 URL = '{0}/coprs/{1}/{2}/new_build/'.format(
184 copr_api_url,
185 user['username'],
186 copr)
187
188 data = {'pkgs': ' '.join(pkgs),
189 'memory': memory,
190 'timeout': timeout
191 }
192
193 req = requests.post(URL,
194 auth=(user['login'], user['token']),
195 data=data)
196 output = _get_data(req, user, copr)
197 if output is None:
198 return
199 else:
200 print output['message']
201
202 if wait:
203 print("Build ID: {0}".format(output['id']))
204 print("Watching build (this may be safely interrupted)...")
205 prevstatus = None
206 try:
207 while True:
208 (ret, status) = _fetch_status(output['id'])
209 if not ret:
210 print("Unable to get build status: {0}".format(status))
211 return False
212
213 now = datetime.datetime.now()
214 if prevstatus != status:
215 print("{0} {1}".format(now.strftime('%H:%M:%S'), status))
216 prevstatus = status
217
218 if status in ['succeeded', 'failed']:
219 return True
220
221 time.sleep(60)
222
223 except KeyboardInterrupt:
224 pass
225
226 return True
227