예제 #1
0
        /**
         * Retrieves the layer digest selected by the {@code selector}.
         *
         * @param selector the selector
         * @return the layer digest {@code selector} selects, if found
         * @throws CacheCorruptedException if the selector file contents was not a valid layer digest
         * @throws IOException if an I/O exception occurs
         */
        public Maybe <DescriptorDigest> Select(DescriptorDigest selector)
        {
            selector = selector ?? throw new ArgumentNullException(nameof(selector));
            SystemPath selectorFile = cacheStorageFiles.GetSelectorFile(selector);

            if (!Files.Exists(selectorFile))
            {
                return(Maybe.Empty <DescriptorDigest>());
            }
            string selectorFileContents =
                File.ReadAllText(selectorFile.ToFile().FullName, Encoding.UTF8);

            try
            {
                return(Maybe.Of(DescriptorDigest.FromHash(selectorFileContents)));
            }
            catch (DigestException)
            {
                throw new CacheCorruptedException(
                          cacheStorageFiles.GetCacheDirectory(),
                          "Expected valid layer digest as contents of selector file `"
                          + selectorFile
                          + "` for selector `"
                          + selector.GetHash()
                          + "`, but got: "
                          + selectorFileContents);
            }
        }
예제 #2
0
        public async Task TestPull_unknownBlobAsync()
        {
            localRegistry.PullAndPushToLocal("busybox", "busybox");
            DescriptorDigest nonexistentDigest =
                DescriptorDigest.FromHash(
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");

            RegistryClient registryClient =
                RegistryClient.CreateFactory(EventHandlers.NONE, "localhost:5000", "busybox")
                .SetAllowInsecureRegistries(true)
                .NewRegistryClient();

            try
            {
                await registryClient
                .PullBlob(nonexistentDigest, _ => { }, _ => { })
                .WriteToAsync(Stream.Null).ConfigureAwait(false);

                Assert.Fail("Trying to pull nonexistent blob should have errored");
            }
            catch (IOException ex) when(ex.InnerException is RegistryErrorException)
            {
                StringAssert.Contains(
                    ex.Message,
                    "pull BLOB for localhost:5000/busybox with digest " + nonexistentDigest);
            }
        }
예제 #3
0
        /**
         * Computes the hash and returns it along with the size of the bytes written to compute the hash.
         * The buffer resets after this method is called, so this method should only be called once per
         * computation.
         *
         * @return the computed hash and the size of the bytes consumed
         */
        public BlobDescriptor ComputeDigest()
        {
            Flush();
            try
            {
                byte[] hashedBytes = MessageDigest.Digest();

                // Encodes each hashed byte into 2-character hexadecimal representation.
                StringBuilder stringBuilder = new StringBuilder(2 * hashedBytes.Length);
                foreach (byte b in hashedBytes)
                {
                    stringBuilder.Append($"{b:x2}");
                }
                string hash = stringBuilder.ToString();

                BlobDescriptor blobDescriptor =
                    new BlobDescriptor(bytesSoFar, DescriptorDigest.FromHash(hash));
                bytesSoFar = 0;
                return(blobDescriptor);
            }
            catch (DigestException ex)
            {
                throw new Exception("SHA-256 algorithm produced invalid hash: " + ex.Message, ex);
            }
        }
예제 #4
0
        private IContainerizer CreateMockContainerizer()
        {
            ImageReference targetImage       = ImageReference.Parse("target-image");
            IContainerizer mockContainerizer = Mock.Of <IContainerizer>();
            IStepsRunner   stepsRunner       = Mock.Of <IStepsRunner>();
            IBuildResult   mockBuildResult   = Mock.Of <IBuildResult>();

            Mock.Get(mockContainerizer).Setup(m => m.GetImageConfiguration()).Returns(ImageConfiguration.CreateBuilder(targetImage).Build());

            Mock.Get(mockContainerizer).Setup(m => m.CreateStepsRunner(It.IsAny <BuildConfiguration>())).Returns(stepsRunner);

            Mock.Get(stepsRunner).Setup(s => s.RunAsync()).Returns(Task.FromResult(mockBuildResult));

            Mock.Get(mockBuildResult).Setup(m => m.GetImageDigest()).Returns(
                DescriptorDigest.FromHash(
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"));

            Mock.Get(mockBuildResult).Setup(m => m.GetImageId()).Returns(
                DescriptorDigest.FromHash(
                    "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"));

            Mock.Get(mockContainerizer).Setup(m => m.GetAdditionalTags()).Returns(new HashSet <string>());

            Mock.Get(mockContainerizer).Setup(m => m.GetBaseImageLayersCacheDirectory()).Returns(Paths.Get("/"));

            Mock.Get(mockContainerizer).Setup(m => m.GetApplicationLayersCacheDirectory()).Returns(Paths.Get("/"));

            Mock.Get(mockContainerizer).Setup(m => m.GetAllowInsecureRegistries()).Returns(false);

            Mock.Get(mockContainerizer).Setup(m => m.GetToolName()).Returns("mocktool");

            Mock.Get(mockContainerizer).Setup(m => m.BuildEventHandlers()).Returns(EventHandlers.NONE);

            return(mockContainerizer);
        }
예제 #5
0
        public void TestReadJsonWithLock()
        {
            SystemPath jsonFile = Paths.Get(TestResources.GetResource("core/json/basic.json").ToURI());

            // Deserializes into a metadata JSON object.
            TestJson testJson = JsonTemplateMapper.ReadJsonFromFileWithLock <TestJson>(jsonFile);

            Assert.AreEqual(testJson.Number, 54);
            Assert.AreEqual(testJson.Text, "crepecake");
            Assert.AreEqual(
                testJson.Digest,
                DescriptorDigest.FromDigest(
                    "sha256:8c662931926fa990b41da3c9f42663a537ccd498130030f9149173a0493832ad"));
            Assert.IsInstanceOf <TestJson.InnerObjectClass>(testJson.InnerObject);
            Assert.AreEqual(testJson.InnerObject.Number, 23);

            Assert.AreEqual(
                testJson.InnerObject.Texts, new[] { "first text", "second text" });

            Assert.AreEqual(testJson.InnerObject.Digests, new[]
            {
                DescriptorDigest.FromDigest("sha256:91e0cae00b86c289b33fee303a807ae72dd9f0315c16b74e6ab0cdbe9d996c10"),
                DescriptorDigest.FromHash("4945ba5011739b0b98c4a41afe224e417f47c7c99b2ce76830999c9a0861b236")
            });

            // ignore testJson.list
        }
예제 #6
0
        public void SetUpFakes()
        {
            fakeDigest =
                DescriptorDigest.FromHash(
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");

            testBlobChecker = new BlobChecker(fakeRegistryEndpointRequestProperties, new BlobDescriptor(fakeDigest));
        }
예제 #7
0
        public void TestCreateFromHash_pass()
        {
            string goodHash = CreateGoodHash('a');

            DescriptorDigest descriptorDigest = DescriptorDigest.FromHash(goodHash);

            Assert.AreEqual(goodHash, descriptorDigest.GetHash());
            Assert.AreEqual("sha256:" + goodHash, descriptorDigest.ToString());
        }
예제 #8
0
 public void SetUp()
 {
     layerDigest1 =
         DescriptorDigest.FromHash(
             "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
     layerDigest2 =
         DescriptorDigest.FromHash(
             "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");
 }
예제 #9
0
        public async Task TestPushAsync()
        {
            localRegistry.PullAndPushToLocal("busybox", "busybox");
            IBlob testLayerBlob = Blobs.From("crepecake");
            // Known digest for 'crepecake'
            DescriptorDigest testLayerBlobDigest =
                DescriptorDigest.FromHash(
                    "52a9e4d4ba4333ce593707f98564fee1e6d898db0d3602408c0b2a6a424d357c");
            IBlob            testContainerConfigurationBlob       = Blobs.From("12345");
            DescriptorDigest testContainerConfigurationBlobDigest =
                DescriptorDigest.FromHash(
                    "5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5");

            // Creates a valid image manifest.
            V22ManifestTemplate expectedManifestTemplate = new V22ManifestTemplate();

            expectedManifestTemplate.AddLayer(9, testLayerBlobDigest);
            expectedManifestTemplate.SetContainerConfiguration(5, testContainerConfigurationBlobDigest);

            // Pushes the BLOBs.
            RegistryClient registryClient =
                RegistryClient.CreateFactory(EVENT_HANDLERS, "localhost:5000", "testimage")
                .SetAllowInsecureRegistries(true)
                .NewRegistryClient();

            Assert.IsFalse(
                await registryClient.PushBlobAsync(testLayerBlobDigest, testLayerBlob, null, _ => { }).ConfigureAwait(false));
            Assert.IsFalse(
                await registryClient.PushBlobAsync(
                    testContainerConfigurationBlobDigest,
                    testContainerConfigurationBlob,
                    null,
                    _ => { }).ConfigureAwait(false));

            // Pushes the manifest.
            DescriptorDigest imageDigest = await registryClient.PushManifestAsync(expectedManifestTemplate, "latest").ConfigureAwait(false);

            // Pulls the manifest.
            V22ManifestTemplate manifestTemplate =
                await registryClient.PullManifestAsync <V22ManifestTemplate>("latest").ConfigureAwait(false);

            Assert.AreEqual(1, manifestTemplate.Layers.Count);
            Assert.AreEqual(testLayerBlobDigest, manifestTemplate.Layers[0].Digest);
            Assert.IsNotNull(manifestTemplate.GetContainerConfiguration());
            Assert.AreEqual(
                testContainerConfigurationBlobDigest,
                manifestTemplate.GetContainerConfiguration().Digest);

            // Pulls the manifest by digest.
            V22ManifestTemplate manifestTemplateByDigest =
                await registryClient.PullManifestAsync <V22ManifestTemplate>(imageDigest.ToString()).ConfigureAwait(false);

            Assert.AreEqual(
                await Digests.ComputeJsonDigestAsync(manifestTemplate).ConfigureAwait(false),
                await Digests.ComputeJsonDigestAsync(manifestTemplateByDigest).ConfigureAwait(false));
        }
예제 #10
0
        public void TestGetLayerFilename()
        {
            DescriptorDigest diffId =
                DescriptorDigest.FromHash(
                    "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb");

            Assert.AreEqual(
                "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb",
                TEST_CACHE_STORAGE_FILES.GetLayerFilename(diffId));
        }
예제 #11
0
 public void SetUpFakes()
 {
     fakeDescriptorDigest =
         DescriptorDigest.FromHash(
             "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
     testBlobPusher =
         new BlobPusher(
             new RegistryEndpointRequestProperties("someServerUrl", "someImageName"),
             fakeDescriptorDigest,
             TEST_BLOB,
             null);
 }
        public async Task TestCheck_doesNotExistAsync()
        {
            localRegistry.PullAndPushToLocal("busybox", "busybox");
            RegistryClient registryClient =
                RegistryClient.CreateFactory(EventHandlers.NONE, "localhost:5000", "busybox")
                .SetAllowInsecureRegistries(true)
                .NewRegistryClient();
            DescriptorDigest fakeBlobDigest =
                DescriptorDigest.FromHash(
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");

            Assert.IsFalse(await registryClient.CheckBlobAsync(new BlobDescriptor(fakeBlobDigest)).ConfigureAwait(false));
        }
예제 #13
0
        public void TestGetLayerDirectory()
        {
            DescriptorDigest layerDigest =
                DescriptorDigest.FromHash(
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");

            Assert.AreEqual(
                Paths.Get(
                    "cache",
                    "directory",
                    "layers",
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
                TEST_CACHE_STORAGE_FILES.GetLayerDirectory(layerDigest));
        }
예제 #14
0
        public void TestCreateFromHash_failIncorrectLength()
        {
            string badHash = CreateGoodHash('a') + 'a';

            try
            {
                DescriptorDigest.FromHash(badHash);
                Assert.Fail("Invalid hash should have caused digest creation failure.");
            }
            catch (DigestException ex)
            {
                Assert.AreEqual("Invalid hash: " + badHash, ex.Message);
            }
        }
예제 #15
0
        public void TestCreateFromHash_fail()
        {
            const string badHash = "not a valid hash";

            try
            {
                DescriptorDigest.FromHash(badHash);
                Assert.Fail("Invalid hash should have caused digest creation failure.");
            }
            catch (DigestException ex)
            {
                Assert.AreEqual("Invalid hash: " + badHash, ex.Message);
            }
        }
예제 #16
0
 /**
  * Gets the diff ID portion of the layer filename.
  *
  * @param layerFile the layer file to parse for the diff ID
  * @return the diff ID portion of the layer file filename
  * @throws CacheCorruptedException if no valid diff ID could be parsed
  */
 public DescriptorDigest GetDiffId(SystemPath layerFile)
 {
     try
     {
         layerFile = layerFile ?? throw new ArgumentNullException(nameof(layerFile));
         string diffId = layerFile.GetFileName().ToString();
         return(DescriptorDigest.FromHash(diffId));
     }
     catch (Exception ex) when(ex is DigestException || ex is IndexOutOfRangeException)
     {
         throw new CacheCorruptedException(
                   cacheDirectory, "Layer file did not include valid diff ID: " + layerFile, ex);
     }
 }
예제 #17
0
        public void TestGetSelectorFile()
        {
            DescriptorDigest selector =
                DescriptorDigest.FromHash(
                    "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc");

            Assert.AreEqual(
                Paths.Get(
                    "cache",
                    "directory",
                    "selectors",
                    "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"),
                TEST_CACHE_STORAGE_FILES.GetSelectorFile(selector));
        }
예제 #18
0
        public void TestWriteJson()
        {
            SystemPath jsonFile     = Paths.Get(TestResources.GetResource("core/json/basic.json").ToURI());
            string     expectedJson = Encoding.UTF8.GetString(Files.ReadAllBytes(jsonFile));

            TestJson testJson = new TestJson
            {
                Number = 54,
                Text   = "crepecake",
                Digest =
                    DescriptorDigest.FromDigest(
                        "sha256:8c662931926fa990b41da3c9f42663a537ccd498130030f9149173a0493832ad"),
                InnerObject = new TestJson.InnerObjectClass
                {
                    Number = 23,
                    Texts  = new List <string> {
                        "first text", "second text"
                    },
                    Digests = new[]
                    {
                        DescriptorDigest.FromDigest(
                            "sha256:91e0cae00b86c289b33fee303a807ae72dd9f0315c16b74e6ab0cdbe9d996c10"),
                        DescriptorDigest.FromHash(
                            "4945ba5011739b0b98c4a41afe224e417f47c7c99b2ce76830999c9a0861b236")
                    }
                }
            };

            TestJson.InnerObjectClass innerObject1 = new TestJson.InnerObjectClass
            {
                Number = 42,
                Texts  = new List <string>()
            };
            TestJson.InnerObjectClass innerObject2 = new TestJson.InnerObjectClass
            {
                Number = 99,
                Texts  = new List <string> {
                    "some text"
                },
                Digests =
                    new List <DescriptorDigest> {
                    DescriptorDigest.FromDigest(
                        "sha256:d38f571aa1c11e3d516e0ef7e513e7308ccbeb869770cb8c4319d63b10a0075e")
                }
            };
            testJson.List = new[] { innerObject1, innerObject2 };

            Assert.AreEqual(expectedJson, JsonTemplateMapper.ToUtf8String(testJson));
        }
예제 #19
0
 public void TestGetDiffId()
 {
     Assert.AreEqual(
         DescriptorDigest.FromHash(
             "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"),
         TEST_CACHE_STORAGE_FILES.GetDiffId(
             Paths.Get(
                 "layer",
                 "file",
                 "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb")));
     Assert.AreEqual(
         DescriptorDigest.FromHash(
             "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"),
         TEST_CACHE_STORAGE_FILES.GetDiffId(
             Paths.Get("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")));
 }
예제 #20
0
        public async Task TestPushAsync()
        {
            localRegistry.PullAndPushToLocal("busybox", "busybox");
            IBlob testBlob = Blobs.From("crepecake");
            // Known digest for 'crepecake'
            DescriptorDigest testBlobDigest =
                DescriptorDigest.FromHash(
                    "52a9e4d4ba4333ce593707f98564fee1e6d898db0d3602408c0b2a6a424d357c");

            RegistryClient registryClient =
                RegistryClient.CreateFactory(EventHandlers.NONE, "localhost:5000", "testimage")
                .SetAllowInsecureRegistries(true)
                .NewRegistryClient();

            Assert.IsFalse(await registryClient.PushBlobAsync(testBlobDigest, testBlob, null, _ => { }).ConfigureAwait(false));
        }
예제 #21
0
        public void SetUpFakes()
        {
            layerContentOutputStream = new MemoryStream();
            layerOutputStream        = new CountingDigestOutputStream(layerContentOutputStream);

            fakeDigest =
                DescriptorDigest.FromHash(
                    "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");

            testBlobPuller =
                new BlobPuller(
                    fakeRegistryEndpointRequestProperties,
                    fakeDigest,
                    layerOutputStream,
                    _ => { },
                    _ => { });
        }
        public async Task Test_smokeTestAsync()
        {
            foreach (KeyValuePair <string, string> knownHash in KNOWN_SHA256_HASHES)
            {
                string toHash       = knownHash.Key;
                string expectedHash = knownHash.Value;

                byte[] bytesToHash            = Encoding.UTF8.GetBytes(toHash);
                Stream underlyingOutputStream = new MemoryStream();
                using (CountingDigestOutputStream countingDigestOutputStream = new CountingDigestOutputStream(underlyingOutputStream))
                    using (Stream toHashInputStream = new MemoryStream(bytesToHash))
                    {
                        await toHashInputStream.CopyToAsync(countingDigestOutputStream).ConfigureAwait(false);

                        BlobDescriptor blobDescriptor = countingDigestOutputStream.ComputeDigest();
                        Assert.AreEqual(DescriptorDigest.FromHash(expectedHash), blobDescriptor.GetDigest());
                        Assert.AreEqual(bytesToHash.Length, blobDescriptor.GetSize());
                    }
            }
        }
예제 #23
0
        public void SetUpFakes()
        {
            DescriptorDigest mockDescriptorDigest1 = DescriptorDigest.FromHash(new string('a', 64));
            DescriptorDigest mockDescriptorDigest2 = DescriptorDigest.FromHash(new string('b', 64));
            DescriptorDigest mockDescriptorDigest3 = DescriptorDigest.FromHash(new string('c', 64));

            BlobDescriptor layerBlobDescriptor                  = new BlobDescriptor(0, mockDescriptorDigest1);
            BlobDescriptor referenceLayerBlobDescriptor         = new BlobDescriptor(0, mockDescriptorDigest2);
            BlobDescriptor referenceNoDiffIdLayerBlobDescriptor =
                new BlobDescriptor(0, mockDescriptorDigest3);
            // Intentionally the same digest as the mockLayer.
            BlobDescriptor anotherBlobDescriptor = new BlobDescriptor(0, mockDescriptorDigest1);

            Mock.Get(mockLayer).Setup(m => m.GetBlobDescriptor()).Returns(layerBlobDescriptor);

            Mock.Get(mockReferenceLayer).Setup(m => m.GetBlobDescriptor()).Returns(referenceLayerBlobDescriptor);

            Mock.Get(mockDigestOnlyLayer).Setup(m => m.GetBlobDescriptor()).Returns(referenceNoDiffIdLayerBlobDescriptor);

            Mock.Get(mockLayer2).Setup(m => m.GetBlobDescriptor()).Returns(anotherBlobDescriptor);
        }
예제 #24
0
        public void TestToJson()
        {
            // Loads the expected JSON string.
            SystemPath jsonFile     = Paths.Get(TestResources.GetResource("core/json/ocimanifest.json").ToURI());
            string     expectedJson = Encoding.UTF8.GetString(Files.ReadAllBytes(jsonFile));

            // Creates the JSON object to serialize.
            OCIManifestTemplate manifestJson = new OCIManifestTemplate();

            manifestJson.SetContainerConfiguration(
                1000,
                DescriptorDigest.FromDigest(
                    "sha256:8c662931926fa990b41da3c9f42663a537ccd498130030f9149173a0493832ad"));

            manifestJson.AddLayer(
                1000_000,
                DescriptorDigest.FromHash(
                    "4945ba5011739b0b98c4a41afe224e417f47c7c99b2ce76830999c9a0861b236"));

            // Serializes the JSON object.
            Assert.AreEqual(expectedJson, JsonTemplateMapper.ToUtf8String(manifestJson));
        }
예제 #25
0
        public async Task TestExecuteAsync_OutputsResult()
        {
            _objectUnderTest.ConfigFile =
                Path.Combine(TestContext.CurrentContext.TestDirectory, "Resources", "trivial-config.json");
            Mock.Get(_objectUnderTest.Containerizer)
            .Setup(c => c.CreateStepsRunner(It.IsAny <BuildConfiguration>()).RunAsync())
            .Returns(
                Task.FromResult(
                    Mock.Of <IBuildResult>(
                        r => r.GetImageDigest()
                        == DescriptorDigest.FromHash(new string('a', DescriptorDigest.HashLength)) &&
                        r.GetImageId()
                        == DescriptorDigest.FromHash(new string('b', DescriptorDigest.HashLength)))));
            await _objectUnderTest.ExecuteAsync(_output, _error).ConfigureAwait(false);

            Assert.That(
                _output.ToString(),
                Contains.Substring($"ImageDigest:sha256:{new string('a', DescriptorDigest.HashLength)}"));
            Assert.That(
                _output.ToString(),
                Contains.Substring($"ImageId:sha256:{new string('b', DescriptorDigest.HashLength)}"));
        }
예제 #26
0
        public void TestFromJson()
        {
            // Loads the JSON string.
            SystemPath jsonFile = Paths.Get(TestResources.GetResource("core/json/ocimanifest.json").ToURI());

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

            Assert.AreEqual(
                DescriptorDigest.FromDigest(
                    "sha256:8c662931926fa990b41da3c9f42663a537ccd498130030f9149173a0493832ad"),
                manifestJson.GetContainerConfiguration().Digest);

            Assert.AreEqual(1000, manifestJson.GetContainerConfiguration().Size);

            Assert.AreEqual(
                DescriptorDigest.FromHash(
                    "4945ba5011739b0b98c4a41afe224e417f47c7c99b2ce76830999c9a0861b236"),
                manifestJson.Layers[0].Digest);

            Assert.AreEqual(1000_000, manifestJson.Layers[0].Size);
        }
예제 #27
0
        /**
         * Lists all the layer digests stored.
         *
         * @return the list of layer digests
         * @throws CacheCorruptedException if the cache was found to be corrupted
         * @throws IOException if an I/O exception occurs
         */
        public ISet <DescriptorDigest> FetchDigests()
        {
            IEnumerable <SystemPath> layerDirectories = Files.List(cacheStorageFiles.GetLayersDirectory());

            IList <SystemPath>      layerDirectoriesList = layerDirectories.ToList();
            ISet <DescriptorDigest> layerDigests         = new HashSet <DescriptorDigest>();

            foreach (SystemPath layerDirectory in layerDirectoriesList)
            {
                try
                {
                    layerDigests.Add(DescriptorDigest.FromHash(layerDirectory.GetFileName().ToString()));
                }
                catch (DigestException ex)
                {
                    throw new CacheCorruptedException(
                              cacheStorageFiles.GetCacheDirectory(),
                              Resources.CacheStorageReaderNonDigestFileExceptionMessage,
                              ex);
                }
            }
            return(layerDigests);
        }
예제 #28
0
        public void TestUseAsMapKey()
        {
            DescriptorDigest descriptorDigestA1 = DescriptorDigest.FromHash(CreateGoodHash('a'));
            DescriptorDigest descriptorDigestA2 = DescriptorDigest.FromHash(CreateGoodHash('a'));
            DescriptorDigest descriptorDigestA3 =
                DescriptorDigest.FromDigest("sha256:" + CreateGoodHash('a'));
            DescriptorDigest descriptorDigestB = DescriptorDigest.FromHash(CreateGoodHash('b'));

            IDictionary <DescriptorDigest, string> digestMap = new Dictionary <DescriptorDigest, string>
            {
                [descriptorDigestA1] = "digest with a"
            };

            Assert.AreEqual("digest with a", digestMap[descriptorDigestA1]);
            Assert.AreEqual("digest with a", digestMap[descriptorDigestA2]);
            Assert.AreEqual("digest with a", digestMap[descriptorDigestA3]);
            Assert.IsFalse(digestMap.ContainsKey(descriptorDigestB));

            digestMap[descriptorDigestA2] = "digest with a";
            Assert.AreEqual("digest with a", digestMap[descriptorDigestA1]);
            Assert.AreEqual("digest with a", digestMap[descriptorDigestA2]);
            Assert.AreEqual("digest with a", digestMap[descriptorDigestA3]);
            Assert.IsFalse(digestMap.ContainsKey(descriptorDigestB));

            digestMap[descriptorDigestA3] = "digest with a";
            Assert.AreEqual("digest with a", digestMap[descriptorDigestA1]);
            Assert.AreEqual("digest with a", digestMap[descriptorDigestA2]);
            Assert.AreEqual("digest with a", digestMap[descriptorDigestA3]);
            Assert.IsFalse(digestMap.ContainsKey(descriptorDigestB));

            digestMap[descriptorDigestB] = "digest with b";
            Assert.AreEqual("digest with a", digestMap[descriptorDigestA1]);
            Assert.AreEqual("digest with a", digestMap[descriptorDigestA2]);
            Assert.AreEqual("digest with a", digestMap[descriptorDigestA3]);
            Assert.AreEqual("digest with b", digestMap[descriptorDigestB]);
        }
예제 #29
0
        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");
        }
예제 #30
0
        public async Task TestWriteToAsync()
        {
            SystemPath fileA     = Paths.Get(TestResources.GetResource("core/fileA").ToURI());
            SystemPath fileB     = Paths.Get(TestResources.GetResource("core/fileB").ToURI());
            long       fileASize = Files.Size(fileA);
            long       fileBSize = Files.Size(fileB);

            DescriptorDigest fakeDigestA =
                DescriptorDigest.FromHash(
                    "5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc5");
            DescriptorDigest fakeDigestB =
                DescriptorDigest.FromHash(
                    "5994471abb01112afcc18159f6cc74b4f511b99806da59b3caf5a9c173cacfc6");

            Mock.Get(mockLayer1).Setup(m => m.GetBlob()).Returns(Blobs.From(fileA));

            Mock.Get(mockLayer1).Setup(m => m.GetBlobDescriptor()).Returns(new BlobDescriptor(fileASize, fakeDigestA));

            Mock.Get(mockLayer1).Setup(m => m.GetDiffId()).Returns(fakeDigestA);

            Mock.Get(mockLayer2).Setup(m => m.GetBlob()).Returns(Blobs.From(fileB));

            Mock.Get(mockLayer2).Setup(m => m.GetBlobDescriptor()).Returns(new BlobDescriptor(fileBSize, fakeDigestB));

            Mock.Get(mockLayer2).Setup(m => m.GetDiffId()).Returns(fakeDigestB);

            Image testImage =
                Image.CreateBuilder(ManifestFormat.V22).AddLayer(mockLayer1).AddLayer(mockLayer2).Build();

            ImageTarball imageToTarball = new ImageTarball(testImage, ImageReference.Parse("my/image:tag"));

            MemoryStream @out = new MemoryStream();
            await imageToTarball.WriteToAsync(@out).ConfigureAwait(false);

            MemoryStream @in = new MemoryStream(@out.ToArray());

            using (TarInputStream tarArchiveInputStream = new TarInputStream(@in))
            {
                // Verifies layer with fileA was added.
                TarEntry headerFileALayer = tarArchiveInputStream.GetNextEntry();
                Assert.AreEqual(fakeDigestA.GetHash() + ".tar.gz", headerFileALayer.Name);
                string fileAString =
                    await new StreamReader(tarArchiveInputStream).ReadToEndAsync().ConfigureAwait(false);
                Assert.AreEqual(await Blobs.WriteToStringAsync(Blobs.From(fileA)).ConfigureAwait(false), fileAString);

                // Verifies layer with fileB was added.
                TarEntry headerFileBLayer = tarArchiveInputStream.GetNextEntry();
                Assert.AreEqual(fakeDigestB.GetHash() + ".tar.gz", headerFileBLayer.Name);
                string fileBString = await new StreamReader(tarArchiveInputStream).ReadToEndAsync().ConfigureAwait(false);
                Assert.AreEqual(await Blobs.WriteToStringAsync(Blobs.From(fileB)).ConfigureAwait(false), fileBString);

                // Verifies container configuration was added.
                TarEntry headerContainerConfiguration = tarArchiveInputStream.GetNextEntry();
                Assert.AreEqual("config.json", headerContainerConfiguration.Name);
                string containerConfigJson = await new StreamReader(tarArchiveInputStream).ReadToEndAsync().ConfigureAwait(false);
                JsonTemplateMapper.ReadJson <ContainerConfigurationTemplate>(containerConfigJson);

                // Verifies manifest was added.
                TarEntry headerManifest = tarArchiveInputStream.GetNextEntry();
                Assert.AreEqual("manifest.json", headerManifest.Name);
                string manifestJson = await new StreamReader(tarArchiveInputStream).ReadToEndAsync().ConfigureAwait(false);
                JsonTemplateMapper.ReadListOfJson <DockerLoadManifestEntryTemplate>(manifestJson);
            }
        }