1
1
# -*- coding: utf-8 -*-
2
2
3
+ import re
4
+
3
5
import flask
4
6
5
7
from docker_registry .core import compat
13
15
14
16
from .app import app # noqa
15
17
18
+ RE_USER_AGENT = re .compile ('([^\s/]+)/([^\s/]+)' )
16
19
17
20
store = storage .load ()
18
21
@@ -51,7 +54,7 @@ def put_username(username):
51
54
return toolkit .response ('' , 204 )
52
55
53
56
54
- def update_index_images (namespace , repository , data_arg ):
57
+ def update_index_images (namespace , repository , data_arg , arch , os ):
55
58
path = store .index_images_path (namespace , repository )
56
59
sender = flask .current_app ._get_current_object ()
57
60
try :
@@ -70,13 +73,20 @@ def update_index_images(namespace, repository, data_arg):
70
73
data = images .values ()
71
74
# Note(dmp): unicode patch
72
75
store .put_json (path , data )
76
+
77
+ # Get image arch and os from the json property
78
+ img_data = store .get_content (store .image_json_path (data [0 ]['id' ]))
79
+ arch = json .loads (img_data )['architecture' ]
80
+ os = json .loads (img_data )['os' ]
81
+
73
82
signals .repository_updated .send (
74
- sender , namespace = namespace , repository = repository , value = data )
83
+ sender , namespace = namespace , repository = repository ,
84
+ value = data , arch = arch , os = os )
75
85
except exceptions .FileNotFoundError :
76
86
signals .repository_created .send (
77
87
sender , namespace = namespace , repository = repository ,
78
88
# Note(dmp): unicode patch
79
- value = json .loads (data_arg .decode ('utf8' )))
89
+ value = json .loads (data_arg .decode ('utf8' )), arch = arch , os = os )
80
90
store .put_content (path , data_arg )
81
91
82
92
@@ -88,14 +98,25 @@ def update_index_images(namespace, repository, data_arg):
88
98
@toolkit .requires_auth
89
99
def put_repository (namespace , repository , images = False ):
90
100
data = None
101
+ # Default arch/os are amd64/linux
102
+ arch = 'amd64'
103
+ os = 'linux'
104
+ # If caller is docker host, retrieve arch/os from user agent
105
+ user_agent = flask .request .headers .get ('user-agent' , '' )
106
+ ua = dict (RE_USER_AGENT .findall (user_agent ))
107
+ if 'arch' in ua :
108
+ arch = ua ['arch' ]
109
+ if 'os' in ua :
110
+ os = ua ['os' ]
111
+
91
112
try :
92
113
# Note(dmp): unicode patch
93
114
data = json .loads (flask .request .data .decode ('utf8' ))
94
115
except ValueError :
95
116
return toolkit .api_error ('Error Decoding JSON' , 400 )
96
117
if not isinstance (data , list ):
97
118
return toolkit .api_error ('Invalid data' )
98
- update_index_images (namespace , repository , flask .request .data )
119
+ update_index_images (namespace , repository , flask .request .data , arch , os )
99
120
headers = generate_headers (namespace , repository , 'write' )
100
121
code = 204 if images is True else 200
101
122
return toolkit .response ('' , code , headers )
@@ -107,9 +128,28 @@ def put_repository(namespace, repository, images=False):
107
128
@mirroring .source_lookup (index_route = True )
108
129
def get_repository_images (namespace , repository ):
109
130
data = None
131
+ # Default arch/os are amd64/linux
132
+ arch = 'amd64'
133
+ os = 'linux'
134
+ # If caller is docker host, retrieve arch/os from user agent
135
+ user_agent = flask .request .headers .get ('user-agent' , '' )
136
+ ua = dict (RE_USER_AGENT .findall (user_agent ))
137
+ if 'arch' in ua :
138
+ arch = ua ['arch' ]
139
+ if 'os' in ua :
140
+ os = ua ['os' ]
141
+
110
142
try :
111
143
path = store .index_images_path (namespace , repository )
112
- data = store .get_content (path )
144
+ json_data = store .get_json (path )
145
+ img_data = store .get_content (store .image_json_path (json_data [0 ]['id' ]))
146
+ # Get image arch and os from the json property
147
+ img_arch = json .loads (img_data )['architecture' ]
148
+ img_os = json .loads (img_data )['os' ]
149
+ if arch != img_arch or os != img_os :
150
+ return toolkit .api_error ('images not found for arch/os pair' , 404 )
151
+ else :
152
+ data = store .get_content (path )
113
153
except exceptions .FileNotFoundError :
114
154
return toolkit .api_error ('images not found' , 404 )
115
155
headers = generate_headers (namespace , repository , 'read' )
0 commit comments