public async Task <ICachedLayer> CallAsync()
        {
            string description = "Building " + layerType + " layer";

            buildConfiguration.GetEventHandlers().Dispatch(LogEvent.Progress(description + "..."));

            using (ProgressEventDispatcher ignored =
                       progressEventDispatcherFactory.Create("building " + layerType + " layer", 1))
                using (TimerEventDispatcher ignored2 =
                           new TimerEventDispatcher(buildConfiguration.GetEventHandlers(), description))

                {
                    LayersCache cache = buildConfiguration.GetApplicationLayersCache();

                    // Don't build the layer if it exists already.
                    Maybe <CachedLayer> optionalCachedLayer =
                        await cache.RetrieveAsync(layerConfiguration.LayerEntries).ConfigureAwait(false);

                    if (optionalCachedLayer.IsPresent())
                    {
                        return(new CachedLayerWithType(optionalCachedLayer.Get(), GetLayerType()));
                    }

                    IBlob       layerBlob   = new ReproducibleLayerBuilder(layerConfiguration.LayerEntries).Build();
                    CachedLayer cachedLayer =
                        await cache.WriteUncompressedLayerAsync(layerBlob, layerConfiguration.LayerEntries).ConfigureAwait(false);

                    buildConfiguration
                    .GetEventHandlers()
                    .Dispatch(LogEvent.Debug(description + " built " + cachedLayer.GetDigest()));

                    return(new CachedLayerWithType(cachedLayer, GetLayerType()));
                }
        }
예제 #2
0
        public void SetUp()
        {
            fakeDependenciesLayerConfiguration =
                MakeLayerConfiguration(
                    "core/application/dependencies", EXTRACTION_PATH_ROOT.Resolve("libs"));
            fakeSnapshotDependenciesLayerConfiguration =
                MakeLayerConfiguration(
                    "core/application/snapshot-dependencies", EXTRACTION_PATH_ROOT.Resolve("libs"));
            fakeResourcesLayerConfiguration =
                MakeLayerConfiguration(
                    "core/application/resources", EXTRACTION_PATH_ROOT.Resolve("resources"));
            fakeClassesLayerConfiguration =
                MakeLayerConfiguration("core/application/classes", EXTRACTION_PATH_ROOT.Resolve("classes"));
            fakeExtraFilesLayerConfiguration =
                LayerConfiguration.CreateBuilder()
                .AddEntry(
                    Paths.Get(TestResources.GetResource("core/fileA").ToURI()),
                    EXTRA_FILES_LAYER_EXTRACTION_PATH.Resolve("fileA"))
                .AddEntry(
                    Paths.Get(TestResources.GetResource("core/fileB").ToURI()),
                    EXTRA_FILES_LAYER_EXTRACTION_PATH.Resolve("fileB"))
                .Build();
            emptyLayerConfiguration = LayerConfiguration.CreateBuilder().Build();

            cache = LayersCache.WithDirectory(temporaryFolder.NewFolder().ToPath());

            Mock.Get(mockBuildConfiguration).Setup(m => m.GetEventHandlers()).Returns(mockEventHandlers);

            Mock.Get(mockBuildConfiguration).Setup(m => m.GetApplicationLayersCache()).Returns(cache);
        }
예제 #3
0
 /** Instantiate with {@link #builder}. */
 private BuildConfiguration(
     ImageConfiguration baseImageConfiguration,
     ImageConfiguration targetImageConfiguration,
     ImmutableHashSet <string> additionalTargetImageTags,
     ContainerConfiguration containerConfiguration,
     LayersCache baseImageLayersCache,
     LayersCache applicationLayersCache,
     ManifestFormat targetFormat,
     bool allowInsecureRegistries,
     bool offline,
     ImmutableArray <ILayerConfiguration> layerConfigurations,
     string toolName,
     string toolVersion,
     IEventHandlers eventHandlers)
 {
     this.baseImageConfiguration    = baseImageConfiguration;
     this.targetImageConfiguration  = targetImageConfiguration;
     this.additionalTargetImageTags = additionalTargetImageTags;
     this.containerConfiguration    = containerConfiguration;
     this.baseImageLayersCache      = baseImageLayersCache;
     this.applicationLayersCache    = applicationLayersCache;
     this.targetFormat            = targetFormat;
     this.allowInsecureRegistries = allowInsecureRegistries;
     this.offline             = offline;
     this.layerConfigurations = layerConfigurations;
     this.toolName            = toolName;
     this.toolVersion         = toolVersion;
     this.eventHandlers       = eventHandlers;
 }
