Commit 7eb49f16 authored by Georges Racinet's avatar Georges Racinet 🦑
Browse files

Job artifacts: upload and download facilities

upload is attached on Runner instances, while download
is provided on Project instances. In both cases, the
`job` dict is to be passed.

--HG--
branch : stable
parent 4104ff18e9be
......@@ -1172,6 +1172,19 @@ class Project(object):
lambda d: d.find_element_by_xpath(
'//a[contains(@href, "/toggle_group_runners")]')))
def get_job_artifacts(self, job):
"""Return filename, artifacts (archive) as bytes."""
resp = self.owner_api_get(subpath='jobs/%d/artifacts' % job['id'])
assert resp.status_code == 200
# Not fully compliant filename parsing.
# Full specification: RFC 6266.
# there's an unsupported lib on PyPI for this (rfc6266)
m = re.match(r'attachment; filename="(.*?)";',
resp.headers['Content-Disposition'])
assert m is not None
return m.group(1), resp.content
def api_create_mirror(self, **params):
return ProjectMirror.api_create(self, **params)
......
......@@ -5,6 +5,11 @@ from . import (
wait_assert,
)
ARTIFACT_FORMATS = dict(archive='zip',
trace='raw',
metadata='gzip',
)
@attr.s
class Runner:
......@@ -89,6 +94,19 @@ class Runner:
data=dict(token=self.token))
assert resp.status_code == 204
def upload_artifact(self, job, fobj, artifact_type='archive'):
artifact_format = ARTIFACT_FORMATS[artifact_type]
resp = requests.post(
'{base_url}/jobs/{id}/artifacts'.format(
base_url=self.heptapod.api_url,
**job),
params=dict(artifact_format=artifact_format,
artifact_type=artifact_type),
headers={'JOB-TOKEN': job['token']},
files=dict(file=fobj))
assert resp.status_code < 400
return resp.json()
def __enter__(self):
return self
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment