Example #1
0
        /**
         * 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()));
        }
Example #2
0
        /**
         * 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());
            }
        }