Skip to content

Commit 1e066c3

Browse files
author
Travis Clarke
committed
kettle - upgrade py2 -> py3
1 parent 3d091d0 commit 1e066c3

11 files changed

+82
-73
lines changed

kettle/BUILD.bazel

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ py_test(
1111
# https://github.com/bazelbuild/bazel/issues/1973
1212
# https://github.com/bazelbuild/bazel/issues/2056
1313
local = True,
14-
python_version = "PY2",
14+
python_version = "PY3",
1515
deps = [
1616
requirement("certifi"),
1717
requirement("chardet"),
1818
requirement("idna"),
19-
requirement("PyYAML"),
19+
requirement("ruamel.yaml"),
2020
requirement("requests"),
2121
requirement("urllib3"),
2222
],
@@ -28,7 +28,7 @@ py_binary(
2828
"make_db.py",
2929
"model.py",
3030
],
31-
python_version = "PY2",
31+
python_version = "PY3",
3232
)
3333

3434
# TODO(rmmh): re-enable when Bazel is fixed.
@@ -51,7 +51,7 @@ py_test(
5151
"model_test.py",
5252
":package-srcs",
5353
],
54-
python_version = "PY2",
54+
python_version = "PY3",
5555
)
5656

5757
py_test(
@@ -65,12 +65,12 @@ py_test(
6565
"buckets.yaml",
6666
"schema.json",
6767
],
68-
python_version = "PY2",
68+
python_version = "PY3",
6969
deps = [
7070
requirement("certifi"),
7171
requirement("chardet"),
7272
requirement("idna"),
73-
requirement("PyYAML"),
73+
requirement("ruamel.yaml"),
7474
requirement("requests"),
7575
requirement("urllib3"),
7676
],
@@ -87,8 +87,8 @@ py_test(
8787
data = [":buckets.yaml"],
8888
# idem
8989
local = True,
90-
python_version = "PY2",
91-
deps = [requirement("PyYAML")],
90+
python_version = "PY3",
91+
deps = [requirement("ruamel.yaml")],
9292
)
9393

9494
filegroup(

kettle/Dockerfile

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,29 +12,37 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
FROM ubuntu
15+
FROM ubuntu:18.04
16+
17+
ENV KETTLE_DB=/data/build.db
18+
ENV TZ=America/Los_Angeles
19+
20+
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && \
21+
echo $TZ > /etc/timezone
1622

1723
RUN apt-get update && apt-get install -y \
1824
tzdata \
1925
curl \
2026
pv \
2127
time \
2228
sqlite3 \
23-
python-pip \
29+
python \
30+
python3 \
31+
python3-pip \
2432
&& rm -rf /var/lib/apt/lists/*
2533

26-
RUN curl -fsSL https://bitbucket.org/squeaky/portable-pypy/downloads/pypy-5.8-1-linux_x86_64-portable.tar.bz2 | tar xj -C opt
27-
RUN ln -s /opt/pypy*/bin/pypy /usr/bin
28-
29-
ADD requirements.txt /kettle/
30-
RUN pip install -r /kettle/requirements.txt
34+
RUN pip3 install requests google-cloud-pubsub==0.25.0 google-cloud-bigquery==0.24.0 influxdb ruamel.yaml==0.16
3135

32-
RUN curl -o installer https://sdk.cloud.google.com && bash installer --disable-prompts --install-dir=/ && rm installer && ln -s /google-cloud-sdk/bin/* /bin/
36+
RUN curl -fsSL https://bitbucket.org/squeaky/portable-pypy/downloads/pypy3.6-7.1.1-beta-linux_x86_64-portable.tar.bz2 | tar xj -C opt && \
37+
ln -s /opt/pypy*/bin/pypy /usr/bin
3338

34-
ENV KETTLE_DB=/data/build.db
35-
ENV TZ=America/Los_Angeles
39+
RUN curl -o installer https://sdk.cloud.google.com && \
40+
bash installer --disable-prompts --install-dir=/ && \
41+
rm installer && \
42+
ln -s /google-cloud-sdk/bin/* /bin/
3643

3744
ADD *.py schema.json runner.sh buckets.yaml /kettle/
3845

39-
CMD ["/kettle/runner.sh"]
4046
VOLUME ["/data"]
47+
48+
CMD ["/kettle/runner.sh"]

kettle/make_db.py

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
"""Generates a SQLite DB containing test data downloaded from GCS."""
1616

17-
from __future__ import print_function
1817

1918
import argparse
2019
import logging
@@ -24,13 +23,13 @@
2423
import signal
2524
import sys
2625
import time
27-
import urllib2
26+
import urllib.parse
2827
from xml.etree import cElementTree as ET
2928

3029
import multiprocessing
3130
import multiprocessing.pool
3231
import requests
33-
import yaml
32+
import ruamel.yaml as yaml
3433

3534
import model
3635

@@ -41,7 +40,7 @@ def pad_numbers(string):
4140

4241
WORKER_CLIENT = None # used for multiprocessing
4342

44-
class GCSClient(object):
43+
class GCSClient:
4544
def __init__(self, jobs_dir, metadata=None):
4645
self.jobs_dir = jobs_dir
4746
self.metadata = metadata or {}
@@ -55,15 +54,15 @@ def _request(self, path, params, as_json=True):
5554
5655
"""
5756
url = 'https://www.googleapis.com/storage/v1/b/%s' % path
58-
for retry in xrange(23):
57+
for retry in range(23):
5958
try:
6059
resp = self.session.get(url, params=params, stream=False)
6160
if 400 <= resp.status_code < 500 and resp.status_code != 429:
6261
return None
6362
resp.raise_for_status()
6463
if as_json:
6564
return resp.json()
66-
return resp.content
65+
return resp.text
6766
except requests.exceptions.RequestException:
6867
logging.exception('request failed %s', url)
6968
time.sleep(random.random() * min(60, 2 ** retry))
@@ -78,7 +77,7 @@ def _parse_uri(path):
7877
def get(self, path, as_json=False):
7978
"""Get an object from GCS."""
8079
bucket, path = self._parse_uri(path)
81-
return self._request('%s/o/%s' % (bucket, urllib2.quote(path, '')),
80+
return self._request('%s/o/%s' % (bucket, urllib.parse.quote(path, '')),
8281
{'alt': 'media'}, as_json=as_json)
8382

8483
def ls(self, path, dirs=True, files=True, delim=True, item_field='name'):
@@ -140,7 +139,7 @@ def _get_builds(self, job):
140139
except (ValueError, TypeError):
141140
pass
142141
else:
143-
return False, (str(n) for n in xrange(latest_build, 0, -1))
142+
return False, (str(n) for n in range(latest_build, 0, -1))
144143
# Invalid latest-build or bucket is using timestamps
145144
build_paths = self.ls_dirs('%s%s/' % (self.jobs_dir, job))
146145
return True, sorted(
@@ -193,14 +192,16 @@ def mp_init_worker(jobs_dir, metadata, client_class, use_signal=True):
193192
global WORKER_CLIENT # pylint: disable=global-statement
194193
WORKER_CLIENT = client_class(jobs_dir, metadata)
195194

196-
def get_started_finished((job, build)):
195+
def get_started_finished(job_info):
196+
(job, build) = job_info
197197
try:
198198
return WORKER_CLIENT.get_started_finished(job, build)
199199
except:
200200
logging.exception('failed to get tests for %s/%s', job, build)
201201
raise
202202

203-
def get_junits((build_id, gcs_path)):
203+
def get_junits(build_info):
204+
(build_id, gcs_path) = build_info
204205
try:
205206
junits = WORKER_CLIENT.get_junits_from_build(gcs_path)
206207
return build_id, gcs_path, junits
@@ -267,7 +268,7 @@ def remove_system_out(data):
267268
for parent in root.findall('*//system-out/..'):
268269
for child in parent.findall('system-out'):
269270
parent.remove(child)
270-
return ET.tostring(root)
271+
return ET.tostring(root, 'unicode')
271272
except ET.ParseError:
272273
pass
273274
return data
@@ -292,7 +293,7 @@ def download_junit(db, threads, client_class):
292293
for n, (build_id, build_path, junits) in enumerate(test_iterator, 1):
293294
print('%d/%d' % (n, len(builds_to_grab)),
294295
build_path, len(junits), len(''.join(junits.values())))
295-
junits = {k: remove_system_out(v) for k, v in junits.iteritems()}
296+
junits = {k: remove_system_out(v) for k, v in junits.items()}
296297

297298
db.insert_build_junits(build_id, junits)
298299
if n % 100 == 0:
@@ -307,7 +308,7 @@ def main(db, jobs_dirs, threads, get_junit, client_class=GCSClient):
307308
"""Collect test info in matching jobs."""
308309
get_builds(db, 'gs://kubernetes-jenkins/pr-logs', {'pr': True},
309310
threads, client_class)
310-
for bucket, metadata in jobs_dirs.iteritems():
311+
for bucket, metadata in jobs_dirs.items():
311312
if not bucket.endswith('/'):
312313
bucket += '/'
313314
get_builds(db, bucket, metadata, threads, client_class)
@@ -340,6 +341,6 @@ def get_options(argv):
340341
if __name__ == '__main__':
341342
OPTIONS = get_options(sys.argv[1:])
342343
main(model.Database(),
343-
yaml.load(open(OPTIONS.buckets)),
344+
yaml.safe_load(open(OPTIONS.buckets)),
344345
OPTIONS.threads,
345346
OPTIONS.junit)

kettle/make_db_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env python
1+
#!/usr/bin/env python3
22

33
# Copyright 2017 The Kubernetes Authors.
44
#

kettle/make_json.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env python
1+
#!/usr/bin/env python3
22

33
# Copyright 2017 The Kubernetes Authors.
44
#
@@ -81,15 +81,15 @@ def make_result(name, time, failure_text):
8181

8282

8383
def buckets_yaml():
84-
import yaml # does not support pypy
84+
import ruamel.yaml as yaml # does not support pypy
8585
with open(os.path.dirname(os.path.abspath(__file__))+'/buckets.yaml') as fp:
86-
return yaml.load(fp)
86+
return yaml.safe_load(fp)
8787

8888
# pypy compatibility hack
89-
def python_buckets_yaml(python='python2'):
89+
def python_buckets_yaml(python='python3'):
9090
return json.loads(subprocess.check_output(
91-
[python, '-c', 'import json,yaml; print json.dumps(yaml.load(open("buckets.yaml")))'],
92-
cwd=os.path.dirname(os.path.abspath(__file__))))
91+
[python, '-c', 'import json, ruamel.yaml as yaml; print(json.dumps(yaml.safe_load(open("buckets.yaml"))))'],
92+
cwd=os.path.dirname(os.path.abspath(__file__)), encoding='utf-8'))
9393

