TeraDurableMediaRoots.swift (2191B)
1 import CryptoKit 2 import Foundation 3 import RadrootsKit 4 5 /// Prepared photos live with application data. Existing temporary copies stay 6 /// untouched and are migrated lazily when an acknowledged reference is opened. 7 enum TeraDurableMediaRoots { 8 static func selectingStaging(in base: RadrootsAppleFileRoots) throws -> RadrootsAppleFileRoots { 9 try RadrootsAppleFileRoots( 10 appIdentifier: base.appIdentifier, dataRoot: base.dataRoot, cacheRoot: base.cacheRoot, 11 temporaryRoot: base.temporaryRoot, logsRoot: base.logsRoot, 12 stagedBlobsRoot: base.dataRoot.appendingPathComponent("staged_blobs", isDirectory: true) 13 ) 14 } 15 16 static func restoreLegacyBlob(_ blob: RadrootsStagedBlobReference, roots: RadrootsAppleFileRoots) throws { 17 let access = RadrootsAppleFileAccess(roots: roots) 18 do { 19 try validate(access.readStagedBlob(blob), reference: blob) 20 return 21 } catch RadrootsAppleFileError.notFound { 22 // Only definitive absence permits the legacy copy to be installed. 23 // Conflicting, protected or unsafe destinations require recovery. 24 } 25 let legacy = try RadrootsAppleFileRoots( 26 appIdentifier: roots.appIdentifier, dataRoot: roots.dataRoot, cacheRoot: roots.cacheRoot, 27 temporaryRoot: roots.temporaryRoot, logsRoot: roots.logsRoot 28 ) 29 guard legacy.stagedBlobsRoot != roots.stagedBlobsRoot else { throw RadrootsAppleFileError.notFound } 30 let bytes = try RadrootsAppleFileAccess(roots: legacy).readStagedBlob(blob) 31 try validate(bytes, reference: blob) 32 // Preserve the legacy copy and reconcile a completed install by its exact 33 // existing reference on restart, without introducing a second journal. 34 try access.installStagedBlob(bytes, reference: blob) 35 } 36 37 private static func validate(_ bytes: Data, reference blob: RadrootsStagedBlobReference) throws { 38 let digest = SHA256.hash(data: bytes).map { String(format: "%02x", $0) }.joined() 39 guard digest == blob.blobID else { 40 throw TeraRuntimeFailure.local(operation: "add.media.migrate", code: "ios.add.media_corrupt", 41 safeMessage: "A prepared photo could not be verified on this device.") 42 } 43 } 44 }