Skip to content

Commit c7251a7

Browse files
author
Gabriel Monroy
committed
spaces > tabs
1 parent ae23502 commit c7251a7

1 file changed

Lines changed: 121 additions & 121 deletions

File tree

api/docker.py

Lines changed: 121 additions & 121 deletions
Original file line numberDiff line numberDiff line change
@@ -10,174 +10,174 @@
1010

1111

1212
def publish_release(repository_path, config, tag):
13-
"""
14-
Publish a new release as a Docker image
15-
16-
Given a source repository path, a dictionary of environment variables
17-
and a target tag, create a new lightweight Docker image on the registry.
18-
19-
For example, publish_release('gabrtv/myapp', {'ENVVAR': 'values'}, 'v23')
20-
results in a new Docker image at: <registry_url>/gabrtv/myapp:v23
21-
which contains the new configuration as ENV entries.
22-
"""
23-
image_id = _get_tag(repository_path, 'latest')
24-
image = _get_image(image_id)
25-
# construct the new image
26-
image['parent'] = image['id']
27-
image['id'] = _new_id()
28-
image['config']['Env'] = _construct_env(image['config']['Env'], config)
29-
# update and tag the new image
30-
_put_image(image)
31-
cookies = _put_layer(image['id'], _empty_tar_archive())
32-
_put_checksum(image, cookies)
33-
_put_tag(image['id'], repository_path, tag)
13+
"""
14+
Publish a new release as a Docker image
15+
16+
Given a source repository path, a dictionary of environment variables
17+
and a target tag, create a new lightweight Docker image on the registry.
18+
19+
For example, publish_release('gabrtv/myapp', {'ENVVAR': 'values'}, 'v23')
20+
results in a new Docker image at: <registry_url>/gabrtv/myapp:v23
21+
which contains the new configuration as ENV entries.
22+
"""
23+
image_id = _get_tag(repository_path, 'latest')
24+
image = _get_image(image_id)
25+
# construct the new image
26+
image['parent'] = image['id']
27+
image['id'] = _new_id()
28+
image['config']['Env'] = _construct_env(image['config']['Env'], config)
29+
# update and tag the new image
30+
_put_image(image)
31+
cookies = _put_layer(image['id'], _empty_tar_archive())
32+
_put_checksum(image, cookies)
33+
_put_tag(image['id'], repository_path, tag)
3434

3535

3636
# registry access
3737

3838

3939
def _get_tag(repository, tag):
40-
path = "/v1/repositories/{repository}/tags/{tag}".format(**locals())
41-
url = urlparse.urljoin(settings.REGISTRY_URL, path)
42-
r = requests.get(url)
43-
if not r.status_code == 200:
44-
raise RuntimeError("GET Image Error ({}: {})".format(r.status_code, r.text))
45-
print r.text
46-
return r.json()
40+
path = "/v1/repositories/{repository}/tags/{tag}".format(**locals())
41+
url = urlparse.urljoin(settings.REGISTRY_URL, path)
42+
r = requests.get(url)
43+
if not r.status_code == 200:
44+
raise RuntimeError("GET Image Error ({}: {})".format(r.status_code, r.text))
45+
print r.text
46+
return r.json()
4747

4848

4949
def _get_image(image_id):
50-
path = "/v1/images/{image_id}/json".format(**locals())
51-
url = urlparse.urljoin(settings.REGISTRY_URL, path)
52-
r = requests.get(url)
53-
if not r.status_code == 200:
54-
raise RuntimeError("GET Image Error ({}: {})".format(r.status_code, r.text))
55-
return r.json()
50+
path = "/v1/images/{image_id}/json".format(**locals())
51+
url = urlparse.urljoin(settings.REGISTRY_URL, path)
52+
r = requests.get(url)
53+
if not r.status_code == 200:
54+
raise RuntimeError("GET Image Error ({}: {})".format(r.status_code, r.text))
55+
return r.json()
5656

5757