9494
for attempt in [python_buckets_yaml, buckets_yaml, lambda: python_buckets_yaml(python='python')]:
9595
try:
@@ -105,7 +105,7 @@ def python_buckets_yaml(python='python2'):
105105

106106
def path_to_job_and_number(path):
107107
assert not path.endswith('/')
108-
for bucket, meta in BUCKETS.iteritems():
108+
for bucket, meta in BUCKETS.items():
109109
if path.startswith(bucket):
110110
prefix = meta['prefix']
111111
break
@@ -171,7 +171,7 @@ def get_metadata():
171171
if metadata.get('version') == build_version:
172172
metadata.pop('version')
173173
for key, value in metadata.items():
174-
if not isinstance(value, basestring):
174+
if not isinstance(value, str):
175175
# the schema specifies a string value. force it!
176176
metadata[key] = json.dumps(value)
177177
if not metadata:
@@ -247,9 +247,9 @@ def main(db, opts, outfile):
247247

248248
if rows_emitted:
249249
gen = db.insert_emitted(rows_emitted, incremental_table=incremental_table)
250-
print >>sys.stderr, 'incremental progress gen #%d' % gen
250+
print('incremental progress gen #%d' % gen, file=sys.stderr)
251251
else:
252-
print >>sys.stderr, 'no rows emitted'
252+
print('no rows emitted', file=sys.stderr)
253253
return 0
254254

