コード例 #1
0
        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);
        }
コード例 #2
0
ファイル: CacheStorageWriter.cs プロジェクト: tiaotiao97/jib
        /**
         * Writes a V2.1 manifest for a given image reference.
         *
         * @param imageReference the image reference to store the metadata for
         * @param manifestTemplate the manifest
         */
        public async Task WriteMetadataAsync(IImageReference imageReference, V21ManifestTemplate manifestTemplate)
        {
            SystemPath imageDirectory = cacheStorageFiles.GetImageDirectory(imageReference);

            Files.CreateDirectories(imageDirectory);

            using (LockFile ignored1 = LockFile.Create(imageDirectory.Resolve("lock")))
            {
                await WriteMetadataAsync(manifestTemplate, imageDirectory.Resolve("manifest.json")).ConfigureAwait(false);
            }
        }
コード例 #3
0
        private static void SetupCachedMetadataV22(SystemPath cacheDirectory)
        {
            SystemPath imageDirectory = cacheDirectory.Resolve("images/test/image!tag");

            Files.CreateDirectories(imageDirectory);
            Files.Copy(
                Paths.Get(TestResources.GetResource("core/json/v22manifest.json").ToURI()),
                imageDirectory.Resolve("manifest.json"));
            Files.Copy(
                Paths.Get(TestResources.GetResource("core/json/containerconfig.json").ToURI()),
                imageDirectory.Resolve("config.json"));
        }
コード例 #4
0
ファイル: CacheStorageWriter.cs プロジェクト: tiaotiao97/jib
        /**
         * Writes an uncompressed {@code layerBlob} to the {@code layerDirectory}.
         *
         * @param uncompressedLayerBlob the uncompressed layer {@link Blob}
         * @param layerDirectory the directory for the layer
         * @return a {@link WrittenLayer} with the written layer information
         * @throws IOException if an I/O exception occurs
         */
        private async Task <WrittenLayer> WriteUncompressedLayerBlobToDirectoryAsync(
            IBlob uncompressedLayerBlob, SystemPath layerDirectory)
        {
            using (TemporaryFile temporaryLayerFile = CacheStorageFiles.GetTemporaryLayerFile(layerDirectory))
            {
                DescriptorDigest layerDiffId;
                BlobDescriptor   blobDescriptor;

                // Writes the layer with GZIP compression. The original bytes are captured as the layer's
                // diff ID and the bytes outputted from the GZIP compression are captured as the layer's
                // content descriptor.
                using (CountingDigestOutputStream compressedDigestOutputStream =
                           new CountingDigestOutputStream(
                               Files.NewOutputStream(temporaryLayerFile.Path)))
                {
                    using (GZipStream compressorStream = new GZipStream(compressedDigestOutputStream, CompressionMode.Compress, true))
                    {
                        BlobDescriptor descriptor = await uncompressedLayerBlob.WriteToAsync(compressorStream).ConfigureAwait(false);

                        layerDiffId = descriptor.GetDigest();
                    }
                    // The GZIPOutputStream must be closed in order to write out the remaining compressed data.
                    blobDescriptor = compressedDigestOutputStream.ComputeDigest();
                }
                DescriptorDigest layerDigest = blobDescriptor.GetDigest();
                long             layerSize   = blobDescriptor.GetSize();

                // Renames the temporary layer file to the correct filename.
                SystemPath layerFile = layerDirectory.Resolve(cacheStorageFiles.GetLayerFilename(layerDiffId));
                temporaryLayerFile.MoveIfDoesNotExist(layerFile);

                return(new WrittenLayer(layerDigest, layerDiffId, layerSize));
            }
        }
コード例 #5
0
        public void TestClose_directoryNotDeletedIfMoved()
        {
            SystemPath destinationParent = temporaryFolder.NewFolder().ToPath();

            using (TemporaryDirectory temporaryDirectory =
                       new TemporaryDirectory(temporaryFolder.NewFolder().ToPath()))
            {
                CreateFilesInDirectory(temporaryDirectory.GetDirectory());

                Assert.IsFalse(Files.Exists(destinationParent.Resolve("destination")));
                Files.Move(temporaryDirectory.GetDirectory(), destinationParent.Resolve("destination"));

                temporaryDirectory.Dispose();
                Assert.IsFalse(Files.Exists(temporaryDirectory.GetDirectory()));
                Assert.IsTrue(Files.Exists(destinationParent.Resolve("destination")));
            }
        }
