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()));
                }
        }
        /**
         * Makes a list of {@link BuildAndCacheApplicationLayerStep} for dependencies, resources, and
         * classes layers. Optionally adds an extra layer if configured to do so.
         */
        public static IAsyncStep <IReadOnlyList <ICachedLayer> > MakeList(
            IBuildConfiguration buildConfiguration,
            ProgressEventDispatcher.Factory progressEventDispatcherFactory)
        {
            buildConfiguration = buildConfiguration ?? throw new ArgumentNullException(nameof(buildConfiguration));
            int layerCount = buildConfiguration.GetLayerConfigurations().Length;

            using (ProgressEventDispatcher progressEventDispatcher =
                       progressEventDispatcherFactory.Create(
                           "setting up to build application layers", layerCount))
                using (TimerEventDispatcher ignored =
                           new TimerEventDispatcher(buildConfiguration.GetEventHandlers(), Description))

                {
                    List <Task <ICachedLayer> > buildAndCacheApplicationLayerSteps = new List <Task <ICachedLayer> >();
                    foreach (LayerConfiguration layerConfiguration in buildConfiguration.GetLayerConfigurations())
                    {
                        // Skips the layer if empty.
                        if (layerConfiguration.LayerEntries.Length == 0)
                        {
                            continue;
                        }

                        buildAndCacheApplicationLayerSteps.Add(
                            new BuildAndCacheApplicationLayerStep(
                                buildConfiguration,
                                progressEventDispatcher.NewChildProducer(),
                                layerConfiguration.Name,
                                layerConfiguration).GetFuture());
                    }
                    return(AsyncSteps.FromTasks(buildAndCacheApplicationLayerSteps));
                }
        }
Esempio n. 3
0
        public async Task <Image> CallAsync()
        {
            BaseImageWithAuthorization baseImageWithAuthorization = await pullBaseImageStep.GetFuture().ConfigureAwait(false);

            IReadOnlyList <ICachedLayer> baseImageLayers = await pullAndCacheBaseImageLayersStep.GetFuture().ConfigureAwait(false);

            IReadOnlyList <ICachedLayer> applicationLayers = await buildAndCacheApplicationLayersStep.GetFuture().ConfigureAwait(false);

            using (progressEventDispatcherFactory.Create("building image format", 1))
                using (new TimerEventDispatcher(buildConfiguration.GetEventHandlers(), DESCRIPTION))
                {
                    // Constructs the image.
                    Image.Builder           imageBuilder           = Image.CreateBuilder(buildConfiguration.GetTargetFormat());
                    Image                   baseImage              = baseImageWithAuthorization.GetBaseImage();
                    IContainerConfiguration containerConfiguration =
                        buildConfiguration.GetContainerConfiguration();

                    // Base image layers
                    foreach (ICachedLayer pullAndCacheBaseImageLayer in baseImageLayers)
                    {
                        imageBuilder.AddLayer(pullAndCacheBaseImageLayer);
                    }

                    // Passthrough config and count non-empty history entries
                    int nonEmptyLayerCount = 0;
                    foreach (HistoryEntry historyObject in baseImage.GetHistory())
                    {
                        imageBuilder.AddHistory(historyObject);
                        if (!historyObject.HasCorrespondingLayer())
                        {
                            nonEmptyLayerCount++;
                        }
                    }
                    imageBuilder
                    .SetArchitecture(baseImage.GetArchitecture())
                    .SetOs(baseImage.GetOs())
                    .AddEnvironment(baseImage.GetEnvironment())
                    .AddLabels(baseImage.GetLabels())
                    .SetHealthCheck(baseImage.GetHealthCheck())
                    .AddExposedPorts(baseImage.GetExposedPorts())
                    .AddVolumes(baseImage.GetVolumes())
                    .SetWorkingDirectory(baseImage.GetWorkingDirectory());

                    // Add history elements for non-empty layers that don't have one yet
                    Instant layerCreationTime =
                        containerConfiguration == null
                        ? ContainerConfiguration.DefaultCreationTime
                        : containerConfiguration.GetCreationTime();
                    for (int count = 0; count < baseImageLayers.Count - nonEmptyLayerCount; count++)
                    {
                        imageBuilder.AddHistory(
                            HistoryEntry.CreateBuilder()
                            .SetCreationTimestamp(layerCreationTime)
                            .SetComment("auto-generated by Fib")
                            .Build());
                    }

                    // Add built layers/configuration
                    foreach (ICachedLayer applicationLayer in applicationLayers)
                    {
                        HistoryEntry.Builder historyBuilder = HistoryEntry.CreateBuilder();
                        if (buildConfiguration.GetToolName() != null)
                        {
                            historyBuilder.SetCreatedBy(buildConfiguration.GetToolName() + ":" + (buildConfiguration.GetToolVersion() ?? "null"));
                        }
                        else
                        {
                            historyBuilder.SetCreatedBy(ProjectInfo.TOOL_NAME + ":" + ProjectInfo.VERSION);
                        }
                        imageBuilder
                        .AddLayer(applicationLayer)
                        .AddHistory(
                            historyBuilder
                            .SetCreationTimestamp(layerCreationTime)
                            .SetAuthor("Fib")
                            .SetComment(applicationLayer.GetLayerType())
                            .Build());
                    }
                    if (containerConfiguration != null)
                    {
                        imageBuilder
                        .AddEnvironment(containerConfiguration.GetEnvironmentMap())
                        .SetCreated(containerConfiguration.GetCreationTime())
                        .SetUser(containerConfiguration.GetUser())
                        .SetEntrypoint(ComputeEntrypoint(baseImage, containerConfiguration))
                        .SetProgramArguments(ComputeProgramArguments(baseImage, containerConfiguration))
                        .AddExposedPorts(containerConfiguration.GetExposedPorts())
                        .AddVolumes(containerConfiguration.GetVolumes())
                        .AddLabels(containerConfiguration.GetLabels());
                        if (containerConfiguration.GetWorkingDirectory() != null)
                        {
                            imageBuilder.SetWorkingDirectory(containerConfiguration.GetWorkingDirectory().ToString());
                        }
                    }

                    // Gets the container configuration content descriptor.
                    return(imageBuilder.Build());
                }
        }