5858
def _put_image(image):
59-
path = "/v1/images/{id}/json".format(**image)
60-
url = urlparse.urljoin(settings.REGISTRY_URL, path)
61-
r = requests.put(url, data=json.dumps(image))
62-
if not r.status_code == 200:
63-
raise RuntimeError("PUT Image Error ({}: {})".format(r.status_code, r.text))
64-
return r.json()
59+
path = "/v1/images/{id}/json".format(**image)
60+
url = urlparse.urljoin(settings.REGISTRY_URL, path)
61+
r = requests.put(url, data=json.dumps(image))
62+
if not r.status_code == 200:
63+
raise RuntimeError("PUT Image Error ({}: {})".format(r.status_code, r.text))
64+
return r.json()
6565

6666

6767
def _put_layer(image_id, layer_fileobj):
68-
path = "/v1/images/{image_id}/layer".format(**locals())
69-
url = urlparse.urljoin(settings.REGISTRY_URL, path)
70-
r = requests.put(url, data=layer_fileobj.read())
71-
if not r.status_code == 200:
72-
raise RuntimeError("PUT Layer Error ({}: {})".format(r.status_code, r.text))
73-
return r.cookies
68+
path = "/v1/images/{image_id}/layer".format(**locals())
69+
url = urlparse.urljoin(settings.REGISTRY_URL, path)
70+
r = requests.put(url, data=layer_fileobj.read())
71+
if not r.status_code == 200:
72+
raise RuntimeError("PUT Layer Error ({}: {})".format(r.status_code, r.text))
73+
return r.cookies
7474

7575

7676
def _put_checksum(image, cookies):
77-
path = "/v1/images/{id}/checksum".format(**image)
78-
url = urlparse.urljoin(settings.REGISTRY_URL, path)
79-
tarsum = TarSum(json.dumps(image)).compute()
80-
headers = {'X-Docker-Checksum': tarsum}
81-
r = requests.put(url, headers=headers, cookies=cookies)
82-
if not r.status_code == 200:
83-
raise RuntimeError("PUT Checksum Error ({}: {})".format(r.status_code, r.text))
84-
print r.json()
77+
path = "/v1/images/{id}/checksum".format(**image)
78+
url = urlparse.urljoin(settings.REGISTRY_URL, path)
79+
tarsum = TarSum(json.dumps(image)).compute()
80+
headers = {'X-Docker-Checksum': tarsum}
81+
r = requests.put(url, headers=headers, cookies=cookies)
82+
if not r.status_code == 200:
83+
raise RuntimeError("PUT Checksum Error ({}: {})".format(r.status_code, r.text))
84+
print r.json()
8585

8686

8787
def _put_tag(image_id, repository_path, tag):
88-
path = "/v1/repositories/{repository_path}/tags/{tag}".format(**locals())
89-
url = urlparse.urljoin(settings.REGISTRY_URL, path)
90-
r = requests.put(url, data=json.dumps(image_id))
91-
if not r.status_code == 200:
92-
raise RuntimeError("PUT Tag Error ({}: {})".format(r.status_code, r.text))
93-
print r.json()
88+
path = "/v1/repositories/{repository_path}/tags/{tag}".format(**locals())
89+
url = urlparse.urljoin(settings.REGISTRY_URL, path)
90+
r = requests.put(url, data=json.dumps(image_id))
91+
if not r.status_code == 200:
92+
raise RuntimeError("PUT Tag Error ({}: {})".format(r.status_code, r.text))
93+
print r.json()
9494

9595

9696
# utility functions
9797

9898

9999
def _construct_env(env, config):
100-
"Update current environment with latest config"
101-
new_env = []
102-
# see if we need to update existing ENV vars
103-
for e in env:
104-
k, v = e.split('=', 1)
105-
if k in config:
106-
# update values defined by config
107-
v = config.pop(k)
108-
new_env.append("{}={}".format(k, v))
109-
# add other config ENV items
110-
for k, v in config.items():
111-
new_env.append("{}={}".format(k, v))
112-
return new_env
100+
"Update current environment with latest config"
101+
new_env = []
102+
# see if we need to update existing ENV vars
103+
for e in env:
104+
k, v = e.split('=', 1)
105+
if k in config:
106+
# update values defined by config
107+
v = config.pop(k)
108+
new_env.append("{}={}".format(k, v))
109+
# add other config ENV items
110+
for k, v in config.items():
111+
new_env.append("{}={}".format(k, v))
112+
return new_env
113113