コード例 #6
0
        private static void CreateFilesInDirectory(SystemPath directory)
        {
            SystemPath testFilesDirectory = Paths.Get(TestResources.GetResource("core/layer").ToURI());

            new DirectoryWalker(testFilesDirectory)
            .FilterRoot()
            .Walk(path =>
            {
                if (File.Exists(path))
                {
                    Files.Copy(path, directory.Resolve(testFilesDirectory.Relativize(path)));
                }
                else if (Directory.Exists(path))
                {
                    Directory.CreateDirectory(directory.Resolve(testFilesDirectory.Relativize(path)));
                }
            });
        }
コード例 #7
0
        private SystemPath CreateFile(SystemPath root, string filename, string content, long lastModifiedTime)
        {
            SystemPath newFile =
                Files.Write(
                    root.Resolve(filename),
                    Encoding.UTF8.GetBytes(content));

            Files.SetLastModifiedTime(newFile, FileTime.FromMillis(lastModifiedTime));
            return(newFile);
        }
コード例 #8
0
ファイル: CacheStorageWriter.cs プロジェクト: tiaotiao97/jib
        /**
         * Saves the manifest and container configuration for a V2.2 or OCI image.
         *
         * @param imageReference the image reference to store the metadata for
         * @param manifestTemplate the manifest
         * @param containerConfiguration the container configuration
         */
        public async Task WriteMetadataAsync(
            IImageReference imageReference,
            IBuildableManifestTemplate manifestTemplate,
            ContainerConfigurationTemplate containerConfiguration)
        {
            manifestTemplate = manifestTemplate ?? throw new ArgumentNullException(nameof(manifestTemplate));
            Preconditions.CheckNotNull(manifestTemplate.GetContainerConfiguration());
            Preconditions.CheckNotNull(manifestTemplate.GetContainerConfiguration().Digest);

            SystemPath imageDirectory = cacheStorageFiles.GetImageDirectory(imageReference);

            Files.CreateDirectories(imageDirectory);

            using (LockFile ignored1 = LockFile.Create(imageDirectory.Resolve("lock")))
            {
                await WriteMetadataAsync(manifestTemplate, imageDirectory.Resolve("manifest.json")).ConfigureAwait(false);
                await WriteMetadataAsync(containerConfiguration, imageDirectory.Resolve("config.json")).ConfigureAwait(false);
            }
        }
コード例 #9
0
        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);
        }
コード例 #10
0
        public async Task TestWriteMetadata_v21Async()
        {
            SystemPath manifestJsonFile =
                Paths.Get(TestResources.GetResource("core/json/v21manifest.json").ToURI());
            V21ManifestTemplate manifestTemplate =
                JsonTemplateMapper.ReadJsonFromFile <V21ManifestTemplate>(manifestJsonFile);
            ImageReference imageReference = ImageReference.Parse("image.reference/project/thing:tag");

            await new CacheStorageWriter(cacheStorageFiles).WriteMetadataAsync(imageReference, manifestTemplate).ConfigureAwait(false);

            SystemPath savedManifestPath =
                cacheRoot.Resolve("images/image.reference/project/thing!tag/manifest.json");

            Assert.IsTrue(Files.Exists(savedManifestPath));

            V21ManifestTemplate savedManifest =
                JsonTemplateMapper.ReadJsonFromFile <V21ManifestTemplate>(savedManifestPath);

            Assert.AreEqual("amd64", savedManifest.GetContainerConfiguration().Get().Architecture);
        }
