11# -*- coding: utf-8 -*-
22
3+ import re
4+
35import flask
46
57from docker_registry .core import compat
1315
1416from .app import app # noqa
1517
18+ RE_USER_AGENT = re .compile ('([^\s/]+)/([^\s/]+)' )
1619
1720store = storage .load ()
1821
@@ -51,7 +54,7 @@ def put_username(username):
5154 return toolkit .response ('' , 204 )
5255
5356
54- def update_index_images (namespace , repository , data_arg ):
57+ def update_index_images (namespace , repository , data_arg , arch , os ):
5558 path = store .index_images_path (namespace , repository )
5659 sender = flask .current_app ._get_current_object ()
5760 try :
@@ -70,13 +73,20 @@ def update_index_images(namespace, repository, data_arg):
7073 data = images .values ()
7174 # Note(dmp): unicode patch
7275 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+
7382 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 )
7585 except exceptions .FileNotFoundError :
7686 signals .repository_created .send (
7787 sender , namespace = namespace , repository = repository ,
7888 # Note(dmp): unicode patch
79- value = json .loads (data_arg .decode ('utf8' )))
89+ value = json .loads (data_arg .decode ('utf8' )), arch = arch , os = os )
8090 store .put_content (path , data_arg )
8191
8292
@@ -88,14 +98,25 @@ def update_index_images(namespace, repository, data_arg):
8898@toolkit .requires_auth
8999def put_repository (namespace , repository , images = False ):
90100 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+
91112 try :
92113 # Note(dmp): unicode patch
93114 data = json .loads (flask .request .data .decode ('utf8' ))
94115 except ValueError :
95116 return toolkit .api_error ('Error Decoding JSON' , 400 )
96117 if not isinstance (data , list ):
97118 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 )
99120 headers = generate_headers (namespace , repository , 'write' )
100121 code = 204 if images is True else 200
101122 return toolkit .response ('' , code , headers )
@@ -107,9 +128,28 @@ def put_repository(namespace, repository, images=False):
107128@mirroring .source_lookup (index_route = True )
108129def get_repository_images (namespace , repository ):
109130 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+
110142 try :
111143 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 )
113153 except exceptions .FileNotFoundError :
114154 return toolkit .api_error ('images not found' , 404 )
115155 headers = generate_headers (namespace , repository , 'read' )
0 commit comments