/** * Retrieves the {@link CachedLayer} for the layer with digest {@code layerDigest}. * * @param layerDigest the layer digest * @return the {@link CachedLayer} referenced by the layer digest, if found * @throws CacheCorruptedException if the cache was found to be corrupted * @throws IOException if an I/O exception occurs */ public Maybe <CachedLayer> Retrieve(DescriptorDigest layerDigest) { layerDigest = layerDigest ?? throw new ArgumentNullException(nameof(layerDigest)); SystemPath layerDirectory = cacheStorageFiles.GetLayerDirectory(layerDigest); if (!Files.Exists(layerDirectory)) { return(Maybe.Empty <CachedLayer>()); } CachedLayer.Builder cachedLayerBuilder = CachedLayer.CreateBuilder().SetLayerDigest(layerDigest); foreach (SystemPath fileInLayerDirectory in Files.List(layerDirectory)) { if (CacheStorageFiles.IsLayerFile(fileInLayerDirectory)) { if (cachedLayerBuilder.HasLayerBlob()) { throw new CacheCorruptedException( cacheStorageFiles.GetCacheDirectory(), "Multiple layer files found for layer with digest " + layerDigest.GetHash() + " in directory: " + layerDirectory); } cachedLayerBuilder .SetLayerBlob(Blobs.From(fileInLayerDirectory)) .SetLayerDiffId(cacheStorageFiles.GetDiffId(fileInLayerDirectory)) .SetLayerSize(Files.Size(fileInLayerDirectory)); } } return(Maybe.Of(cachedLayerBuilder.Build())); }
/** * Writes a compressed layer {@link Blob}. * * <p>The {@code compressedLayerBlob} is written to the layer directory under the layers directory * corresponding to the layer blob. * * @param compressedLayerBlob the compressed layer {@link Blob} to write out * @return the {@link CachedLayer} representing the written entry * @throws IOException if an I/O exception occurs */ public async Task <CachedLayer> WriteCompressedAsync(IBlob compressedLayerBlob) { compressedLayerBlob = compressedLayerBlob ?? throw new ArgumentNullException(nameof(compressedLayerBlob)); // Creates the layers directory if it doesn't exist. Files.CreateDirectories(cacheStorageFiles.GetLayersDirectory()); // Creates the temporary directory. Files.CreateDirectories(cacheStorageFiles.GetTemporaryDirectory()); using (TemporaryDirectory temporaryDirectory = new TemporaryDirectory(cacheStorageFiles.GetTemporaryDirectory())) { SystemPath temporaryLayerDirectory = temporaryDirectory.GetDirectory(); // Writes the layer file to the temporary directory. WrittenLayer writtenLayer = await WriteCompressedLayerBlobToDirectoryAsync(compressedLayerBlob, temporaryLayerDirectory).ConfigureAwait(false); // Moves the temporary directory to the final location. temporaryDirectory.MoveIfDoesNotExist(cacheStorageFiles.GetLayerDirectory(writtenLayer.LayerDigest)); // Updates cachedLayer with the blob information. SystemPath layerFile = cacheStorageFiles.GetLayerFile(writtenLayer.LayerDigest, writtenLayer.LayerDiffId); return(CachedLayer.CreateBuilder() .SetLayerDigest(writtenLayer.LayerDigest) .SetLayerDiffId(writtenLayer.LayerDiffId) .SetLayerSize(writtenLayer.LayerSize) .SetLayerBlob(Blobs.From(layerFile)) .Build()); } }
/** * Writes an uncompressed {@link Blob} out to the cache directory in the form: * * <ul> * <li>The {@code uncompressedLayerBlob} is written to the layer directory under the layers * directory corresponding to the layer blob. * <li>The {@code selector} is written to the selector file under the selectors directory. * </ul> * * @param uncompressedLayerBlob the {@link Blob} containing the uncompressed layer contents to * write out * @param selector the optional selector digest to also reference this layer data. A selector * digest may be a secondary identifier for a layer that is distinct from the default layer * digest. * @return the {@link CachedLayer} representing the written entry * @throws IOException if an I/O exception occurs */ public async Task <CachedLayer> WriteUncompressedAsync(IBlob uncompressedLayerBlob, DescriptorDigest selector) { uncompressedLayerBlob = uncompressedLayerBlob ?? throw new ArgumentNullException(nameof(uncompressedLayerBlob)); // Creates the layers directory if it doesn't exist. Files.CreateDirectories(cacheStorageFiles.GetLayersDirectory()); // Creates the temporary directory. The temporary directory must be in the same FileStore as the // final location for Files.move to work. Files.CreateDirectories(cacheStorageFiles.GetTemporaryDirectory()); using (TemporaryDirectory temporaryDirectory = new TemporaryDirectory(cacheStorageFiles.GetTemporaryDirectory())) { SystemPath temporaryLayerDirectory = temporaryDirectory.GetDirectory(); // Writes the layer file to the temporary directory. WrittenLayer writtenLayer = await WriteUncompressedLayerBlobToDirectoryAsync(uncompressedLayerBlob, temporaryLayerDirectory).ConfigureAwait(false); // Moves the temporary directory to the final location. temporaryDirectory.MoveIfDoesNotExist(cacheStorageFiles.GetLayerDirectory(writtenLayer.LayerDigest)); // Updates cachedLayer with the blob information. SystemPath layerFile = cacheStorageFiles.GetLayerFile(writtenLayer.LayerDigest, writtenLayer.LayerDiffId); CachedLayer.Builder cachedLayerBuilder = CachedLayer.CreateBuilder() .SetLayerDigest(writtenLayer.LayerDigest) .SetLayerDiffId(writtenLayer.LayerDiffId) .SetLayerSize(writtenLayer.LayerSize) .SetLayerBlob(Blobs.From(layerFile)); // Write the selector file. if (selector != null) { WriteSelector(selector, writtenLayer.LayerDigest); } return(cachedLayerBuilder.Build()); } }