コード例 #11
0
        public void TestGetImageDirectory()
        {
            SystemPath imagesDirectory = Paths.Get("cache", "directory", "images");

            Assert.AreEqual(imagesDirectory, TEST_CACHE_STORAGE_FILES.GetImagesDirectory());

            Assert.AreEqual(
                imagesDirectory.Resolve("reg.istry/repo/sitory!tag"),
                TEST_CACHE_STORAGE_FILES.GetImageDirectory(
                    ImageReference.Parse("reg.istry/repo/sitory:tag")));
            Assert.AreEqual(
                imagesDirectory.Resolve(
                    "reg.istry/repo!sha256!aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
                TEST_CACHE_STORAGE_FILES.GetImageDirectory(
                    ImageReference.Parse(
                        "reg.istry/repo@sha256:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")));
            Assert.AreEqual(
                imagesDirectory.Resolve("reg.istry!5000/repo/sitory!tag"),
                TEST_CACHE_STORAGE_FILES.GetImageDirectory(
                    ImageReference.Parse("reg.istry:5000/repo/sitory:tag")));
        }
コード例 #12
0
        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));
        }
コード例 #13
0
        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>();
        }
コード例 #14
0
        /** Starts the registry */
        public async Task StartAsync()
        {
            // Runs the Docker registry.
            List <string> dockerTokens = new List <string> {
                "run",
                "--rm",
                "-d",
                "-p",
                port + ":5000",
                "--name",
                containerName
            };

            if (username != null && password != null)
            {
                // Generate the htpasswd file to store credentials
                string credentialString =
                    new Command(
                        "docker",
                        "run",
                        "--rm",
                        "--entrypoint",
                        "htpasswd",
                        "registry",
                        "-Bbn",
                        username,
                        password)
                    .Run();
                // Creates the temporary directory in /tmp since that is one of the default directories
                // mounted into Docker.
                // See: https://docs.docker.com/docker-for-mac/osxfs
                SystemPath tempFolder = Files.CreateTempDirectory(Paths.Get(Path.GetTempPath()), "");
                Files.Write(
                    tempFolder.Resolve("htpasswd"), Encoding.UTF8.GetBytes(credentialString));

                // Run the Docker registry
                dockerTokens.AddRange(new[] {
                    "-v",
                    // Volume mount used for storing credentials
                    tempFolder + ":/auth",
                    "-e",
                    "REGISTRY_AUTH=htpasswd",
                    "-e",
                    "REGISTRY_AUTH_HTPASSWD_REALM=\"Registry Realm\"",
                    "-e",
                    "REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd"
                });
            }
            dockerTokens.Add("registry");
            new Command("docker", dockerTokens).Run();
            await WaitUntilReadyAsync().ConfigureAwait(false);
        }
コード例 #15
0
        public void TestCopy()
        {
            SystemPath destDir  = temporaryFolder.NewFolder().ToPath();
            SystemPath libraryA =
                Paths.Get(TestResources.GetResource("core/application/dependencies/libraryA.jar").ToURI());
            SystemPath libraryB =
                Paths.Get(TestResources.GetResource("core/application/dependencies/libraryB.jar").ToURI());
            SystemPath dirLayer = Paths.Get(TestResources.GetResource("core/layer").ToURI());

            FileOperations.Copy(ImmutableArray.Create(libraryA, libraryB, dirLayer), destDir);

            AssertFilesEqual(libraryA, destDir.Resolve("libraryA.jar"));
            AssertFilesEqual(libraryB, destDir.Resolve("libraryB.jar"));
            Assert.IsTrue(Files.Exists(destDir.Resolve("layer").Resolve("a").Resolve("b")));
            Assert.IsTrue(Files.Exists(destDir.Resolve("layer").Resolve("c")));
            AssertFilesEqual(
                dirLayer.Resolve("a").Resolve("b").Resolve("bar"),
                destDir.Resolve("layer").Resolve("a").Resolve("b").Resolve("bar"));
            AssertFilesEqual(
                dirLayer.Resolve("c").Resolve("cat"), destDir.Resolve("layer").Resolve("c").Resolve("cat"));
            AssertFilesEqual(dirLayer.Resolve("foo"), destDir.Resolve("layer").Resolve("foo"));
        }
コード例 #16
0
        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);
        }
