public void TestToJson()
        {
            // Loads the expected JSON string.
            SystemPath jsonFile     = Paths.Get(TestResources.GetResource("core/json/containerconfig.json").ToURI());
            string     expectedJson = Encoding.UTF8.GetString(Files.ReadAllBytes(jsonFile));

            // Creates the JSON object to serialize.
            ContainerConfigurationTemplate containerConfigJson = new ContainerConfigurationTemplate
            {
                Created      = "1970-01-01T00:00:20Z",
                Architecture = "wasm",
                Os           = "js"
            };

            containerConfigJson.SetContainerEnvironment(new[] { "VAR1=VAL1", "VAR2=VAL2" });
            containerConfigJson.SetContainerEntrypoint(new[] { "some", "entrypoint", "command" });
            containerConfigJson.SetContainerCmd(new[] { "arg1", "arg2" });
            containerConfigJson.SetContainerHealthCheckTest(new[] { "CMD-SHELL", "/checkhealth" });
            containerConfigJson.SetContainerHealthCheckInterval(3000000000L);
            containerConfigJson.SetContainerHealthCheckTimeout(1000000000L);
            containerConfigJson.SetContainerHealthCheckStartPeriod(2000000000L);
            containerConfigJson.SetContainerHealthCheckRetries(3);
            containerConfigJson.SetContainerExposedPorts(
                new Dictionary <string, IDictionary <object, object> >
            {
                ["1000/tcp"] =
                    ImmutableDictionary.Create <object, object>(),
                ["2000/tcp"] =
                    ImmutableDictionary.Create <object, object>(),
                ["3000/udp"] =
                    ImmutableDictionary.Create <object, object>()
            }.ToImmutableSortedDictionary());
            containerConfigJson.SetContainerLabels(ImmutableDic.Of("key1", "value1", "key2", "value2"));
            containerConfigJson.SetContainerVolumes(
                ImmutableDic.Of <string, IDictionary <object, object> >(
                    "/var/job-result-data", ImmutableDictionary.Create <object, object>(), "/var/log/my-app-logs", ImmutableDictionary.Create <object, object>()));
            containerConfigJson.SetContainerWorkingDir("/some/workspace");
            containerConfigJson.SetContainerUser("tomcat");

            containerConfigJson.AddLayerDiffId(
                DescriptorDigest.FromDigest(
                    "sha256:8c662931926fa990b41da3c9f42663a537ccd498130030f9149173a0493832ad"));
            containerConfigJson.AddHistoryEntry(
                HistoryEntry.CreateBuilder()
                .SetCreationTimestamp(Instant.FromUnixTimeSeconds(0))
                .SetAuthor("Bazel")
                .SetCreatedBy("bazel build ...")
                .SetEmptyLayer(true)
                .Build());
            containerConfigJson.AddHistoryEntry(
                HistoryEntry.CreateBuilder()
                .SetCreationTimestamp(Instant.FromUnixTimeSeconds(20))
                .SetAuthor("Fib")
                .SetCreatedBy("fib")
                .Build());

            // Serializes the JSON object.
            Assert.AreEqual(expectedJson, JsonTemplateMapper.ToUtf8String(containerConfigJson));
        }
        public void TestFromJson()
        {
            // Loads the JSON string.
            SystemPath jsonFile = Paths.Get(TestResources.GetResource("core/json/containerconfig.json").ToURI());

            // Deserializes into a manifest JSON object.
            ContainerConfigurationTemplate containerConfigJson =
                JsonTemplateMapper.ReadJsonFromFile <ContainerConfigurationTemplate>(jsonFile);

            Assert.AreEqual("1970-01-01T00:00:20Z", containerConfigJson.Created);
            Assert.AreEqual("wasm", containerConfigJson.Architecture);
            Assert.AreEqual("js", containerConfigJson.Os);
            Assert.AreEqual(
                new[] { "VAR1=VAL1", "VAR2=VAL2" }, containerConfigJson.GetContainerEnvironment());
            Assert.AreEqual(
                new[] { "some", "entrypoint", "command" },
                containerConfigJson.GetContainerEntrypoint());
            Assert.AreEqual(new[] { "arg1", "arg2" }, containerConfigJson.GetContainerCmd());

            Assert.AreEqual(
                new[] { "CMD-SHELL", "/checkhealth" }, containerConfigJson.GetContainerHealthTest());
            Assert.IsNotNull(containerConfigJson.GetContainerHealthInterval());
            Assert.AreEqual(3000000000L, containerConfigJson.GetContainerHealthInterval().GetValueOrDefault());
            Assert.IsNotNull(containerConfigJson.GetContainerHealthTimeout());
            Assert.AreEqual(1000000000L, containerConfigJson.GetContainerHealthTimeout().GetValueOrDefault());
            Assert.IsNotNull(containerConfigJson.GetContainerHealthStartPeriod());
            Assert.AreEqual(
                2000000000L, containerConfigJson.GetContainerHealthStartPeriod().GetValueOrDefault());
            Assert.IsNotNull(containerConfigJson.GetContainerHealthRetries());
            Assert.AreEqual(3, containerConfigJson.GetContainerHealthRetries().GetValueOrDefault());

            Assert.AreEqual(
                ImmutableDic.Of("key1", "value1", "key2", "value2"),
                containerConfigJson.GetContainerLabels());
            Assert.AreEqual("/some/workspace", containerConfigJson.GetContainerWorkingDir());
            Assert.AreEqual(
                DescriptorDigest.FromDigest(
                    "sha256:8c662931926fa990b41da3c9f42663a537ccd498130030f9149173a0493832ad"),
                containerConfigJson.GetLayerDiffId(0));
            Assert.AreEqual(
                ImmutableArray.Create(
                    HistoryEntry.CreateBuilder()
                    .SetCreationTimestamp(Instant.FromUnixTimeSeconds(0))
                    .SetAuthor("Bazel")
                    .SetCreatedBy("bazel build ...")
                    .SetEmptyLayer(true)
                    .Build(),
                    HistoryEntry.CreateBuilder()
                    .SetCreationTimestamp(Instant.FromUnixTimeSeconds(20))
                    .SetAuthor("Fib")
                    .SetCreatedBy("fib")
                    .Build()),
                containerConfigJson.History);
        }
        //private static DescriptorDigest fakeDigest = DescriptorDigest.fromHash(new string('a', 64));

        private void SetUp(ManifestFormat imageFormat)
        {
            Image.Builder testImageBuilder =
                Image.CreateBuilder(imageFormat)
                .SetCreated(Instant.FromUnixTimeSeconds(20))
                .SetArchitecture("wasm")
                .SetOs("js")
                .AddEnvironmentVariable("VAR1", "VAL1")
                .AddEnvironmentVariable("VAR2", "VAL2")
                .SetEntrypoint(new[] { "some", "entrypoint", "command" })
                .SetProgramArguments(new[] { "arg1", "arg2" })
                .SetHealthCheck(
                    DockerHealthCheck.FromCommand(ImmutableArray.Create("CMD-SHELL", "/checkhealth"))
                    .SetInterval(Duration.FromSeconds(3))
                    .SetTimeout(Duration.FromSeconds(1))
                    .SetStartPeriod(Duration.FromSeconds(2))
                    .SetRetries(3)
                    .Build())
                .AddExposedPorts(ImmutableHashSet.Create(Port.Tcp(1000), Port.Tcp(2000), Port.Udp(3000)))
                .AddVolumes(
                    ImmutableHashSet.Create(
                        AbsoluteUnixPath.Get("/var/job-result-data"),
                        AbsoluteUnixPath.Get("/var/log/my-app-logs")))
                .AddLabels(ImmutableDic.Of("key1", "value1", "key2", "value2"))
                .SetWorkingDirectory("/some/workspace")
                .SetUser("tomcat");

            DescriptorDigest fakeDigest =
                DescriptorDigest.FromDigest(
                    "sha256:8c662931926fa990b41da3c9f42663a537ccd498130030f9149173a0493832ad");

            testImageBuilder.AddLayer(
                new FakeLayer(fakeDigest));
            testImageBuilder.AddHistory(
                HistoryEntry.CreateBuilder()
                .SetCreationTimestamp(Instant.FromUnixTimeSeconds(0))
                .SetAuthor("Bazel")
                .SetCreatedBy("bazel build ...")
                .SetEmptyLayer(true)
                .Build());
            testImageBuilder.AddHistory(
                HistoryEntry.CreateBuilder()
                .SetCreationTimestamp(Instant.FromUnixTimeSeconds(20))
                .SetAuthor("Fib")
                .SetCreatedBy("fib")
                .Build());
            imageToJsonTranslator = new ImageToJsonTranslator(testImageBuilder.Build());
        }
