1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
|
import base64
import httplib
import socket
import sys
import traceback
import urllib
import urllib2
from xml.dom.minidom import parseString
from mozharness.base.log import FATAL
class BouncerSubmitterMixin(object):
def query_credentials(self):
if self.credentials:
return self.credentials
global_dict = {}
local_dict = {}
execfile(self.config["credentials_file"], global_dict, local_dict)
self.credentials = (local_dict["tuxedoUsername"],
local_dict["tuxedoPassword"])
return self.credentials
def api_call(self, route, data, error_level=FATAL, retry_config=None):
retry_args = dict(
failure_status=None,
retry_exceptions=(urllib2.HTTPError, urllib2.URLError,
httplib.BadStatusLine,
socket.timeout, socket.error),
error_message="call to %s failed" % (route),
error_level=error_level,
)
if retry_config:
retry_args.update(retry_config)
return self.retry(
self._api_call,
args=(route, data),
**retry_args
)
def _api_call(self, route, data):
api_prefix = self.config["bouncer-api-prefix"]
api_url = "%s/%s" % (api_prefix, route)
request = urllib2.Request(api_url)
if data:
post_data = urllib.urlencode(data, doseq=True)
request.add_data(post_data)
self.info("POST data: %s" % post_data)
credentials = self.query_credentials()
if credentials:
auth = base64.encodestring('%s:%s' % credentials)
request.add_header("Authorization", "Basic %s" % auth.strip())
try:
self.info("Submitting to %s" % api_url)
res = urllib2.urlopen(request, timeout=60).read()
self.info("Server response")
self.info(res)
return res
except urllib2.HTTPError as e:
self.warning("Cannot access %s" % api_url)
traceback.print_exc(file=sys.stdout)
self.warning("Returned page source:")
self.warning(e.read())
raise
except urllib2.URLError:
traceback.print_exc(file=sys.stdout)
self.warning("Cannot access %s" % api_url)
raise
except socket.timeout as e:
self.warning("Timed out accessing %s: %s" % (api_url, e))
raise
except socket.error as e:
self.warning("Socket error when accessing %s: %s" % (api_url, e))
raise
except httplib.BadStatusLine as e:
self.warning('BadStatusLine accessing %s: %s' % (api_url, e))
raise
def product_exists(self, product_name):
self.info("Checking if %s already exists" % product_name)
res = self.api_call("product_show?product=%s" %
urllib.quote(product_name), data=None)
try:
xml = parseString(res)
# API returns <products/> if the product doesn't exist
products_found = len(xml.getElementsByTagName("product"))
self.info("Products found: %s" % products_found)
return bool(products_found)
except Exception as e:
self.warning("Error parsing XML: %s" % e)
self.warning("Assuming %s does not exist" % product_name)
# ignore XML parsing errors
return False
def api_add_product(self, product_name, add_locales, ssl_only=False):
data = {
"product": product_name,
}
if self.locales and add_locales:
data["languages"] = self.locales
if ssl_only:
# Send "true" as a string
data["ssl_only"] = "true"
self.api_call("product_add/", data)
def api_add_location(self, product_name, bouncer_platform, path):
data = {
"product": product_name,
"os": bouncer_platform,
"path": path,
}
self.api_call("location_add/", data)
|