コード例 #17
0
        /**
         * Gets the directory corresponding to the given image reference.
         *
         * @param imageReference the image reference
         * @return a path in the form of {@code
         *     (fib-cache)/images/registry[!port]/repository!(tag|digest-type!digest)}
         */
        public SystemPath GetImageDirectory(IImageReference imageReference)
        {
            imageReference = imageReference ?? throw new ArgumentNullException(nameof(imageReference));
            // Replace ':' and '@' with '!' to avoid directory-naming restrictions
            string replacedReference = imageReference.ToStringWithTag().Replace(':', '!').Replace('@', '!');

            // Split image reference on '/' to build directory structure
            IEnumerable <string> directories = Splitter.On('/').Split(replacedReference);
            SystemPath           destination = GetImagesDirectory();

            foreach (string dir in directories)
            {
                destination = destination.Resolve(dir);
            }
            return(destination);
        }
コード例 #18
0
        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());
            }
        }
コード例 #19
0
ファイル: CacheStorageWriter.cs プロジェクト: tiaotiao97/jib
        /**
         * Writes a compressed {@code layerBlob} to the {@code layerDirectory}.
         *
         * @param compressedLayerBlob the compressed layer {@link Blob}
         * @param layerDirectory the directory for the layer
         * @return a {@link WrittenLayer} with the written layer information
         * @throws IOException if an I/O exception occurs
         */
        private async Task <WrittenLayer> WriteCompressedLayerBlobToDirectoryAsync(
            IBlob compressedLayerBlob, SystemPath layerDirectory)
        {
            // Writes the layer file to the temporary directory.
            using (TemporaryFile temporaryLayerFile = CacheStorageFiles.GetTemporaryLayerFile(layerDirectory))
            {
                BlobDescriptor layerBlobDescriptor;
                using (Stream fileOutputStream = Files.NewOutputStream(temporaryLayerFile.Path))
                {
                    layerBlobDescriptor = await compressedLayerBlob.WriteToAsync(fileOutputStream).ConfigureAwait(false);
                }

                // Gets the diff ID.
                DescriptorDigest layerDiffId = await GetDiffIdByDecompressingFileAsync(temporaryLayerFile.Path).ConfigureAwait(false);

                // Renames the temporary layer file to the correct filename.
                SystemPath layerFile = layerDirectory.Resolve(cacheStorageFiles.GetLayerFilename(layerDiffId));
                temporaryLayerFile.MoveIfDoesNotExist(layerFile);

                return(new WrittenLayer(
                           layerBlobDescriptor.GetDigest(), layerDiffId, layerBlobDescriptor.GetSize()));
            }
        }
コード例 #20
0
        public void TestWalk()
        {
            new DirectoryWalker(testDir).Walk(addToWalkedPaths);

            ISet <SystemPath> expectedPaths = new HashSet <SystemPath>
            {
                testDir,
                testDir.Resolve("a"),
                testDir.Resolve("a").Resolve("b"),
                testDir.Resolve("a").Resolve("b").Resolve("bar"),
                testDir.Resolve("c"),
                testDir.Resolve("c").Resolve("cat"),
                testDir.Resolve("foo")
            };

            Assert.AreEqual(expectedPaths, walkedPaths);
        }
