mirror of
https://github.com/apple/container.git
synced 2026-09-15 12:15:42 +00:00
Handle the same file name in the fetchBlob method (#258)
With the suggested change, when a file exists, we'll verify whether it has the same content before skipping it.
This commit is contained in:
@@ -35,6 +35,26 @@ package final class LocalOCILayoutClient: ContentClient {
|
||||
return c
|
||||
}
|
||||
|
||||
private func calculateFileDigest(at url: URL) throws -> SHA256Digest {
|
||||
let fileHandle = try FileHandle(forReadingFrom: url)
|
||||
defer {
|
||||
try? fileHandle.close()
|
||||
}
|
||||
|
||||
var hasher = SHA256()
|
||||
let chunkSize = Int(getpagesize()) * 1024
|
||||
|
||||
while true {
|
||||
let chunk = fileHandle.readData(ofLength: chunkSize)
|
||||
if chunk.isEmpty {
|
||||
break
|
||||
}
|
||||
hasher.update(data: chunk)
|
||||
}
|
||||
|
||||
return hasher.finalize()
|
||||
}
|
||||
|
||||
package func fetch<T: Codable>(name: String, descriptor: Descriptor) async throws -> T {
|
||||
let c = try await self._fetch(digest: descriptor.digest)
|
||||
return try c.decode()
|
||||
@@ -44,7 +64,8 @@ package final class LocalOCILayoutClient: ContentClient {
|
||||
let c = try await self._fetch(digest: descriptor.digest)
|
||||
let fileManager = FileManager.default
|
||||
let filePath = file.absolutePath()
|
||||
if !fileManager.fileExists(atPath: filePath) {
|
||||
|
||||
do {
|
||||
let src = c.path
|
||||
try fileManager.copyItem(at: src, to: file)
|
||||
|
||||
@@ -53,7 +74,33 @@ package final class LocalOCILayoutClient: ContentClient {
|
||||
ProgressEvent(event: "add-size", value: fileSize)
|
||||
])
|
||||
}
|
||||
} catch let error as NSError {
|
||||
guard error.code == NSFileWriteFileExistsError else {
|
||||
throw error
|
||||
}
|
||||
|
||||
do {
|
||||
let expectedDigest = try c.digest()
|
||||
let existingDigest = try calculateFileDigest(at: file)
|
||||
|
||||
guard existingDigest.digestString == expectedDigest.digestString else {
|
||||
throw ContainerizationError(
|
||||
.internalError,
|
||||
message:
|
||||
"File \(filePath) exists but contains different content. Expected digest: \(expectedDigest.digestString), existing digest: \(existingDigest.digestString)"
|
||||
)
|
||||
}
|
||||
|
||||
if let progress, let fileSize = fileManager.fileSize(atPath: filePath) {
|
||||
await progress([
|
||||
ProgressEvent(event: "add-size", value: fileSize)
|
||||
])
|
||||
}
|
||||
} catch {
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
let size = try Int64(c.size())
|
||||
let digest = try c.digest()
|
||||
return (size, digest)
|
||||
|
||||
Reference in New Issue
Block a user