public async Task SetUpAsync() { SystemPath directory = temporaryFolder.NewFolder().ToPath(); Files.CreateDirectory(directory.Resolve("source")); Files.CreateFile(directory.Resolve("source/file")); Files.CreateDirectories(directory.Resolve("another/source")); Files.CreateFile(directory.Resolve("another/source/file")); layerBlob1 = Blobs.From("layerBlob1"); layerDigest1 = await DigestOfAsync(Compress(layerBlob1)).ConfigureAwait(false); layerDiffId1 = await DigestOfAsync(layerBlob1).ConfigureAwait(false); layerSize1 = await SizeOfAsync(Compress(layerBlob1)).ConfigureAwait(false); layerEntries1 = ImmutableArray.Create( DefaultLayerEntry( directory.Resolve("source/file"), AbsoluteUnixPath.Get("/extraction/path")), DefaultLayerEntry( directory.Resolve("another/source/file"), AbsoluteUnixPath.Get("/another/extraction/path"))); layerBlob2 = Blobs.From("layerBlob2"); layerDigest2 = await DigestOfAsync(Compress(layerBlob2)).ConfigureAwait(false); layerDiffId2 = await DigestOfAsync(layerBlob2).ConfigureAwait(false); layerSize2 = await SizeOfAsync(Compress(layerBlob2)).ConfigureAwait(false); layerEntries2 = ImmutableArray.Create <LayerEntry>(); }
public void TestBuilder_workingDirectory() { ContainerConfiguration configuration = ContainerConfiguration.CreateBuilder().SetWorkingDirectory(AbsoluteUnixPath.Get("/path")).Build(); Assert.AreEqual(AbsoluteUnixPath.Get("/path"), configuration.GetWorkingDirectory()); }
public void Test_smokeTest() { Image image = Image.CreateBuilder(ManifestFormat.V22) .SetCreated(Instant.FromUnixTimeSeconds(10000)) .AddEnvironmentVariable("crepecake", "is great") .AddEnvironmentVariable("VARIABLE", "VALUE") .SetEntrypoint(new[] { "some", "command" }) .SetProgramArguments(new[] { "arg1", "arg2" }) .AddExposedPorts(ImmutableHashSet.Create(Port.Tcp(1000), Port.Tcp(2000))) .AddVolumes( ImmutableHashSet.Create( AbsoluteUnixPath.Get("/a/path"), AbsoluteUnixPath.Get("/another/path"))) .SetUser("john") .AddLayer(mockLayer) .Build(); Assert.AreEqual(ManifestFormat.V22, image.GetImageFormat()); Assert.AreEqual( mockDescriptorDigest, image.GetLayers()[0].GetBlobDescriptor().GetDigest()); Assert.AreEqual(Instant.FromUnixTimeSeconds(10000), image.GetCreated()); Assert.AreEqual( ImmutableDic.Of("crepecake", "is great", "VARIABLE", "VALUE"), image.GetEnvironment()); Assert.AreEqual(new[] { "some", "command" }, image.GetEntrypoint()); Assert.AreEqual(new[] { "arg1", "arg2" }, image.GetProgramArguments()); Assert.AreEqual(ImmutableHashSet.Create(Port.Tcp(1000), Port.Tcp(2000)), image.GetExposedPorts()); Assert.AreEqual( ImmutableHashSet.Create(AbsoluteUnixPath.Get("/a/path"), AbsoluteUnixPath.Get("/another/path")), image.GetVolumes()); Assert.AreEqual("john", image.GetUser()); }
public static async Task CreateImageAsync() { SystemPath root = imageLocation.GetRoot().ToPath(); SystemPath fileA = Files.CreateFile(root.Resolve("fileA.txt")); SystemPath fileB = Files.CreateFile(root.Resolve("fileB.txt")); SystemPath fileC = Files.CreateFile(root.Resolve("fileC.txt")); SystemPath subdir = Files.CreateDirectory(root.Resolve("dir")); SystemPath subsubdir = Files.CreateDirectory(subdir.Resolve("subdir")); Files.CreateFile(subdir.Resolve("fileD.txt")); Files.CreateFile(subsubdir.Resolve("fileE.txt")); imageTar = new FileInfo(Path.Combine(imageLocation.GetRoot().FullName, "image.tar")); Containerizer containerizer = Containerizer.To(TarImage.Named("fibdotnet-core/reproducible").SaveTo(imageTar.ToPath())); await FibContainerBuilder.FromScratch() .SetEntrypoint("echo", "Hello World") .AddLayer(ImmutableArray.Create(fileA), AbsoluteUnixPath.Get("/app")) // layer with out-of-order files .AddLayer(ImmutableArray.Create(fileC, fileB), "/app") .AddLayer( LayerConfiguration.CreateBuilder() .AddEntryRecursive(subdir, AbsoluteUnixPath.Get("/app")) .Build()) .ContainerizeAsync(containerizer).ConfigureAwait(false); }
public async Task TestBuild_timestampNonDefaultAsync() { SystemPath file = CreateFile(temporaryFolder.GetRoot().ToPath(), "fileA", "some content", 54321); IBlob blob = new ReproducibleLayerBuilder( ImmutableArray.Create( new LayerEntry( file, AbsoluteUnixPath.Get("/fileA"), FilePermissions.DefaultFilePermissions, Instant.FromUnixTimeSeconds(123)))) .Build(); SystemPath tarFile = temporaryFolder.NewFile().ToPath(); using (Stream @out = new BufferedStream(Files.NewOutputStream(tarFile))) { await blob.WriteToAsync(@out).ConfigureAwait(false); } // Reads the file back. using (TarInputStream @in = new TarInputStream(Files.NewInputStream(tarFile))) { Assert.AreEqual( (Instant.FromUnixTimeSeconds(0) + Duration.FromSeconds(123)).ToDateTimeUtc(), @in.GetNextEntry().TarHeader.ModTime); } }
public void TestVolumeMapToList() { ImmutableSortedDictionary <string, IDictionary <object, object> > input = new Dictionary <string, IDictionary <object, object> > { ["/var/job-result-data"] = ImmutableDictionary.Create <object, object>(), ["/var/log/my-app-logs"] = ImmutableDictionary.Create <object, object>() }.ToImmutableSortedDictionary(); ImmutableHashSet <AbsoluteUnixPath> expected = ImmutableHashSet.Create( AbsoluteUnixPath.Get("/var/job-result-data"), AbsoluteUnixPath.Get("/var/log/my-app-logs")); Assert.AreEqual(expected, JsonToImageTranslator.VolumeMapToSet(input)); ImmutableArray <IDictionary <string, IDictionary <object, object> > > badInputs = ImmutableArray.Create <IDictionary <string, IDictionary <object, object> > >( ImmutableDic.Of <string, IDictionary <object, object> >("var/job-result-data", ImmutableDictionary.Create <object, object>()), ImmutableDic.Of <string, IDictionary <object, object> >("log", ImmutableDictionary.Create <object, object>()), ImmutableDic.Of <string, IDictionary <object, object> >("C:/udp", ImmutableDictionary.Create <object, object>())); foreach (IDictionary <string, IDictionary <object, object> > badInput in badInputs) { try { JsonToImageTranslator.VolumeMapToSet(badInput); Assert.Fail(); } catch (BadContainerConfigurationFormatException) { } } }
public void TestAddEntryRecursive_defaults() { SystemPath testDirectory = TestResources.GetResource("core/layer"); SystemPath testFile = TestResources.GetResource("core/fileA"); ILayerConfiguration layerConfiguration = LayerConfiguration.CreateBuilder() .AddEntryRecursive(testDirectory, AbsoluteUnixPath.Get("/app/layer/")) .AddEntryRecursive(testFile, AbsoluteUnixPath.Get("/app/fileA")) .Build(); ImmutableHashSet <LayerEntry> expectedLayerEntries = ImmutableHashSet.Create( DefaultLayerEntry(testDirectory, AbsoluteUnixPath.Get("/app/layer/")), DefaultLayerEntry(testDirectory.Resolve("a"), AbsoluteUnixPath.Get("/app/layer/a/")), DefaultLayerEntry( testDirectory.Resolve("a/b"), AbsoluteUnixPath.Get("/app/layer/a/b/")), DefaultLayerEntry( testDirectory.Resolve("a/b/bar"), AbsoluteUnixPath.Get("/app/layer/a/b/bar/")), DefaultLayerEntry(testDirectory.Resolve("c/"), AbsoluteUnixPath.Get("/app/layer/c")), DefaultLayerEntry( testDirectory.Resolve("c/cat/"), AbsoluteUnixPath.Get("/app/layer/c/cat")), DefaultLayerEntry(testDirectory.Resolve("foo"), AbsoluteUnixPath.Get("/app/layer/foo")), DefaultLayerEntry(testFile, AbsoluteUnixPath.Get("/app/fileA"))); CollectionAssert.AreEquivalent( expectedLayerEntries, ImmutableHashSet.CreateRange(layerConfiguration.LayerEntries)); }
public void TestEquals() { AbsoluteUnixPath absoluteUnixPath1 = AbsoluteUnixPath.Get("/absolute/path"); AbsoluteUnixPath absoluteUnixPath2 = AbsoluteUnixPath.Get("/absolute/path/"); AbsoluteUnixPath absoluteUnixPath3 = AbsoluteUnixPath.Get("/another/path"); Assert.AreEqual(absoluteUnixPath1, absoluteUnixPath2); Assert.AreNotEqual(absoluteUnixPath1, absoluteUnixPath3); }
public void TestBuilder_nullValues() { // Java arguments element should not be null. try { ContainerConfiguration.CreateBuilder().SetProgramArguments(new[] { "first", null }); Assert.Fail("The IllegalArgumentException should be thrown."); } catch (ArgumentException ex) { Assert.That(ex.Message, Contains.Substring(Resources.NullProgramArgument)); } // Entrypoint element should not be null. try { ContainerConfiguration.CreateBuilder().SetEntrypoint(new[] { "first", null }); Assert.Fail("The IllegalArgumentException should be thrown."); } catch (ArgumentException ex) { Assert.That(ex.Message, Contains.Substring(Resources.NullEntrypointArgument)); } // Exposed ports element should not be null. ISet <Port> badPorts = new HashSet <Port> { Port.Tcp(1000), null }; try { ContainerConfiguration.CreateBuilder().SetExposedPorts(badPorts); Assert.Fail("The IllegalArgumentException should be thrown."); } catch (ArgumentException ex) { Assert.That(ex.Message, Contains.Substring(Resources.NullPort)); } // Volume element should not be null. ISet <AbsoluteUnixPath> badVolumes = new HashSet <AbsoluteUnixPath> { AbsoluteUnixPath.Get("/"), null }; try { ContainerConfiguration.CreateBuilder().SetVolumes(badVolumes); Assert.Fail("The IllegalArgumentException should be thrown."); } catch (ArgumentException ex) { Assert.That(ex.Message, Contains.Substring(Resources.NullVolume)); } }
public async Task TestBuildAsync() { SystemPath layerDirectory = Paths.Get(TestResources.GetResource("core/layer").ToURI()); SystemPath blobA = Paths.Get(TestResources.GetResource("core/blobA").ToURI()); ReproducibleLayerBuilder layerBuilder = new ReproducibleLayerBuilder( LayerConfiguration.CreateBuilder() .AddEntryRecursive( layerDirectory, AbsoluteUnixPath.Get("/extract/here/apple/layer")) .AddEntry(blobA, AbsoluteUnixPath.Get("/extract/here/apple/blobA")) .AddEntry(blobA, AbsoluteUnixPath.Get("/extract/here/banana/blobA")) .Build() .LayerEntries); // Writes the layer tar to a temporary file. IBlob unwrittenBlob = layerBuilder.Build(); SystemPath temporaryFile = temporaryFolder.NewFile().ToPath(); using (Stream temporaryFileOutputStream = new BufferedStream(Files.NewOutputStream(temporaryFile))) { await unwrittenBlob.WriteToAsync(temporaryFileOutputStream).ConfigureAwait(false); } // Reads the file back. TarInputStream tarArchiveInputStream = new TarInputStream(Files.NewInputStream(temporaryFile)); VerifyNextTarArchiveEntryIsDirectory(tarArchiveInputStream, "extract/"); VerifyNextTarArchiveEntryIsDirectory(tarArchiveInputStream, "extract/here/"); VerifyNextTarArchiveEntryIsDirectory(tarArchiveInputStream, "extract/here/apple/"); VerifyNextTarArchiveEntry(tarArchiveInputStream, "extract/here/apple/blobA", blobA); VerifyNextTarArchiveEntryIsDirectory(tarArchiveInputStream, "extract/here/apple/layer/"); VerifyNextTarArchiveEntryIsDirectory(tarArchiveInputStream, "extract/here/apple/layer/a/"); VerifyNextTarArchiveEntryIsDirectory(tarArchiveInputStream, "extract/here/apple/layer/a/b/"); VerifyNextTarArchiveEntry( tarArchiveInputStream, "extract/here/apple/layer/a/b/bar", Paths.Get(TestResources.GetResource("core/layer/a/b/bar").ToURI())); VerifyNextTarArchiveEntryIsDirectory(tarArchiveInputStream, "extract/here/apple/layer/c/"); VerifyNextTarArchiveEntry( tarArchiveInputStream, "extract/here/apple/layer/c/cat", Paths.Get(TestResources.GetResource("core/layer/c/cat").ToURI())); VerifyNextTarArchiveEntry( tarArchiveInputStream, "extract/here/apple/layer/foo", Paths.Get(TestResources.GetResource("core/layer/foo").ToURI())); VerifyNextTarArchiveEntryIsDirectory(tarArchiveInputStream, "extract/here/banana/"); VerifyNextTarArchiveEntry(tarArchiveInputStream, "extract/here/banana/blobA", blobA); }
public void TestGetContainerBuilder_BaseImage() { LayerConfiguration[] layerConfigurations = new[] { new LayerConfiguration("appLayer", ImmutableArray <LayerEntry> .Empty) }; var cliConfiguration = new FibCliConfiguration { ImageFormat = ImageFormat.OCI, ImageLayers = layerConfigurations, BaseImage = "reg.io/base-image:tag", Entrypoint = new[] { "Entrypoint" }, Cmd = new[] { "Program", "Arguments" }, Environment = new Dictionary <string, string> { ["Var"] = "Value" }, ImageWorkingDirectory = AbsoluteUnixPath.Get("/working/dir"), ImageUser = "******", Ports = new[] { Port.Tcp(5000) }, Volumes = new[] { AbsoluteUnixPath.Get("/volume") }, Labels = new Dictionary <string, string> { ["Label"] = "data" }, ReproducableBuild = true }; var builder = cliConfiguration.GetContainerBuilder(); var configuration = builder.ToBuildConfiguration(Containerizer.To(DockerDaemonImage.Named("target-image"))); Assert.AreEqual(ManifestFormat.OCI, configuration.GetTargetFormat()); Assert.AreEqual(layerConfigurations, configuration.GetLayerConfigurations()); ImageConfiguration imageConfiguration = configuration.GetBaseImageConfiguration(); Assert.AreEqual("reg.io", imageConfiguration.GetImageRegistry()); Assert.AreEqual("base-image", imageConfiguration.GetImageRepository()); Assert.AreEqual("tag", imageConfiguration.GetImageTag()); IContainerConfiguration containerConfiguration = configuration.GetContainerConfiguration(); Assert.AreEqual(new[] { "Entrypoint" }, containerConfiguration.GetEntrypoint()); Assert.AreEqual(new[] { "Program", "Arguments" }, containerConfiguration.GetProgramArguments()); Assert.AreEqual(new Dictionary <string, string> { ["Var"] = "Value" }, containerConfiguration.GetEnvironmentMap()); Assert.AreEqual(AbsoluteUnixPath.Get("/working/dir"), containerConfiguration.GetWorkingDirectory()); Assert.AreEqual("user", containerConfiguration.GetUser()); Assert.AreEqual(new[] { Port.Tcp(5000) }, containerConfiguration.GetExposedPorts()); Assert.AreEqual(new[] { AbsoluteUnixPath.Get("/volume") }, containerConfiguration.GetVolumes()); Assert.AreEqual(new Dictionary <string, string> { ["Label"] = "data" }, containerConfiguration.GetLabels()); Assert.AreEqual(ContainerConfiguration.DefaultCreationTime, containerConfiguration.GetCreationTime()); }
public void TestGet_notAbsolute() { try { AbsoluteUnixPath.Get("not/absolute"); Assert.Fail(); } catch (ArgumentException ex) { Assert.AreEqual( "Path does not start with forward slash (/): not/absolute", ex.Message); } }
public void TestResolve_Path_notRelative() { try { AbsoluteUnixPath.Get("/").Resolve(Paths.Get("/not/relative")); Assert.Fail(); } catch (ArgumentException ex) { Assert.AreEqual( "Cannot resolve against absolute Path: " + Paths.Get("/not/relative"), ex.Message); } }
public void TestResolve_relativeUnixPath() { AbsoluteUnixPath absoluteUnixPath1 = AbsoluteUnixPath.Get("/"); Assert.AreEqual(absoluteUnixPath1, absoluteUnixPath1.Resolve("")); Assert.AreEqual("/file", absoluteUnixPath1.Resolve("file").ToString()); Assert.AreEqual("/relative/path", absoluteUnixPath1.Resolve("relative/path").ToString()); AbsoluteUnixPath absoluteUnixPath2 = AbsoluteUnixPath.Get("/some/path"); Assert.AreEqual(absoluteUnixPath2, absoluteUnixPath2.Resolve("")); Assert.AreEqual("/some/path/file", absoluteUnixPath2.Resolve("file").ToString()); Assert.AreEqual( "/some/path/relative/path", absoluteUnixPath2.Resolve("relative/path").ToString()); }
public void TestVolumeListToMap() { ImmutableHashSet <AbsoluteUnixPath> input = ImmutableHashSet.Create( AbsoluteUnixPath.Get("/var/job-result-data"), AbsoluteUnixPath.Get("/var/log/my-app-logs")); ImmutableSortedDictionary <string, IDictionary <object, object> > expected = new Dictionary <string, IDictionary <object, object> > { ["/var/job-result-data"] = ImmutableDictionary.Create <object, object>(), ["/var/log/my-app-logs"] = ImmutableDictionary.Create <object, object>() }.ToImmutableSortedDictionary(); Assert.AreEqual(expected, ImageToJsonTranslator.VolumesSetToMap(input)); }
//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()); }
public async Task TestContainerize_configuredExecutorAsync() { FibContainerBuilder fibContainerBuilder = new FibContainerBuilder(RegistryImage.Named("base/image"), buildConfigurationBuilder) .SetEntrypoint(new[] { "entry", "point" }) .SetEnvironment(ImmutableDic.Of("name", "value")) .SetExposedPorts(ImmutableHashSet.Create(Port.Tcp(1234), Port.Udp(5678))) .SetLabels(ImmutableDic.Of("key", "value")) .SetProgramArguments(new[] { "program", "arguments" }) .SetCreationTime(DateTimeOffset.FromUnixTimeMilliseconds(1000)) .SetUser("user") .SetWorkingDirectory(AbsoluteUnixPath.Get("/working/directory")); IContainerizer mockContainerizer = CreateMockContainerizer(); await fibContainerBuilder.ContainerizeAsync(mockContainerizer).ConfigureAwait(false); }
/** * Lists the files in the {@code resourcePath} resources directory and builds a {@link * LayerConfiguration} from those files. */ private static ILayerConfiguration MakeLayerConfiguration( string resourcePath, string pathInContainer) { IEnumerable <SystemPath> fileStream = Files.List(Paths.Get(TestResources.GetResource(resourcePath).ToURI())); { LayerConfiguration.Builder layerConfigurationBuilder = LayerConfiguration.CreateBuilder(); foreach (SystemPath i in fileStream) { ((Func <SystemPath, LayerConfiguration.Builder>)(sourceFile => layerConfigurationBuilder.AddEntry( sourceFile, AbsoluteUnixPath.Get(pathInContainer + sourceFile.GetFileName()))))(i); } return(layerConfigurationBuilder.Build()); } }
public async Task TestBuild_permissionsAsync() { SystemPath testRoot = temporaryFolder.GetRoot().ToPath(); SystemPath folder = Files.CreateDirectories(testRoot.Resolve("files1")); SystemPath fileA = CreateFile(testRoot, "fileA", "abc", 54321); SystemPath fileB = CreateFile(testRoot, "fileB", "def", 54321); IBlob blob = new ReproducibleLayerBuilder( ImmutableArray.Create( DefaultLayerEntry(fileA, AbsoluteUnixPath.Get("/somewhere/fileA")), new LayerEntry( fileB, AbsoluteUnixPath.Get("/somewhere/fileB"), FilePermissions.FromOctalString("123"), LayerConfiguration.DefaultModifiedTime), new LayerEntry( folder, AbsoluteUnixPath.Get("/somewhere/folder"), FilePermissions.FromOctalString("456"), LayerConfiguration.DefaultModifiedTime))) .Build(); SystemPath tarFile = temporaryFolder.NewFile().ToPath(); using (Stream @out = new BufferedStream(Files.NewOutputStream(tarFile))) { await blob.WriteToAsync(@out).ConfigureAwait(false); } using (TarInputStream @in = new TarInputStream(Files.NewInputStream(tarFile))) { // Root folder (default folder permissions) TarEntry rootEntry = @in.GetNextEntry(); // fileA (default file permissions) TarEntry fileAEntry = @in.GetNextEntry(); // fileB (custom file permissions) TarEntry fileBEntry = @in.GetNextEntry(); // folder (custom folder permissions) TarEntry folderEntry = @in.GetNextEntry(); Assert.AreEqual("755", rootEntry.GetMode().ToOctalString()); Assert.AreEqual("644", fileAEntry.GetMode().ToOctalString()); Assert.AreEqual("123", fileBEntry.GetMode().ToOctalString()); Assert.AreEqual("456", folderEntry.GetMode().ToOctalString()); } }
public void SetUp() { SystemPath folder = temporaryFolder.NewFolder().ToPath(); SystemPath file1 = Files.CreateDirectory(folder.Resolve("files")); SystemPath file2 = Files.CreateFile(folder.Resolve("files").Resolve("two")); SystemPath file3 = Files.CreateFile(folder.Resolve("gile")); LayerEntry testLayerEntry1 = DefaultLayerEntry(file1, AbsoluteUnixPath.Get("/extraction/path")); LayerEntry testLayerEntry2 = DefaultLayerEntry(file2, AbsoluteUnixPath.Get("/extraction/path")); LayerEntry testLayerEntry3 = DefaultLayerEntry(file3, AbsoluteUnixPath.Get("/extraction/path")); LayerEntry testLayerEntry4 = new LayerEntry( file3, AbsoluteUnixPath.Get("/extraction/path"), FilePermissions.FromOctalString("755"), LayerConfiguration.DefaultModifiedTime); LayerEntry testLayerEntry5 = DefaultLayerEntry(file3, AbsoluteUnixPath.Get("/extraction/patha")); LayerEntry testLayerEntry6 = new LayerEntry( file3, AbsoluteUnixPath.Get("/extraction/patha"), FilePermissions.FromOctalString("755"), LayerConfiguration.DefaultModifiedTime); outOfOrderLayerEntries = ImmutableArray.Create( testLayerEntry4, testLayerEntry2, testLayerEntry6, testLayerEntry3, testLayerEntry1, testLayerEntry5); inOrderLayerEntries = ImmutableArray.Create( testLayerEntry1, testLayerEntry2, testLayerEntry3, testLayerEntry4, testLayerEntry5, testLayerEntry6); }
public async Task TestGenerateSelector_fileModifiedAsync() { SystemPath layerFile = temporaryFolder.NewFolder("testFolder").ToPath().Resolve("file"); Files.Write(layerFile, Encoding.UTF8.GetBytes("hello")); Files.SetLastModifiedTime(layerFile, FileTime.From(Instant.FromUnixTimeSeconds(0))); LayerEntry layerEntry = DefaultLayerEntry(layerFile, AbsoluteUnixPath.Get("/extraction/path")); DescriptorDigest expectedSelector = await GenerateSelectorAsync(ImmutableArray.Create(layerEntry)).ConfigureAwait(false); // Verify that changing modified time generates a different selector Files.SetLastModifiedTime(layerFile, FileTime.From(Instant.FromUnixTimeSeconds(1))); Assert.AreNotEqual( expectedSelector, await GenerateSelectorAsync(ImmutableArray.Create(layerEntry)).ConfigureAwait(false)); // Verify that changing modified time back generates same selector Files.SetLastModifiedTime(layerFile, FileTime.From(Instant.FromUnixTimeSeconds(0))); Assert.AreEqual( expectedSelector, await GenerateSelectorAsync(ImmutableArray.Create(layerEntry)).ConfigureAwait(false)); }
/** * Converts a map of volumes strings to a set of {@link AbsoluteUnixPath}s (e.g. {@code {@code * {"/var/log/my-app-logs":{}}} => AbsoluteUnixPath().get("/var/log/my-app-logs")}). * * @param volumeMap the map to convert * @return a set of {@link AbsoluteUnixPath}s */ public static ImmutableHashSet <AbsoluteUnixPath> VolumeMapToSet(IDictionary <string, IDictionary <object, object> > volumeMap) { if (volumeMap == null) { return(ImmutableHashSet.Create <AbsoluteUnixPath>()); } ImmutableHashSet <AbsoluteUnixPath> .Builder volumeList = ImmutableHashSet.CreateBuilder <AbsoluteUnixPath>(); foreach (string volume in volumeMap.Keys) { try { volumeList.Add(AbsoluteUnixPath.Get(volume)); } catch (ArgumentException) { throw new BadContainerConfigurationFormatException("Invalid volume path: " + volume); } } return(volumeList.ToImmutable()); }
public async Task TestToBlob_reproducibilityAsync() { SystemPath testRoot = temporaryFolder.GetRoot().ToPath(); SystemPath root1 = Files.CreateDirectories(testRoot.Resolve("files1")); SystemPath root2 = Files.CreateDirectories(testRoot.Resolve("files2")); // TODO: Currently this test only covers variation in order and modified time, even though // TODO: the code is designed to clean up userid/groupid, this test does not check that yet. const string contentA = "abcabc"; SystemPath fileA1 = CreateFile(root1, "fileA", contentA, 10000); SystemPath fileA2 = CreateFile(root2, "fileA", contentA, 20000); const string contentB = "yumyum"; SystemPath fileB1 = CreateFile(root1, "fileB", contentB, 10000); SystemPath fileB2 = CreateFile(root2, "fileB", contentB, 20000); // check if modified times are off Assert.AreNotEqual(Files.GetLastModifiedTime(fileA1), Files.GetLastModifiedTime(fileA2)); Assert.AreNotEqual(Files.GetLastModifiedTime(fileB1), Files.GetLastModifiedTime(fileB2)); // create layers of exact same content but ordered differently and with different timestamps IBlob layer = new ReproducibleLayerBuilder( ImmutableArray.Create( DefaultLayerEntry(fileA1, AbsoluteUnixPath.Get("/somewhere/fileA")), DefaultLayerEntry(fileB1, AbsoluteUnixPath.Get("/somewhere/fileB")))) .Build(); IBlob reproduced = new ReproducibleLayerBuilder( ImmutableArray.Create( DefaultLayerEntry(fileB2, AbsoluteUnixPath.Get("/somewhere/fileB")), DefaultLayerEntry(fileA2, AbsoluteUnixPath.Get("/somewhere/fileA")))) .Build(); byte[] layerContent = await Blobs.WriteToByteArrayAsync(layer).ConfigureAwait(false); byte[] reproducedLayerContent = await Blobs.WriteToByteArrayAsync(reproduced).ConfigureAwait(false); Assert.AreEqual(layerContent, reproducedLayerContent); }
public void TestToBuildConfiguration_containerConfigurationSet() { FibContainerBuilder fibContainerBuilder = new FibContainerBuilder(RegistryImage.Named("base/image"), buildConfigurationBuilder) .SetEntrypoint(new[] { "entry", "point" }) .SetEnvironment(ImmutableDictionary.CreateRange(new Dictionary <string, string> { ["name"] = "value" })) .SetExposedPorts(ImmutableHashSet.Create(Port.Tcp(1234), Port.Udp(5678))) .SetLabels(ImmutableDictionary.CreateRange(new Dictionary <string, string> { ["key"] = "value" })) .SetProgramArguments(new[] { "program", "arguments" }) .SetCreationTime(DateTimeOffset.FromUnixTimeMilliseconds(1000)) .SetUser("user") .SetWorkingDirectory(AbsoluteUnixPath.Get("/working/directory")); BuildConfiguration buildConfiguration = fibContainerBuilder.ToBuildConfiguration( Containerizer.To(RegistryImage.Named("target/image"))); IContainerConfiguration containerConfiguration = buildConfiguration.GetContainerConfiguration(); Assert.AreEqual(new[] { "entry", "point" }, containerConfiguration.GetEntrypoint()); Assert.AreEqual( ImmutableDictionary.CreateRange(new Dictionary <string, string> { ["name"] = "value" }), containerConfiguration.GetEnvironmentMap()); Assert.AreEqual( ImmutableHashSet.Create(Port.Tcp(1234), Port.Udp(5678)), containerConfiguration.GetExposedPorts()); Assert.AreEqual(ImmutableDictionary.CreateRange(new Dictionary <string, string> { ["key"] = "value" }), containerConfiguration.GetLabels()); Assert.AreEqual( new[] { "program", "arguments" }, containerConfiguration.GetProgramArguments()); Assert.AreEqual(Instant.FromUnixTimeMilliseconds(1000), containerConfiguration.GetCreationTime()); Assert.AreEqual("user", containerConfiguration.GetUser()); Assert.AreEqual( AbsoluteUnixPath.Get("/working/directory"), containerConfiguration.GetWorkingDirectory()); }
public void TestGenerateSelector_permissionsModified() { SystemPath layerFile = temporaryFolder.NewFolder("testFolder").ToPath().Resolve("file"); Files.Write(layerFile, Encoding.UTF8.GetBytes("hello")); LayerEntry layerEntry111 = new LayerEntry( layerFile, AbsoluteUnixPath.Get("/extraction/path"), FilePermissions.FromOctalString("111"), LayerConfiguration.DefaultModifiedTime); LayerEntry layerEntry222 = new LayerEntry( layerFile, AbsoluteUnixPath.Get("/extraction/path"), FilePermissions.FromOctalString("222"), LayerConfiguration.DefaultModifiedTime); // Verify that changing permissions generates a different selector Assert.AreNotEqual( GenerateSelectorAsync(ImmutableArray.Create(layerEntry111)), GenerateSelectorAsync(ImmutableArray.Create(layerEntry222))); }
public async Task TestOverrideWorkingDirectoryAsync() { Mock.Get(mockContainerConfiguration).Setup(m => m.GetWorkingDirectory()).Returns(AbsoluteUnixPath.Get("/my/directory")); Mock.Get(mockBuildAndCacheApplicationLayersStep).Setup(s => s.GetFuture()).Returns(Task.FromResult <IReadOnlyList <ICachedLayer> >(ImmutableArray.Create( mockDependenciesLayer, mockResourcesLayer, mockClassesLayer))); BuildImageStep buildImageStep = new BuildImageStep( mockBuildConfiguration, ProgressEventDispatcher.NewRoot(mockEventHandlers, "ignored", 1).NewChildProducer(), mockPullBaseImageStep, mockPullAndCacheBaseImageLayersStep, mockBuildAndCacheApplicationLayersStep); Image image = await buildImageStep.GetFuture().ConfigureAwait(false); Assert.AreEqual("/my/directory", image.GetWorkingDirectory()); }
public void TestBuilder() { const string expectedBaseImageServerUrl = "someserver"; const string expectedBaseImageName = "baseimage"; const string expectedBaseImageTag = "baseimagetag"; const string expectedTargetServerUrl = "someotherserver"; const string expectedTargetImageName = "targetimage"; const string expectedTargetTag = "targettag"; ISet <string> additionalTargetImageTags = ImmutableHashSet.Create("tag1", "tag2", "tag3"); ISet <string> expectedTargetImageTags = ImmutableHashSet.Create("targettag", "tag1", "tag2", "tag3"); IList <CredentialRetriever> credentialRetrievers = new List <CredentialRetriever> { () => Maybe.Of(Credential.From("username", "password")) }; Instant expectedCreationTime = Instant.FromUnixTimeSeconds(10000); IList <string> expectedEntrypoint = new[] { "some", "entrypoint" }; IList <string> expectedProgramArguments = new[] { "arg1", "arg2" }; IDictionary <string, string> expectedEnvironment = ImmutableDic.Of("key", "value"); ImmutableHashSet <Port> expectedExposedPorts = ImmutableHashSet.Create(Port.Tcp(1000), Port.Tcp(2000)); IDictionary <string, string> expectedLabels = ImmutableDic.Of("key1", "value1", "key2", "value2"); const ManifestFormat expectedTargetFormat = ManifestFormat.OCI; SystemPath expectedApplicationLayersCacheDirectory = Paths.Get("application/layers"); SystemPath expectedBaseImageLayersCacheDirectory = Paths.Get("base/image/layers"); IList <ILayerConfiguration> expectedLayerConfigurations = new List <ILayerConfiguration> { LayerConfiguration.CreateBuilder() .AddEntry(Paths.Get("sourceFile"), AbsoluteUnixPath.Get("/path/in/container")) .Build() }; const string expectedCreatedBy = "createdBy"; ImageConfiguration baseImageConfiguration = ImageConfiguration.CreateBuilder( ImageReference.Of( expectedBaseImageServerUrl, expectedBaseImageName, expectedBaseImageTag)) .Build(); ImageConfiguration targetImageConfiguration = ImageConfiguration.CreateBuilder( ImageReference.Of( expectedTargetServerUrl, expectedTargetImageName, expectedTargetTag)) .SetCredentialRetrievers(credentialRetrievers) .Build(); ContainerConfiguration containerConfiguration = ContainerConfiguration.CreateBuilder() .SetCreationTime(expectedCreationTime) .SetEntrypoint(expectedEntrypoint) .SetProgramArguments(expectedProgramArguments) .SetEnvironment(expectedEnvironment) .SetExposedPorts(expectedExposedPorts) .SetLabels(expectedLabels) .Build(); BuildConfiguration.Builder buildConfigurationBuilder = BuildConfiguration.CreateBuilder() .SetBaseImageConfiguration(baseImageConfiguration) .SetTargetImageConfiguration(targetImageConfiguration) .SetAdditionalTargetImageTags(additionalTargetImageTags) .SetContainerConfiguration(containerConfiguration) .SetApplicationLayersCacheDirectory(expectedApplicationLayersCacheDirectory) .SetBaseImageLayersCacheDirectory(expectedBaseImageLayersCacheDirectory) .SetTargetFormat(ImageFormat.OCI) .SetAllowInsecureRegistries(true) .SetLayerConfigurations(expectedLayerConfigurations) .SetToolName(expectedCreatedBy); BuildConfiguration buildConfiguration = buildConfigurationBuilder.Build(); Assert.IsNotNull(buildConfiguration.GetContainerConfiguration()); Assert.AreEqual( expectedCreationTime, buildConfiguration.GetContainerConfiguration().GetCreationTime()); Assert.AreEqual( expectedBaseImageServerUrl, buildConfiguration.GetBaseImageConfiguration().GetImageRegistry()); Assert.AreEqual( expectedBaseImageName, buildConfiguration.GetBaseImageConfiguration().GetImageRepository()); Assert.AreEqual( expectedBaseImageTag, buildConfiguration.GetBaseImageConfiguration().GetImageTag()); Assert.AreEqual( expectedTargetServerUrl, buildConfiguration.GetTargetImageConfiguration().GetImageRegistry()); Assert.AreEqual( expectedTargetImageName, buildConfiguration.GetTargetImageConfiguration().GetImageRepository()); Assert.AreEqual( expectedTargetTag, buildConfiguration.GetTargetImageConfiguration().GetImageTag()); Assert.AreEqual(expectedTargetImageTags, buildConfiguration.GetAllTargetImageTags()); Assert.AreEqual( Credential.From("username", "password"), buildConfiguration .GetTargetImageConfiguration() .GetCredentialRetrievers() [0] .Retrieve() .OrElseThrow(() => new AssertionException(""))); Assert.AreEqual( expectedProgramArguments, buildConfiguration.GetContainerConfiguration().GetProgramArguments()); Assert.AreEqual( expectedEnvironment, buildConfiguration.GetContainerConfiguration().GetEnvironmentMap()); Assert.AreEqual( expectedExposedPorts, buildConfiguration.GetContainerConfiguration().GetExposedPorts()); Assert.AreEqual(expectedLabels, buildConfiguration.GetContainerConfiguration().GetLabels()); Assert.AreEqual(expectedTargetFormat, buildConfiguration.GetTargetFormat()); Assert.AreEqual( expectedApplicationLayersCacheDirectory, buildConfigurationBuilder.GetApplicationLayersCacheDirectory()); Assert.AreEqual( expectedBaseImageLayersCacheDirectory, buildConfigurationBuilder.GetBaseImageLayersCacheDirectory()); Assert.IsTrue(buildConfiguration.GetAllowInsecureRegistries()); Assert.AreEqual(expectedLayerConfigurations, buildConfiguration.GetLayerConfigurations()); Assert.AreEqual( expectedEntrypoint, buildConfiguration.GetContainerConfiguration().GetEntrypoint()); Assert.AreEqual(expectedCreatedBy, buildConfiguration.GetToolName()); }
public void TestAddEntryRecursive_permissionsAndTimestamps() { SystemPath testDirectory = TestResources.GetResource("core/layer"); SystemPath testFile = TestResources.GetResource("core/fileA"); FilePermissions permissions1 = FilePermissions.FromOctalString("111"); FilePermissions permissions2 = FilePermissions.FromOctalString("777"); Instant timestamp1 = Instant.FromUnixTimeSeconds(123); Instant timestamp2 = Instant.FromUnixTimeSeconds(987); FilePermissions permissionsProvider(SystemPath _, AbsoluteUnixPath destination) => destination.ToString().StartsWith("/app/layer/a", StringComparison.Ordinal) ? permissions1 : permissions2; Instant timestampProvider(SystemPath _, AbsoluteUnixPath destination) => destination.ToString().StartsWith("/app/layer/a", StringComparison.Ordinal) ? timestamp1 : timestamp2; ILayerConfiguration layerConfiguration = LayerConfiguration.CreateBuilder() .AddEntryRecursive( testDirectory, AbsoluteUnixPath.Get("/app/layer/"), permissionsProvider, timestampProvider) .AddEntryRecursive( testFile, AbsoluteUnixPath.Get("/app/fileA"), permissionsProvider, timestampProvider) .Build(); ImmutableHashSet <LayerEntry> expectedLayerEntries = ImmutableHashSet.Create( new LayerEntry( testDirectory, AbsoluteUnixPath.Get("/app/layer/"), permissions2, timestamp2), new LayerEntry( testDirectory.Resolve("a"), AbsoluteUnixPath.Get("/app/layer/a/"), permissions1, timestamp1), new LayerEntry( testDirectory.Resolve("a/b"), AbsoluteUnixPath.Get("/app/layer/a/b/"), permissions1, timestamp1), new LayerEntry( testDirectory.Resolve("a/b/bar"), AbsoluteUnixPath.Get("/app/layer/a/b/bar/"), permissions1, timestamp1), new LayerEntry( testDirectory.Resolve("c/"), AbsoluteUnixPath.Get("/app/layer/c"), permissions2, timestamp2), new LayerEntry( testDirectory.Resolve("c/cat/"), AbsoluteUnixPath.Get("/app/layer/c/cat"), permissions2, timestamp2), new LayerEntry( testDirectory.Resolve("foo"), AbsoluteUnixPath.Get("/app/layer/foo"), permissions2, timestamp2), new LayerEntry(testFile, AbsoluteUnixPath.Get("/app/fileA"), permissions2, timestamp2)); CollectionAssert.AreEquivalent( expectedLayerEntries, ImmutableHashSet.CreateRange(layerConfiguration.LayerEntries)); }
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"); }
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); }