예제 #4
0
        public async Task TestWriteUncompressedWithLayerEntries_retrieveByLayerDigestAsync()
        {
            LayersCache cache = LayersCache.WithDirectory(temporaryFolder.NewFolder().ToPath());

            await VerifyIsLayer1Async(await cache.WriteUncompressedLayerAsync(layerBlob1, layerEntries1).ConfigureAwait(false)).ConfigureAwait(false);
            await VerifyIsLayer1Async(cache.Retrieve(layerDigest1).OrElseThrow(() => new AssertionException(""))).ConfigureAwait(false);

            Assert.IsFalse(cache.Retrieve(layerDigest2).IsPresent());
        }
예제 #5
0
            /**
             * Builds a new {@link BuildConfiguration} using the parameters passed into the builder.
             *
             * @return the corresponding build configuration
             * @throws IOException if an I/O exception occurs
             */
            public BuildConfiguration Build()
            {
                // Validates the parameters.
                IList <string> missingFields = new List <string>();

                if (baseImageConfiguration == null)
                {
                    missingFields.Add("base image configuration");
                }
                if (targetImageConfiguration == null)
                {
                    missingFields.Add("target image configuration");
                }
                if (baseImageLayersCacheDirectory == null)
                {
                    missingFields.Add("base image layers cache directory");
                }
                if (applicationLayersCacheDirectory == null)
                {
                    missingFields.Add("application layers cache directory");
                }

                switch (missingFields.Count)
                {
                case 0:     // No errors
                    if (Preconditions.CheckNotNull(baseImageConfiguration).GetImage().UsesDefaultTag())
                    {
                        eventHandlers.Dispatch(
                            LogEvent.Warn(
                                "Base image '"
                                + baseImageConfiguration.GetImage()
                                + "' does not use a specific image digest - build may not be reproducible"));
                    }

                    return(new BuildConfiguration(
                               baseImageConfiguration,
                               Preconditions.CheckNotNull(targetImageConfiguration),
                               additionalTargetImageTags,
                               containerConfiguration,
                               LayersCache.WithDirectory(Preconditions.CheckNotNull(baseImageLayersCacheDirectory)),
                               LayersCache.WithDirectory(Preconditions.CheckNotNull(applicationLayersCacheDirectory)),
                               targetFormat,
                               allowInsecureRegistries,
                               offline,
                               layerConfigurations,
                               toolName,
                               toolVersion,
                               eventHandlers));

                case 1:
                    throw new InvalidOperationException("Required field is not set: " + missingFields[0]);

                default:
                    throw new InvalidOperationException("Required fields are not set: " + string.Join(", ", missingFields));
                }
            }
예제 #6
0
        public void TestWithDirectory_existsButNotDirectory()
        {
            SystemPath file = temporaryFolder.NewFile().ToPath();

            try
            {
                LayersCache.WithDirectory(file);
                Assert.Fail();
            }
            catch (IOException)
            {
                // pass
            }
        }
