]> git.ipfire.org Git - people/ms/pakfire.git/blame - python/pakfire/client/base.py
Use the HTTP proxy for HTTPS as well.
[people/ms/pakfire.git] / python / pakfire / client / base.py
CommitLineData
c62d93f1
MT
1#!/usr/bin/python
2
3from __future__ import division
4
5import os
6import socket
7import urlparse
8import xmlrpclib
9
10import pakfire.util
11import pakfire.packages as packages
12from pakfire.system import system
13
14# Local modules.
15import transport
16
17from pakfire.constants import *
38ba21f9 18from pakfire.i18n import _
c62d93f1
MT
19
20import logging
21log = logging.getLogger("pakfire.client")
22
23class PakfireClient(object):
24 type = None
25
26 def __init__(self, server, username, password):
27 self.url = self._join_url(server, username, password)
28
29 # Create a secure XMLRPC connection to the server.
30 self.conn = transport.Connection(self.url)
31
32 def _join_url(self, server, username, password):
33 """
34 Construct a right URL out of the given
35 server, username and password.
36
37 Basicly this just adds the credentials
38 to the URL.
39 """
40 assert self.type
41
42 # Parse the given URL.
43 url = urlparse.urlparse(server)
44 assert url.scheme in ("http", "https")
45
46 # Build new URL.
47 ret = "%s://" % url.scheme
48
49 # Add credentials if provided.
50 if username and password:
51 ret += "%s:%s@" % (username, password)
52
53 # Add host and path components.
0f882359 54 ret += "/".join((url.netloc, self.type))
c62d93f1
MT
55
56 return ret
57
58 ### Misc. actions
59
60 def noop(self):
61 """
62 No operation. Just to check if the connection is
63 working. Returns a random number.
64 """
65 return self.conn.noop()
66
37ff3f8f
MT
67 def test_code(self, error_code):
68 assert error_code >= 100 and error_code <= 999
69
70 return self.conn.test_code(error_code)
71
c62d93f1
MT
72 def get_my_address(self):
73 """
74 Get my own address (as seen by the hub).
75 """
76 return self.conn.get_my_address()
77
78 def get_hub_status(self):
79 """
80 Get some status information about the hub.
81 """
82 return self.conn.get_hub_status()
83
84
85class BuildMixin(object):
86 ### Build actions
87
88 def build_create(self, filename, arches=None, distro=None):
89 """
90 Create a new build on the hub.
91 """
92
93 # Upload the source file to the server.
94 upload_id = self._upload_file(filename)
95
96 # Then create the build.
97 build = self.conn.build_create(upload_id, distro, arches)
98
99 print build
100
101 def _upload_file(self, filename):
102 # Get the hash of the file.
103 hash = pakfire.util.calc_hash1(filename)
104
105 # Get the size of the file.
106 size = os.path.getsize(filename)
107
108 # Get an upload ID from the server.
109 upload_id = self.conn.upload_create(os.path.basename(filename),
110 size, hash)
111
38ba21f9
MT
112 # Make a nice progressbar.
113 pb = pakfire.util.make_progress(os.path.basename(filename), size, speed=True, eta=True)
114
c62d93f1
MT
115 try:
116 # Calculate the number of chunks.
117 chunks = (size // CHUNK_SIZE) + 1
38ba21f9 118 transferred = 0
c62d93f1
MT
119
120 # Cut the file in pieces and upload them one after another.
121 with open(filename) as f:
122 chunk = 0
123 while True:
124 data = f.read(CHUNK_SIZE)
125 if not data:
126 break
127
128 chunk += 1
38ba21f9
MT
129 if pb:
130 transferred += len(data)
131 pb.update(transferred)
c62d93f1
MT
132
133 data = xmlrpclib.Binary(data)
134 self.conn.upload_chunk(upload_id, data)
135
136 # Tell the server, that we finished the upload.
137 ret = self.conn.upload_finished(upload_id)
138
139 except:
140 # If anything goes wrong, try to delete the upload and raise
141 # the exception.
142 self.conn.upload_remove(upload_id)
143
144 raise
145
38ba21f9
MT
146 finally:
147 if pb:
148 pb.finish()
149
c62d93f1
MT
150 # If the server sends false, something happened with the upload that
151 # could not be recovered.
38ba21f9 152 if not ret:
c62d93f1
MT
153 logging.error("Upload of %s was not successful." % filename)
154 raise Exception, "Upload failed."
155
156 return upload_id
157
158
159class PakfireUserClient(BuildMixin, PakfireClient):
160 type = "user"
161
162 def check_auth(self):
163 """
164 Check if the user was successfully authenticated.
165 """
166 return self.conn.check_auth()
167
168 def get_user_profile(self):
169 """
170 Get information about the user profile.
171 """
172 return self.conn.get_user_profile()
173
25a98632
MT
174 def get_builds(self, type=None, limit=10, offset=0):
175 return self.conn.get_builds(type=type, limit=limit, offset=offset)
176
177 def get_build(self, build_id):
178 return self.conn.get_build(build_id)
179
180 def get_builder(self, builder_id):
181 return self.conn.get_builder(builder_id)
182
183 def get_job(self, job_id):
184 return self.conn.get_job(job_id)
185
186 def get_latest_jobs(self):
187 return self.conn.get_latest_jobs()
188
189 def get_active_jobs(self):
190 return self.conn.get_active_jobs()
191
c62d93f1
MT
192
193class PakfireBuilderClient(BuildMixin, PakfireClient):
194 type = "builder"
195
96ccd5d5 196 def send_keepalive(self, force=False, overload=None, free_space=None):
c62d93f1
MT
197 """
198 Sends a little keepalive to the server and
199 updates the hardware information if the server
200 requests it.
201 """
202 log.debug("Sending keepalive to the hub.")
203
204 # Collect the current loadavg and send it to the hub.
205 loadavg = ", ".join(("%.2f" % round(l, 2) for l in os.getloadavg()))
206
e3eb9333
MT
207 try:
208 needs_update = self.conn.send_keepalive(loadavg, overload, free_space)
209
210 except XMLRPCInternalServerError:
211 # If the keepalive message could not successfully be sent, we don't
212 # bother, because the client will soon retry.
213 log.warning(_("Could not send a keepalive message to the hub."))
214
215 return
c62d93f1 216
96ccd5d5 217 if force or needs_update:
c62d93f1
MT
218 log.debug("The hub is requesting an update.")
219 self.send_update()
220
221 def send_update(self):
222 log.info("Sending host information update to hub...")
223
2dbaea05
MT
224 config = pakfire.config.ConfigDaemon()
225
e3eb9333
MT
226 try:
227 self.conn.send_update(
228 # Supported architectures.
229 system.supported_arches,
230
231 # CPU information.
232 system.cpu_model,
233 system.cpu_count,
234
235 # Amount of memory in bytes.
236 system.memory / 1024,
c62d93f1 237
e3eb9333
MT
238 # Send the currently running version of Pakfire.
239 PAKFIRE_VERSION,
c62d93f1 240
e3eb9333
MT
241 # Send the host key.
242 config.get("signatures", "host_key", None),
243 )
fc69babd 244
e3eb9333
MT
245 except XMLRPCInternalServerError:
246 # Don't give a shit either.
247 log.warning(_("Could not update the host information."))
2dbaea05 248
e3eb9333 249 return