Exemple #4
0
        private void TestToImage_buildable <T>(
            string jsonFilename) where T : IBuildableManifestTemplate
        {
            // Loads the container configuration JSON.
            SystemPath containerConfigurationJsonFile =
                Paths.Get(
                    TestResources.GetResource("core/json/containerconfig.json").ToURI());
            ContainerConfigurationTemplate containerConfigurationTemplate =
                JsonTemplateMapper.ReadJsonFromFile <ContainerConfigurationTemplate>(
                    containerConfigurationJsonFile);

            // Loads the manifest JSON.
            SystemPath manifestJsonFile =
                Paths.Get(TestResources.GetResource(jsonFilename).ToURI());
            T manifestTemplate =
                JsonTemplateMapper.ReadJsonFromFile <T>(manifestJsonFile);

            Image image = JsonToImageTranslator.ToImage(manifestTemplate, containerConfigurationTemplate);

            IList <ILayer> layers = image.GetLayers();

            Assert.AreEqual(1, layers.Count);
            Assert.AreEqual(
                new BlobDescriptor(
                    1000000,
                    DescriptorDigest.FromDigest(
                        "sha256:4945ba5011739b0b98c4a41afe224e417f47c7c99b2ce76830999c9a0861b236")),
                layers[0].GetBlobDescriptor());
            Assert.AreEqual(
                DescriptorDigest.FromDigest(
                    "sha256:8c662931926fa990b41da3c9f42663a537ccd498130030f9149173a0493832ad"),
                layers[0].GetDiffId());
            CollectionAssert.AreEqual(
                ImmutableArray.Create(
                    HistoryEntry.CreateBuilder()
                    .SetCreationTimestamp(Instant.FromUnixTimeSeconds(0))
                    .SetAuthor("Bazel")
                    .SetCreatedBy("bazel build ...")
                    .SetEmptyLayer(true)
                    .Build(),
                    HistoryEntry.CreateBuilder()
                    .SetCreationTimestamp(Instant.FromUnixTimeSeconds(20))
                    .SetAuthor("Fib")
                    .SetCreatedBy("fib")
                    .Build()),
                image.GetHistory());
            Assert.AreEqual(Instant.FromUnixTimeSeconds(20), image.GetCreated());
            Assert.AreEqual(new[] { "some", "entrypoint", "command" }, image.GetEntrypoint());
            Assert.AreEqual(ImmutableDic.Of("VAR1", "VAL1", "VAR2", "VAL2"), image.GetEnvironment());
            Assert.AreEqual("/some/workspace", image.GetWorkingDirectory());
            Assert.AreEqual(
                ImmutableHashSet.Create(Port.Tcp(1000), Port.Tcp(2000), Port.Udp(3000)), image.GetExposedPorts());
            Assert.AreEqual(
                ImmutableHashSet.Create(
                    AbsoluteUnixPath.Get("/var/job-result-data"),
                    AbsoluteUnixPath.Get("/var/log/my-app-logs")),
                image.GetVolumes());
            Assert.AreEqual("tomcat", image.GetUser());
            Assert.AreEqual("value1", image.GetLabels()["key1"]);
            Assert.AreEqual("value2", image.GetLabels()["key2"]);
            Assert.AreEqual(2, image.GetLabels().Count);
        }