コード例 #21
0
        public async Task TestBuild_parentDirBehaviorAsync()
        {
            SystemPath testRoot = temporaryFolder.GetRoot().ToPath();

            // the path doesn't really matter on source files, but these are structured
            SystemPath parent        = Files.CreateDirectories(testRoot.Resolve("aaa"));
            SystemPath fileA         = Files.CreateFile(parent.Resolve("fileA"));
            SystemPath ignoredParent = Files.CreateDirectories(testRoot.Resolve("bbb-ignored"));
            SystemPath fileB         = Files.CreateFile(ignoredParent.Resolve("fileB"));
            SystemPath fileC         =
                Files.CreateFile(Files.CreateDirectories(testRoot.Resolve("ccc-absent")).Resolve("fileC"));

            IBlob layer =
                new ReproducibleLayerBuilder(
                    ImmutableArray.Create(
                        new LayerEntry(
                            parent,
                            AbsoluteUnixPath.Get("/root/aaa"),
                            FilePermissions.FromOctalString("111"),
                            Instant.FromUnixTimeSeconds(10)),
                        new LayerEntry(
                            fileA,
                            AbsoluteUnixPath.Get("/root/aaa/fileA"),
                            FilePermissions.FromOctalString("222"),
                            Instant.FromUnixTimeSeconds(20)),
                        new LayerEntry(
                            fileB,
                            AbsoluteUnixPath.Get("/root/bbb-ignored/fileB"),
                            FilePermissions.FromOctalString("333"),
                            Instant.FromUnixTimeSeconds(30)),
                        new LayerEntry(
                            ignoredParent,
                            AbsoluteUnixPath.Get("/root/bbb-ignored"),
                            FilePermissions.FromOctalString("444"),
                            Instant.FromUnixTimeSeconds(40)),
                        new LayerEntry(
                            fileC,
                            AbsoluteUnixPath.Get("/root/ccc-absent/file3"),
                            FilePermissions.FromOctalString("555"),
                            Instant.FromUnixTimeSeconds(50))))
                .Build();

            SystemPath tarFile = temporaryFolder.NewFile().ToPath();

            using (Stream @out = new BufferedStream(Files.NewOutputStream(tarFile)))
            {
                await layer.WriteToAsync(@out).ConfigureAwait(false);
            }

            using (TarInputStream @in = new TarInputStream(Files.NewInputStream(tarFile)))
            {
                // root (default folder permissions)
                TarEntry root = @in.GetNextEntry();
                Assert.AreEqual("755", root.GetMode().ToOctalString());
                Assert.AreEqual(Instant.FromUnixTimeSeconds(1), Instant.FromDateTimeUtc(DateTime.SpecifyKind(root.ModTime, DateTimeKind.Utc)));

                // parentAAA (custom permissions, custom timestamp)
                TarEntry rootParentAAA = @in.GetNextEntry();
                Assert.AreEqual("111", rootParentAAA.GetMode().ToOctalString());
                Assert.AreEqual(Instant.FromUnixTimeSeconds(10), Instant.FromDateTimeUtc(DateTime.SpecifyKind(rootParentAAA.ModTime, DateTimeKind.Utc)));

                // skip over fileA
                @in.GetNextEntry();

                // parentBBB (default permissions - ignored custom permissions, since fileB added first)
                TarEntry rootParentBBB = @in.GetNextEntry();
                // TODO (#1650): we want 040444 here.
                Assert.AreEqual("755", rootParentBBB.GetMode().ToOctalString());
                // TODO (#1650): we want Instant.ofEpochSecond(40) here.
                Assert.AreEqual(Instant.FromUnixTimeSeconds(1), Instant.FromDateTimeUtc(DateTime.SpecifyKind(root.ModTime, DateTimeKind.Utc)));

                // skip over fileB
                @in.GetNextEntry();

                // parentCCC (default permissions - no entry provided)
                TarEntry rootParentCCC = @in.GetNextEntry();
                Assert.AreEqual("755", rootParentCCC.GetMode().ToOctalString());
                Assert.AreEqual(Instant.FromUnixTimeSeconds(1), Instant.FromDateTimeUtc(DateTime.SpecifyKind(root.ModTime, DateTimeKind.Utc)));

                // we don't care about fileC
            }
        }