255255

kettle/make_json_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env python2
1+
#!/usr/bin/env python3
22

33
# Copyright 2017 The Kubernetes Authors.
44
#
@@ -14,7 +14,7 @@
1414
# See the License for the specific language governing permissions and
1515
# limitations under the License.
1616

17-
import cStringIO as StringIO
17+
import io as StringIO
1818
import json
1919
import time
2020
import unittest
@@ -26,7 +26,7 @@
2626
class ValidateBuckets(unittest.TestCase):
2727
def test_buckets(self):
2828
prefixes = set()
29-
for name, options in sorted(make_json.BUCKETS.iteritems()):
29+
for name, options in sorted(make_json.BUCKETS.items()):
3030
if name == 'gs://kubernetes-jenkins/logs/':
3131
continue # only bucket without a prefix
3232
prefix = options.get('prefix', '')

kettle/model.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import zlib
2121

2222

23-
class Database(object):
23+
class Database:
2424
"""
2525
Store build and test result information, and support incremental updates to results.
2626
"""
@@ -103,9 +103,9 @@ def insert_build_junits(self, build_id, junits):
103103
"""
104104
Insert a junit dictionary {gcs_path: contents} for a given build's rowid.
105105
"""
106-
for path, data in junits.iteritems():
106+
for path, data in junits.items():
107107
self.db.execute('replace into file values(?,?)',
108-
(path, buffer(zlib.compress(data, 9))))
108+
(path, memoryview(zlib.compress(data.encode('utf-8'), 9))))
109109
self.db.execute('delete from build_junit_missing where build_id=?', (build_id,))
110110

111111
### make_json
@@ -156,7 +156,7 @@ def test_results_for_build(self, path):
156156
for dataz, in self.db.execute(
157157
'select data from file where path between ? and ?',
158158
(path, path + '\x7F')):
159-
data = zlib.decompress(dataz)
159+
data = zlib.decompress(dataz).decode('utf-8')
160160
if data:
161161
results.append(data)
162162
return results

kettle/model_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
#!/usr/bin/env python2
1+
#!/usr/bin/env python3
22

33
# Copyright 2017 The Kubernetes Authors.
44
#

0 commit comments

Comments
 (0)