Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
38 lines
1.6 KiB
Python
38 lines
1.6 KiB
Python
# SPDX-License-Identifier: MPL-2.0
|
|
"""Describe the dedicated ext4 data file used by a private Sargo installation."""
|
|
import hashlib
|
|
import json
|
|
import re
|
|
import uuid
|
|
from pathlib import Path
|
|
|
|
FEATURES = 'none,has_journal,ext_attr,dir_index,filetype,extent,sparse_super,large_file,uninit_bg,dir_nlink,extra_isize'
|
|
|
|
|
|
def digest(path):
|
|
with Path(path).open('rb') as stream:
|
|
return hashlib.file_digest(stream, 'sha256').hexdigest()
|
|
|
|
|
|
def validate_manifest(path):
|
|
path = Path(path).resolve()
|
|
value = json.loads(path.read_text())
|
|
if value.get('schema') != 1 or value.get('device') != 'sargo':
|
|
raise ValueError('Expected a Sargo data-image manifest')
|
|
identifier = value.get('uuid')
|
|
if not isinstance(identifier, str) or str(uuid.UUID(identifier)) != identifier:
|
|
raise ValueError('Invalid data filesystem UUID')
|
|
if value.get('image') != identifier+'.ext4':
|
|
raise ValueError('Data image filename does not match its UUID')
|
|
size = value.get('bytes')
|
|
if type(size) is not int or not 512*1024**2 <= size <= 8*1024**3 or size % 4096:
|
|
raise ValueError('Invalid data image size')
|
|
for name in ('imageSha256', 'systemImageSha256'):
|
|
if not re.fullmatch('[a-f0-9]{64}', str(value.get(name, ''))):
|
|
raise ValueError('Invalid '+name)
|
|
image = path.parent/value['image']
|
|
if image.is_symlink() or image.stat().st_size != size or digest(image) != value['imageSha256']:
|
|
raise ValueError('Initial data image changed')
|
|
if value.get('filesystemCheckPassed') is not True:
|
|
raise ValueError('Data filesystem has not passed verification')
|
|
return value
|