Exemple #5
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());
                }
        }
        public void SetUp()
        {
            testDescriptorDigest =
                DescriptorDigest.FromHash(
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");

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

            Mock.Get(mockBuildConfiguration).Setup(m => m.GetContainerConfiguration()).Returns(mockContainerConfiguration);

            Mock.Get(mockBuildConfiguration).Setup(m => m.GetToolName()).Returns(() => null);

            Mock.Get(mockContainerConfiguration).Setup(m => m.GetCreationTime()).Returns(Instant.FromUnixTimeSeconds(0));

            Mock.Get(mockContainerConfiguration).Setup(m => m.GetEnvironmentMap()).Returns(ImmutableDictionary.Create <string, string>());

            Mock.Get(mockContainerConfiguration).Setup(m => m.GetProgramArguments()).Returns(ImmutableArray.Create <string>());

            Mock.Get(mockContainerConfiguration).Setup(m => m.GetExposedPorts()).Returns(ImmutableHashSet.Create <Port>());

            Mock.Get(mockContainerConfiguration).Setup(m => m.GetEntrypoint()).Returns(ImmutableArray.Create <string>());

            Mock.Get(mockContainerConfiguration).Setup(m => m.GetUser()).Returns("root");

            Mock.Get(mockCachedLayer).Setup(m => m.GetBlobDescriptor()).Returns(new BlobDescriptor(0, testDescriptorDigest));

            nonEmptyLayerHistory =
                HistoryEntry.CreateBuilder()
                .SetCreationTimestamp(Instant.FromUnixTimeSeconds(0))
                .SetAuthor("FibBase")
                .SetCreatedBy("fib-test")
                .Build();
            emptyLayerHistory =
                HistoryEntry.CreateBuilder()
                .SetCreationTimestamp(Instant.FromUnixTimeSeconds(0))
                .SetAuthor("FibBase")
                .SetCreatedBy("fib-test")
                .SetEmptyLayer(true)
                .Build();

            Image baseImage =
                Image.CreateBuilder(ManifestFormat.V22)
                .SetArchitecture("wasm")
                .SetOs("js")
                .AddEnvironment(ImmutableDic.Of("BASE_ENV", "BASE_ENV_VALUE", "BASE_ENV_2", "DEFAULT"))
                .AddLabel("base.label", "base.label.value")
                .AddLabel("base.label.2", "default")
                .SetWorkingDirectory("/base/working/directory")
                .SetEntrypoint(ImmutableArray.Create("baseImageEntrypoint"))
                .SetProgramArguments(ImmutableArray.Create("catalina.sh", "run"))
                .SetHealthCheck(
                    DockerHealthCheck.FromCommand(ImmutableArray.Create("CMD-SHELL", "echo hi"))
                    .SetInterval(Duration.FromSeconds(3))
                    .SetTimeout(Duration.FromSeconds(2))
                    .SetStartPeriod(Duration.FromSeconds(1))
                    .SetRetries(20)
                    .Build())
                .AddExposedPorts(ImmutableHashSet.Create(Port.Tcp(1000), Port.Udp(2000)))
                .AddVolumes(
                    ImmutableHashSet.Create(
                        AbsoluteUnixPath.Get("/base/path1"), AbsoluteUnixPath.Get("/base/path2")))
                .AddHistory(nonEmptyLayerHistory)
                .AddHistory(emptyLayerHistory)
                .AddHistory(emptyLayerHistory)
                .Build();

            Mock.Get(mockPullAndCacheBaseImageLayerStep).Setup(m => m.GetFuture()).Returns(Futures.ImmediateFutureAsync(mockCachedLayer));

            Mock.Get(mockPullAndCacheBaseImageLayersStep).Setup(m => m.GetFuture()).Returns(
                Futures.ImmediateFutureAsync <IReadOnlyList <ICachedLayer> >(
                    ImmutableArray.Create(
                        mockCachedLayer,
                        mockCachedLayer,
                        mockCachedLayer)));

            Mock.Get(mockPullBaseImageStep).Setup(m => m.GetFuture()).Returns(
                Futures.ImmediateFutureAsync(
                    new BaseImageWithAuthorization(baseImage, null)));

            mockClassesLayer = new CachedLayerWithType(mockCachedLayer, "classes");

            mockDependenciesLayer = new CachedLayerWithType(mockCachedLayer, "dependencies");

            mockExtraFilesLayer = new CachedLayerWithType(mockCachedLayer, "extra files");

            mockResourcesLayer = new CachedLayerWithType(mockCachedLayer, "resources");
        }
        public async Task Test_generateHistoryObjectsAsync()
        {
            Mock.Get(mockBuildAndCacheApplicationLayersStep).Setup(s => s.GetFuture()).Returns(Task.FromResult <IReadOnlyList <ICachedLayer> >(ImmutableArray.Create(
                                                                                                                                                   mockDependenciesLayer,
                                                                                                                                                   mockResourcesLayer,
                                                                                                                                                   mockClassesLayer,
                                                                                                                                                   mockExtraFilesLayer)));
            string         createdBy      = "fib:" + ProjectInfo.VERSION;
            BuildImageStep buildImageStep =
                new BuildImageStep(
                    mockBuildConfiguration,
                    ProgressEventDispatcher.NewRoot(mockEventHandlers, "ignored", 1).NewChildProducer(),
                    mockPullBaseImageStep,
                    mockPullAndCacheBaseImageLayersStep,
                    mockBuildAndCacheApplicationLayersStep);
            Image image = await buildImageStep.GetFuture().ConfigureAwait(false);

            // Make sure history is as expected
            HistoryEntry expectedAddedBaseLayerHistory =
                HistoryEntry.CreateBuilder()
                .SetCreationTimestamp(Instant.FromUnixTimeSeconds(0))
                .SetComment("auto-generated by Fib")
                .Build();

            HistoryEntry expectedApplicationLayerHistoryDependencies =
                HistoryEntry.CreateBuilder()
                .SetCreationTimestamp(Instant.FromUnixTimeSeconds(0))
                .SetAuthor("Fib")
                .SetCreatedBy(createdBy)
                .SetComment("dependencies")
                .Build();

            HistoryEntry expectedApplicationLayerHistoryResources =
                HistoryEntry.CreateBuilder()
                .SetCreationTimestamp(Instant.FromUnixTimeSeconds(0))
                .SetAuthor("Fib")
                .SetCreatedBy(createdBy)
                .SetComment("resources")
                .Build();

            HistoryEntry expectedApplicationLayerHistoryClasses =
                HistoryEntry.CreateBuilder()
                .SetCreationTimestamp(Instant.FromUnixTimeSeconds(0))
                .SetAuthor("Fib")
                .SetCreatedBy(createdBy)
                .SetComment("classes")
                .Build();

            HistoryEntry expectedApplicationLayerHistoryExtrafiles =
                HistoryEntry.CreateBuilder()
                .SetCreationTimestamp(Instant.FromUnixTimeSeconds(0))
                .SetAuthor("Fib")
                .SetCreatedBy(createdBy)
                .SetComment("extra files")
                .Build();

            // Base layers (1 non-empty propagated, 2 empty propagated, 2 non-empty generated)
            Assert.AreEqual(nonEmptyLayerHistory, image.GetHistory()[0]);
            Assert.AreEqual(emptyLayerHistory, image.GetHistory()[1]);
            Assert.AreEqual(emptyLayerHistory, image.GetHistory()[2]);
            Assert.AreEqual(expectedAddedBaseLayerHistory, image.GetHistory()[3]);
            Assert.AreEqual(expectedAddedBaseLayerHistory, image.GetHistory()[4]);

            // Application layers (4 generated)
            Assert.AreEqual(expectedApplicationLayerHistoryDependencies, image.GetHistory()[5]);
            Assert.AreEqual(expectedApplicationLayerHistoryResources, image.GetHistory()[6]);
            Assert.AreEqual(expectedApplicationLayerHistoryClasses, image.GetHistory()[7]);
            Assert.AreEqual(expectedApplicationLayerHistoryExtrafiles, image.GetHistory()[8]);

            // Should be exactly 9 total
            Assert.AreEqual(9, image.GetHistory().Length);
        }