114114

115115
def _new_id():
116-
"Return 64-char UUID for use as Image ID"
117-
return ''.join(uuid.uuid4().hex * 2)
116+
"Return 64-char UUID for use as Image ID"
117+
return ''.join(uuid.uuid4().hex * 2)
118118

119119

120120
def _empty_tar_archive():
121-
"Return an empty tar archive (in memory)"
122-
data = cStringIO.StringIO()
123-
tar = tarfile.open(mode="w", fileobj=data)
124-
tar.close()
125-
data.seek(0)
126-
return data
121+
"Return an empty tar archive (in memory)"
122+
data = cStringIO.StringIO()
123+
tar = tarfile.open(mode="w", fileobj=data)
124+
tar.close()
125+
data.seek(0)
126+
return data
127127

128128

129129
#
130130
# Below adapted from https://github.com/dotcloud/docker-registry/blob/master/lib/checksums.py
131131
#
132132

133133
def sha256_file(fp, data=None):
134-
h = hashlib.sha256(data or '')
135-
if not fp:
136-
return h.hexdigest()
137-
while True:
138-
buf = fp.read(4096)
139-
if not buf:
140-
break
141-
h.update(buf)
142-
return h.hexdigest()
134+
h = hashlib.sha256(data or '')
135+
if not fp:
136+
return h.hexdigest()
137+
while True:
138+
buf = fp.read(4096)
139+
if not buf:
140+
break
141+
h.update(buf)
142+
return h.hexdigest()
143143

144144

145145
def sha256_string(s):
146-
return hashlib.sha256(s).hexdigest()
146+
return hashlib.sha256(s).hexdigest()
147147

148148

149149
class TarSum(object):
150150

151-
def __init__(self, json_data):
152-
self.json_data = json_data
153-
self.hashes = []
154-
self.header_fields = ('name', 'mode', 'uid', 'gid', 'size', 'mtime',
151+
def __init__(self, json_data):
152+
self.json_data = json_data
153+
self.hashes = []
154+
self.header_fields = ('name', 'mode', 'uid', 'gid', 'size', 'mtime',
155155
'type', 'linkname', 'uname', 'gname', 'devmajor',
156156
'devminor')
157157

158-
def append(self, member, tarobj):
159-
header = ''
160-
for field in self.header_fields:
161-
value = getattr(member, field)
162-
if field == 'type':
163-
field = 'typeflag'
164-
elif field == 'name':
165-
if member.isdir() and not value.endswith('/'):
166-
value += '/'
167-
header += '{0}{1}'.format(field, value)
168-
h = None
169-
try:
170-
if member.size > 0:
171-
f = tarobj.extractfile(member)
172-
h = sha256_file(f, header)
173-
else:
174-
h = sha256_string(header)
175-
except KeyError:
176-
h = sha256_string(header)
177-
self.hashes.append(h)
178-
179-
def compute(self):
180-
self.hashes.sort()
181-
data = self.json_data + ''.join(self.hashes)
182-
tarsum = 'tarsum+sha256:{0}'.format(sha256_string(data))
183-
return tarsum
158+
def append(self, member, tarobj):
159+
header = ''
160+
for field in self.header_fields:
161+
value = getattr(member, field)
162+
if field == 'type':
163+
field = 'typeflag'
164+
elif field == 'name':
165+
if member.isdir() and not value.endswith('/'):
166+
value += '/'
167+
header += '{0}{1}'.format(field, value)
168+
h = None
169+
try:
170+
if member.size > 0:
171+
f = tarobj.extractfile(member)
172+
h = sha256_file(f, header)
173+
else:
174+
h = sha256_string(header)
175+
except KeyError:
176+
h = sha256_string(header)
177+
self.hashes.append(h)
178+
179+
def compute(self):
180+
self.hashes.sort()
181+
data = self.json_data + ''.join(self.hashes)
182+
tarsum = 'tarsum+sha256:{0}'.format(sha256_string(data))
183+
return tarsum

0 commit comments

Comments
 (0)