예제 #7
0
        public async Task TestRetrieveWithTwoEntriesInCacheAsync()
        {
            LayersCache cache = LayersCache.WithDirectory(temporaryFolder.NewFolder().ToPath());

            await VerifyIsLayer1Async(await cache.WriteUncompressedLayerAsync(layerBlob1, layerEntries1).ConfigureAwait(false)).ConfigureAwait(false);
            await VerifyIsLayer2Async(await cache.WriteUncompressedLayerAsync(layerBlob2, layerEntries2).ConfigureAwait(false)).ConfigureAwait(false);
            await VerifyIsLayer1Async(cache.Retrieve(layerDigest1).OrElseThrow(() => new AssertionException(""))).ConfigureAwait(false);
            await VerifyIsLayer2Async(cache.Retrieve(layerDigest2).OrElseThrow(() => new AssertionException(""))).ConfigureAwait(false);

            Maybe <CachedLayer> cachedLayer1 = await cache.RetrieveAsync(layerEntries1).ConfigureAwait(false);

            await VerifyIsLayer1Async(cachedLayer1.OrElseThrow(() => new AssertionException(""))).ConfigureAwait(false);

            Maybe <CachedLayer> cachedLayer2 = await cache.RetrieveAsync(layerEntries2).ConfigureAwait(false);

            await VerifyIsLayer2Async(cachedLayer2.OrElseThrow(() => new AssertionException(""))).ConfigureAwait(false);
        }
        public async Task <ICachedLayer> CallAsync()
        {
            using (ProgressEventDispatcher progressEventDispatcher =
                       progressEventDispatcherFactory.Create("checking base image layer " + layerDigest, 1))
                using (TimerEventDispatcher ignored =
                           new TimerEventDispatcher(
                               buildConfiguration.GetEventHandlers(), string.Format(CultureInfo.CurrentCulture, Description, layerDigest)))
                {
                    LayersCache cache = buildConfiguration.GetBaseImageLayersCache();

                    // Checks if the layer already exists in the cache.
                    Maybe <CachedLayer> optionalCachedLayer = cache.Retrieve(layerDigest);
                    if (optionalCachedLayer.IsPresent())
                    {
                        return(optionalCachedLayer.Get());
                    }
                    else if (buildConfiguration.IsOffline())
                    {
                        throw new IOException(
                                  "Cannot run Fib in offline mode; local Fib cache for base image is missing image layer "
                                  + layerDigest
                                  + ". You may need to rerun Fib in online mode to re-download the base image layers.");
                    }

                    RegistryClient registryClient =
                        buildConfiguration
                        .NewBaseImageRegistryClientFactory()
                        .SetAuthorization(pullAuthorization)
                        .NewRegistryClient();

                    using (ThrottledProgressEventDispatcherWrapper progressEventDispatcherWrapper =
                               new ThrottledProgressEventDispatcherWrapper(
                                   progressEventDispatcher.NewChildProducer(),
                                   "pulling base image layer " + layerDigest))
                    {
                        return(await cache.WriteCompressedLayerAsync(
                                   registryClient.PullBlob(
                                       layerDigest,
                                       progressEventDispatcherWrapper.SetProgressTarget,
                                       progressEventDispatcherWrapper.DispatchProgress)).ConfigureAwait(false));
                    }
                }
        }
예제 #9
0
        public async Task TestWriteUncompressedWithLayerEntries_retrieveByLayerEntriesAsync()
        {
            LayersCache cache = LayersCache.WithDirectory(temporaryFolder.NewFolder().ToPath());

            await VerifyIsLayer1Async(await cache.WriteUncompressedLayerAsync(layerBlob1, layerEntries1).ConfigureAwait(false)).ConfigureAwait(false);

            Maybe <CachedLayer> layer = await cache.RetrieveAsync(layerEntries1).ConfigureAwait(false);

            await VerifyIsLayer1Async(layer.OrElseThrow(() => new AssertionException(""))).ConfigureAwait(false);

            Assert.IsFalse(cache.Retrieve(layerDigest2).IsPresent());

            // A source file modification results in the cached layer to be out-of-date and not retrieved.
            Files.SetLastModifiedTime(
                layerEntries1[0].SourceFile, FileTime.From(SystemClock.Instance.GetCurrentInstant() + Duration.FromSeconds(1)));
            Maybe <CachedLayer> outOfDateLayer = await cache.RetrieveAsync(layerEntries1).ConfigureAwait(false);

            Assert.IsFalse(outOfDateLayer.IsPresent());
        }