コード例 #22
0
ファイル: CacheStorageReader.cs プロジェクト: tiaotiao97/jib
        /**
         * Retrieves the cached manifest and container configuration for an image reference.
         *
         * @param imageReference the image reference
         * @return the manifest and container configuration for the image reference, if found
         * @throws IOException if an I/O exception occurs
         * @throws CacheCorruptedException if the cache is corrupted
         */
        public Maybe <ManifestAndConfig> RetrieveMetadata(IImageReference imageReference)
        {
            SystemPath imageDirectory = cacheStorageFiles.GetImageDirectory(imageReference);
            SystemPath manifestPath   = imageDirectory.Resolve("manifest.json");

            if (!Files.Exists(manifestPath))
            {
                return(Maybe.Empty <ManifestAndConfig>());
            }

            // TODO: Consolidate with ManifestPuller
            JToken token;

            using (JsonTextReader reader = new JsonTextReader(File.OpenText(manifestPath)))
            {
                token = JToken.ReadFrom(reader);
            }
            if (!(token is JObject node))
            {
                throw new CacheCorruptedException(
                          cacheStorageFiles.GetCacheDirectory(),
                          Resources.CacheStorageReaderNotJsonExecpetionMessage);
            }
            if (!node.ContainsKey("schemaVersion"))
            {
                throw new CacheCorruptedException(
                          cacheStorageFiles.GetCacheDirectory(),
                          Resources.CacheStorageReaderSchemaVersionMissingExecpetionMessage);
            }

            int schemaVersion = node["schemaVersion"].Value <int>();

            if (schemaVersion == -1)
            {
                throw new CacheCorruptedException(
                          cacheStorageFiles.GetCacheDirectory(),
                          Resources.CacheStorageReaderInvalidSchemaVersionExecpetionMessageFormat);
            }

            if (schemaVersion == 1)
            {
                return(Maybe.Of(
                           new ManifestAndConfig(
                               JsonTemplateMapper.ReadJsonFromFile <V21ManifestTemplate>(manifestPath),
                               null)));
            }
            if (schemaVersion == 2)
            {
                // 'schemaVersion' of 2 can be either Docker V2.2 or OCI.
                string mediaType = node["mediaType"].Value <string>();

                IManifestTemplate manifestTemplate;
                if (V22ManifestTemplate.ManifestMediaType == mediaType)
                {
                    manifestTemplate =
                        JsonTemplateMapper.ReadJsonFromFile <V22ManifestTemplate>(manifestPath);
                }
                else if (OCIManifestTemplate.ManifestMediaType == mediaType)
                {
                    manifestTemplate =
                        JsonTemplateMapper.ReadJsonFromFile <OCIManifestTemplate>(manifestPath);
                }
                else
                {
                    throw new CacheCorruptedException(
                              cacheStorageFiles.GetCacheDirectory(),
                              string.Format(
                                  CultureInfo.CurrentCulture,
                                  Resources.CacheStorageReaderUnknownMediaTypeExecpetionMessageFormat, mediaType));
                }

                SystemPath configPath = imageDirectory.Resolve("config.json");
                if (!Files.Exists(configPath))
                {
                    throw new CacheCorruptedException(
                              cacheStorageFiles.GetCacheDirectory(),
                              Resources.CacheStorageReaderContainerConfigurationMissingExecpetionMessage);
                }
                ContainerConfigurationTemplate config =
                    JsonTemplateMapper.ReadJsonFromFile <ContainerConfigurationTemplate>(configPath);

                return(Maybe.Of(new ManifestAndConfig(manifestTemplate, config)));
            }
            throw new CacheCorruptedException(
                      cacheStorageFiles.GetCacheDirectory(),
                      string.Format(
                          CultureInfo.CurrentCulture,
                          Resources.CacheStorageReaderInvalidSchemaVersionExecpetionMessageFormat, schemaVersion));
        }
コード例 #23
0
 internal static TemporaryFile CreateTempFile(SystemPath systemPath)
 {
     return(new TemporaryFile(systemPath.Resolve(Path.GetRandomFileName())));
 }
コード例 #24
0
 /**
  * Resolves a selector file.
  *
  * @param selector the selector digest
  * @return the selector file
  */
 public SystemPath GetSelectorFile(DescriptorDigest selector)
 {
     selector = selector ?? throw new ArgumentNullException(nameof(selector));
     return(cacheDirectory.Resolve(SELECTORS_DIRECTORY).Resolve(selector.GetHash()));
 }
コード例 #25
0
        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));
        }
コード例 #26
0
 /**
  * Resolves a file to use as a temporary file to write layer contents to.
  *
  * @param layerDirectory the directory in which to resolve the temporary layer file
  * @return the temporary layer file
  */
 public static TemporaryFile GetTemporaryLayerFile(SystemPath layerDirectory)
 {
     layerDirectory = layerDirectory ?? throw new ArgumentNullException(nameof(layerDirectory));
     return(new TemporaryFile(layerDirectory.Resolve(TEMPORARY_LAYER_FILE_NAME)));
 }