9
9
from enum import Enum
10
10
from pathlib import Path
11
11
from tempfile import TemporaryDirectory
12
- from typing import Any , Dict , Iterable , Optional , TypeVar
12
+ from typing import Any , Dict , Iterable , List , Optional , TypeVar
13
13
14
14
import yaml
15
15
from celery import Task
21
21
from django .db .models .base import ModelBase
22
22
from django .utils import timezone
23
23
24
+ from api .utils import deployment_mode_is_production
24
25
from fragalysis .settings import TARGET_LOADER_MEDIA_DIRECTORY
25
26
from scoring .models import SiteObservationGroup
26
27
from viewer .models import (
@@ -179,6 +180,51 @@ def _update_task(self, message: str | list) -> None:
179
180
pass
180
181
181
182
183
+ def _validate_bundle_against_mode (config_yaml : Dict [str , Any ]) -> Optional [str ]:
184
+ """Inspects the meta to ensure it is supported by the MODE this stack is in.
185
+ Mode is (typically) one of DEVELOPER or PRODUCTION.
186
+ """
187
+ assert config_yaml
188
+ if not deployment_mode_is_production ():
189
+ # We're not in production mode - no bundle checks
190
+ return None
191
+
192
+ # PRODUCTION mode (strict)
193
+
194
+ # Initial concern - the 'xca_version'.
195
+ # It must not be 'dirty' and must have a valid 'tag'.
196
+ base_error_msg = "Stack is in PRODUCTION mode - and "
197
+ try :
198
+ xca_version = config_yaml ["xca_version" ]
199
+ except KeyError :
200
+ return f"{ base_error_msg } 'xca_version' is a required configuration property"
201
+
202
+ logger .info ("xca_version: %s" , xca_version )
203
+
204
+ if "dirty" not in xca_version :
205
+ return f"{ base_error_msg } 'xca_version' is missing the 'dirty' property"
206
+ if xca_version ["dirty" ]:
207
+ return f"{ base_error_msg } 'xca_version->dirty' must be False"
208
+
209
+ if "tag" not in xca_version :
210
+ return f"{ base_error_msg } 'xca_version' is missing the 'tag' property"
211
+ xca_version_tag : str = str (xca_version ["tag" ])
212
+ tag_parts : List [str ] = xca_version_tag .split ("." )
213
+ tag_valid : bool = True
214
+ if len (tag_parts ) in {2 , 3 }:
215
+ for tag_part in tag_parts :
216
+ if not tag_part .isdigit ():
217
+ tag_valid = False
218
+ break
219
+ else :
220
+ tag_valid = False
221
+ if not tag_valid :
222
+ return f"{ base_error_msg } 'xca_version->tag' must be 'N.N[.N]'. Got '{ xca_version_tag } '"
223
+
224
+ # OK if we get here
225
+ return None
226
+
227
+
182
228
def _flatten_dict_gen (d : dict , parent_key : tuple | str | int , depth : int ):
183
229
for k , v in d .items ():
184
230
if parent_key :
@@ -1173,10 +1219,19 @@ def process_bundle(self):
1173
1219
msg = "Missing files in uploaded data, aborting"
1174
1220
raise FileNotFoundError (msg )
1175
1221
1222
+ # Validate the upload's XCA version information against any MODE-based conditions.
1223
+ # An error message is returned if the bundle is not supported.
1224
+ if vb_err_msg := _validate_bundle_against_mode (config ):
1225
+ self .report .log (Level .FATAL , vb_err_msg )
1226
+ raise AssertionError (vb_err_msg )
1227
+
1228
+ # Target (very least) is required
1176
1229
try :
1177
1230
self .target_name = config ["target_name" ]
1178
1231
except KeyError as exc :
1179
- raise KeyError ("target_name missing in config file" ) from exc
1232
+ msg = "target_name missing in config file"
1233
+ self .report .log (Level .FATAL , msg )
1234
+ raise KeyError (msg ) from exc
1180
1235
1181
1236
# moved this bit from init
1182
1237
self .target , target_created = Target .objects .get_or_create (
@@ -1199,7 +1254,7 @@ def process_bundle(self):
1199
1254
if self ._is_already_uploaded (target_created , project_created ):
1200
1255
# remove uploaded file
1201
1256
Path (self .bundle_path ).unlink ()
1202
- msg = f"{ self .bundle_name } already uploaded, skipping. "
1257
+ msg = f"{ self .bundle_name } already uploaded"
1203
1258
self .report .final (msg , success = False )
1204
1259
raise FileExistsError (msg )
1205
1260
@@ -1217,7 +1272,7 @@ def process_bundle(self):
1217
1272
self .version_dir = meta ["version_dir" ]
1218
1273
self .previous_version_dirs = meta ["previous_version_dirs" ]
1219
1274
1220
- # check tranformation matrix files
1275
+ # check transformation matrix files
1221
1276
( # pylint: disable=unbalanced-tuple-unpacking
1222
1277
trans_neighbourhood ,
1223
1278
trans_conf_site ,
0 commit comments