Rename spring-boot-cloudnativebuildpack
Rename the `spring-boot-cloudnativebuildpack` module to `spring-boot-buildpack-platform` and update the the package name to `org.springframework.boot.buildpack.platform`. Closes gh-19851
This commit is contained in:
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.build;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
||||
/**
|
||||
* Tests for {@link ApiVersion}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ApiVersionTests {
|
||||
|
||||
@Test
|
||||
void parseWhenVersionIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> ApiVersion.parse(null))
|
||||
.withMessage("Value must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseWhenVersionIsEmptyThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> ApiVersion.parse(""))
|
||||
.withMessage("Value must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseWhenVersionDoesNotMatchPatternThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> ApiVersion.parse("bad"))
|
||||
.withMessage("Malformed version number 'bad'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseReturnsVersion() {
|
||||
ApiVersion version = ApiVersion.parse("1.2");
|
||||
assertThat(version.getMajor()).isEqualTo(1);
|
||||
assertThat(version.getMinor()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void assertSupportsWhenSupports() {
|
||||
ApiVersion.parse("1.2").assertSupports(ApiVersion.parse("1.0"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void assertSupportsWhenDoesNotSupportThrowsException() {
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> ApiVersion.parse("1.2").assertSupports(ApiVersion.parse("1.3")))
|
||||
.withMessage("Version 'v1.3' is not supported by this version ('v1.2')");
|
||||
}
|
||||
|
||||
@Test
|
||||
void supportWhenSame() {
|
||||
assertThat(supports("0.0", "0.0")).isTrue();
|
||||
assertThat(supports("0.1", "0.1")).isTrue();
|
||||
assertThat(supports("1.0", "1.0")).isTrue();
|
||||
assertThat(supports("1.1", "1.1")).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void supportsWhenDifferentMajor() {
|
||||
assertThat(supports("0.0", "1.0")).isFalse();
|
||||
assertThat(supports("1.0", "0.0")).isFalse();
|
||||
assertThat(supports("1.0", "2.0")).isFalse();
|
||||
assertThat(supports("2.0", "1.0")).isFalse();
|
||||
assertThat(supports("1.1", "2.1")).isFalse();
|
||||
assertThat(supports("2.1", "1.1")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void supportsWhenDifferentMinor() {
|
||||
assertThat(supports("1.2", "1.1")).isTrue();
|
||||
assertThat(supports("1.2", "1.3")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void supportWhenMajorZeroAndDifferentMinor() {
|
||||
assertThat(supports("0.2", "0.1")).isFalse();
|
||||
assertThat(supports("0.2", "0.3")).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringReturnsString() {
|
||||
assertThat(ApiVersion.parse("1.2").toString()).isEqualTo("v1.2");
|
||||
}
|
||||
|
||||
@Test
|
||||
void equalsAndHashCode() {
|
||||
ApiVersion v12a = ApiVersion.parse("1.2");
|
||||
ApiVersion v12b = ApiVersion.parse("1.2");
|
||||
ApiVersion v13 = ApiVersion.parse("1.3");
|
||||
assertThat(v12a.hashCode()).isEqualTo(v12b.hashCode());
|
||||
assertThat(v12a).isEqualTo(v12a).isEqualTo(v12b).isNotEqualTo(v13);
|
||||
}
|
||||
|
||||
private boolean supports(String v1, String v2) {
|
||||
return ApiVersion.parse(v1).supports(ApiVersion.parse(v2));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.build;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link BuildLog}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class BuildLogTests {
|
||||
|
||||
@Test
|
||||
void toSystemOutPrintsToSystemOut() {
|
||||
BuildLog log = BuildLog.toSystemOut();
|
||||
assertThat(log).isInstanceOf(PrintStreamBuildLog.class);
|
||||
assertThat(log).extracting("out").isSameAs(System.out);
|
||||
}
|
||||
|
||||
@Test
|
||||
void toPrintsToOutput() {
|
||||
BuildLog log = BuildLog.to(System.err);
|
||||
assertThat(log).isInstanceOf(PrintStreamBuildLog.class);
|
||||
assertThat(log).extracting("out").isSameAs(System.err);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.build;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
||||
/**
|
||||
* Tests for {@link BuildOwner}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class BuildOwnerTests {
|
||||
|
||||
@Test
|
||||
void fromEnvReturnsOwner() {
|
||||
Map<String, String> env = new LinkedHashMap<>();
|
||||
env.put("CNB_USER_ID", "123");
|
||||
env.put("CNB_GROUP_ID", "456");
|
||||
BuildOwner owner = BuildOwner.fromEnv(env);
|
||||
assertThat(owner.getUid()).isEqualTo(123);
|
||||
assertThat(owner.getGid()).isEqualTo(456);
|
||||
assertThat(owner.toString()).isEqualTo("123/456");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromEnvWhenEnvIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> BuildOwner.fromEnv(null))
|
||||
.withMessage("Env must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromEnvWhenUserPropertyIsMissingThrowsException() {
|
||||
Map<String, String> env = new LinkedHashMap<>();
|
||||
env.put("CNB_GROUP_ID", "456");
|
||||
assertThatIllegalStateException().isThrownBy(() -> BuildOwner.fromEnv(env))
|
||||
.withMessage("Missing 'CNB_USER_ID' value from the builder environment");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromEnvWhenGroupPropertyIsMissingThrowsException() {
|
||||
Map<String, String> env = new LinkedHashMap<>();
|
||||
env.put("CNB_USER_ID", "123");
|
||||
assertThatIllegalStateException().isThrownBy(() -> BuildOwner.fromEnv(env))
|
||||
.withMessage("Missing 'CNB_GROUP_ID' value from the builder environment");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromEnvWhenUserPropertyIsMalformedThrowsException() {
|
||||
Map<String, String> env = new LinkedHashMap<>();
|
||||
env.put("CNB_USER_ID", "nope");
|
||||
env.put("CNB_GROUP_ID", "456");
|
||||
assertThatIllegalStateException().isThrownBy(() -> BuildOwner.fromEnv(env))
|
||||
.withMessage("Malformed 'CNB_USER_ID' value 'nope' in the builder environment");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromEnvWhenGroupPropertyIsMalformedThrowsException() {
|
||||
Map<String, String> env = new LinkedHashMap<>();
|
||||
env.put("CNB_USER_ID", "123");
|
||||
env.put("CNB_GROUP_ID", "nope");
|
||||
assertThatIllegalStateException().isThrownBy(() -> BuildOwner.fromEnv(env))
|
||||
.withMessage("Malformed 'CNB_GROUP_ID' value 'nope' in the builder environment");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.build;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ImageReference;
|
||||
import org.springframework.boot.buildpack.platform.io.Owner;
|
||||
import org.springframework.boot.buildpack.platform.io.TarArchive;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
|
||||
/**
|
||||
* Tests for {@link BuildRequest}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public class BuildRequestTests {
|
||||
|
||||
@TempDir
|
||||
File tempDir;
|
||||
|
||||
@Test
|
||||
void forJarFileReturnsRequest() throws IOException {
|
||||
File jarFile = new File(this.tempDir, "my-app-0.0.1.jar");
|
||||
writeTestJarFile(jarFile);
|
||||
BuildRequest request = BuildRequest.forJarFile(jarFile);
|
||||
assertThat(request.getName().toString()).isEqualTo("docker.io/library/my-app:0.0.1");
|
||||
assertThat(request.getBuilder().toString()).isEqualTo("docker.io/cloudfoundry/cnb:0.0.43-bionic");
|
||||
assertThat(request.getApplicationContent(Owner.ROOT)).satisfies(this::hasExpectedJarContent);
|
||||
assertThat(request.getEnv()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void forJarFileWithNameReturnsRequest() throws IOException {
|
||||
File jarFile = new File(this.tempDir, "my-app-0.0.1.jar");
|
||||
writeTestJarFile(jarFile);
|
||||
BuildRequest request = BuildRequest.forJarFile(ImageReference.of("test-app"), jarFile);
|
||||
assertThat(request.getName().toString()).isEqualTo("docker.io/library/test-app:latest");
|
||||
assertThat(request.getBuilder().toString()).isEqualTo("docker.io/cloudfoundry/cnb:0.0.43-bionic");
|
||||
assertThat(request.getApplicationContent(Owner.ROOT)).satisfies(this::hasExpectedJarContent);
|
||||
assertThat(request.getEnv()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
void forJarFileWhenJarFileIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> BuildRequest.forJarFile(null))
|
||||
.withMessage("JarFile must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void forJarFileWhenJarFileIsMissingThrowsException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> BuildRequest.forJarFile(new File(this.tempDir, "missing.jar")))
|
||||
.withMessage("JarFile must exist");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void forJarFileWhenJarFileIsFolderThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> BuildRequest.forJarFile(this.tempDir))
|
||||
.withMessage("JarFile must be a file");
|
||||
}
|
||||
|
||||
@Test
|
||||
void withBuilderUpdatesBuilder() throws IOException {
|
||||
BuildRequest request = BuildRequest.forJarFile(writeTestJarFile("my-app-0.0.1.jar"))
|
||||
.withBuilder(ImageReference.of("spring/builder"));
|
||||
assertThat(request.getBuilder().toString()).isEqualTo("docker.io/spring/builder:latest");
|
||||
}
|
||||
|
||||
@Test
|
||||
void withEnvAddsEnvEntry() throws IOException {
|
||||
BuildRequest request = BuildRequest.forJarFile(writeTestJarFile("my-app-0.0.1.jar"));
|
||||
BuildRequest withEnv = request.withEnv("spring", "boot");
|
||||
assertThat(request.getEnv()).isEmpty();
|
||||
assertThat(withEnv.getEnv()).containsExactly(entry("spring", "boot"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void withEnvMapAddsEnvEntries() throws IOException {
|
||||
BuildRequest request = BuildRequest.forJarFile(writeTestJarFile("my-app-0.0.1.jar"));
|
||||
Map<String, String> env = new LinkedHashMap<>();
|
||||
env.put("spring", "boot");
|
||||
env.put("test", "test");
|
||||
BuildRequest withEnv = request.withEnv(env);
|
||||
assertThat(request.getEnv()).isEmpty();
|
||||
assertThat(withEnv.getEnv()).containsExactly(entry("spring", "boot"), entry("test", "test"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void withEnvWhenKeyIsNullThrowsException() throws IOException {
|
||||
BuildRequest request = BuildRequest.forJarFile(writeTestJarFile("my-app-0.0.1.jar"));
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> request.withEnv(null, "test"))
|
||||
.withMessage("Name must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void withEnvWhenValueIsNullThrowsException() throws IOException {
|
||||
BuildRequest request = BuildRequest.forJarFile(writeTestJarFile("my-app-0.0.1.jar"));
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> request.withEnv("test", null))
|
||||
.withMessage("Value must not be empty");
|
||||
}
|
||||
|
||||
private void hasExpectedJarContent(TarArchive archive) {
|
||||
try {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
archive.writeTo(outputStream);
|
||||
try (TarArchiveInputStream tar = new TarArchiveInputStream(
|
||||
new ByteArrayInputStream(outputStream.toByteArray()))) {
|
||||
assertThat(tar.getNextEntry().getName()).isEqualTo("spring/");
|
||||
assertThat(tar.getNextEntry().getName()).isEqualTo("spring/boot");
|
||||
assertThat(tar.getNextEntry()).isNull();
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private File writeTestJarFile(String name) throws IOException {
|
||||
File file = new File(this.tempDir, name);
|
||||
writeTestJarFile(file);
|
||||
return file;
|
||||
}
|
||||
|
||||
private void writeTestJarFile(File file) throws IOException {
|
||||
try (ZipArchiveOutputStream zip = new ZipArchiveOutputStream(file)) {
|
||||
ZipArchiveEntry dirEntry = new ZipArchiveEntry("spring/");
|
||||
zip.putArchiveEntry(dirEntry);
|
||||
zip.closeArchiveEntry();
|
||||
ZipArchiveEntry fileEntry = new ZipArchiveEntry("spring/boot");
|
||||
zip.putArchiveEntry(fileEntry);
|
||||
zip.write("test".getBytes(StandardCharsets.UTF_8));
|
||||
zip.closeArchiveEntry();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.build;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.type.Image;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ImageConfig;
|
||||
import org.springframework.boot.buildpack.platform.json.AbstractJsonTests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link BuilderMetadata}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class BuilderMetadataTests extends AbstractJsonTests {
|
||||
|
||||
@Test
|
||||
void fromImageLoadsMetadata() throws IOException {
|
||||
Image image = Image.of(getContent("image.json"));
|
||||
BuilderMetadata metadata = BuilderMetadata.fromImage(image);
|
||||
assertThat(metadata.getStack().getRunImage().getImage()).isEqualTo("cloudfoundry/run:full-cnb");
|
||||
assertThat(metadata.getStack().getRunImage().getMirrors()).isEmpty();
|
||||
assertThat(metadata.getLifecycle().getVersion()).isEqualTo("0.5.0");
|
||||
assertThat(metadata.getLifecycle().getApi().getBuildpack()).isEqualTo("0.2");
|
||||
assertThat(metadata.getLifecycle().getApi().getPlatform()).isEqualTo("0.1");
|
||||
assertThat(metadata.getCreatedBy().getName()).isEqualTo("Pack CLI");
|
||||
assertThat(metadata.getCreatedBy().getVersion())
|
||||
.isEqualTo("v0.5.0 (git sha: c9cfac75b49609524e1ea33f809c12071406547c)");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromImageWhenImageIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> BuilderMetadata.fromImage(null))
|
||||
.withMessage("Image must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromImageWhenImageConfigIsNullThrowsException() {
|
||||
Image image = mock(Image.class);
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> BuilderMetadata.fromImage(image))
|
||||
.withMessage("ImageConfig must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromImageConfigWhenLabelIsMissingThrowsException() {
|
||||
Image image = mock(Image.class);
|
||||
ImageConfig imageConfig = mock(ImageConfig.class);
|
||||
given(image.getConfig()).willReturn(imageConfig);
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> BuilderMetadata.fromImage(image))
|
||||
.withMessage("No 'io.buildpacks.builder.metadata' label found in image config");
|
||||
}
|
||||
|
||||
@Test
|
||||
void copyWithUpdatedCreatedByReturnsNewMetadata() throws IOException {
|
||||
Image image = Image.of(getContent("image.json"));
|
||||
BuilderMetadata metadata = BuilderMetadata.fromImage(image);
|
||||
BuilderMetadata copy = metadata.copy((update) -> update.withCreatedBy("test123", "test456"));
|
||||
assertThat(copy).isNotSameAs(metadata);
|
||||
assertThat(copy.getCreatedBy().getName()).isEqualTo("test123");
|
||||
assertThat(copy.getCreatedBy().getVersion()).isEqualTo("test456");
|
||||
}
|
||||
|
||||
@Test
|
||||
void attachToUpdatesMetadata() throws IOException {
|
||||
Image image = Image.of(getContent("image.json"));
|
||||
ImageConfig imageConfig = image.getConfig();
|
||||
BuilderMetadata metadata = BuilderMetadata.fromImage(image);
|
||||
ImageConfig imageConfigCopy = imageConfig.copy(metadata::attachTo);
|
||||
String label = imageConfigCopy.getLabels().get("io.buildpacks.builder.metadata");
|
||||
BuilderMetadata metadataCopy = BuilderMetadata.fromJson(label);
|
||||
assertThat(metadataCopy.getStack().getRunImage().getImage())
|
||||
.isEqualTo(metadata.getStack().getRunImage().getImage());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.build;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.DockerApi;
|
||||
import org.springframework.boot.buildpack.platform.docker.DockerApi.ContainerApi;
|
||||
import org.springframework.boot.buildpack.platform.docker.DockerApi.ImageApi;
|
||||
import org.springframework.boot.buildpack.platform.docker.DockerApi.VolumeApi;
|
||||
import org.springframework.boot.buildpack.platform.docker.TotalProgressPullListener;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.Image;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ImageArchive;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ImageReference;
|
||||
import org.springframework.boot.buildpack.platform.io.TarArchive;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link Builder}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class BuilderTests {
|
||||
|
||||
@Test
|
||||
void createWhenLogIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new Builder(null)).withMessage("Log must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildWhenRequestIsNullThrowsException() {
|
||||
Builder builder = new Builder();
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> builder.build(null))
|
||||
.withMessage("Request must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildInvokesBuildpack() throws Exception {
|
||||
TestPrintStream out = new TestPrintStream();
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image.json");
|
||||
Image runImage = loadImage("run-image.json");
|
||||
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/cnb:0.0.43-bionic")), any()))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:full-cnb")), any()))
|
||||
.willAnswer(withPulledImage(runImage));
|
||||
Builder builder = new Builder(BuildLog.to(out), docker);
|
||||
BuildRequest request = getTestRequest();
|
||||
builder.build(request);
|
||||
assertThat(out.toString()).contains("Running detector");
|
||||
assertThat(out.toString()).contains("Running restorer");
|
||||
assertThat(out.toString()).contains("Running analyzer");
|
||||
assertThat(out.toString()).contains("Running builder");
|
||||
assertThat(out.toString()).contains("Running exporter");
|
||||
assertThat(out.toString()).contains("Running cacher");
|
||||
assertThat(out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||
ArgumentCaptor<ImageArchive> archive = ArgumentCaptor.forClass(ImageArchive.class);
|
||||
verify(docker.image()).load(archive.capture(), any());
|
||||
verify(docker.image()).remove(archive.getValue().getTag(), true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void buildWhenStackIdDoesNotMatchThrowsException() throws Exception {
|
||||
TestPrintStream out = new TestPrintStream();
|
||||
DockerApi docker = mockDockerApi();
|
||||
Image builderImage = loadImage("image.json");
|
||||
Image runImage = loadImage("run-image-with-bad-stack.json");
|
||||
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/cnb:0.0.43-bionic")), any()))
|
||||
.willAnswer(withPulledImage(builderImage));
|
||||
given(docker.image().pull(eq(ImageReference.of("docker.io/cloudfoundry/run:full-cnb")), any()))
|
||||
.willAnswer(withPulledImage(runImage));
|
||||
Builder builder = new Builder(BuildLog.to(out), docker);
|
||||
BuildRequest request = getTestRequest();
|
||||
assertThatIllegalStateException().isThrownBy(() -> builder.build(request)).withMessage(
|
||||
"Run image stack 'org.cloudfoundry.stacks.cfwindowsfs3' does not match builder stack 'org.cloudfoundry.stacks.cflinuxfs3'");
|
||||
}
|
||||
|
||||
private DockerApi mockDockerApi() {
|
||||
DockerApi docker = mock(DockerApi.class);
|
||||
ImageApi imageApi = mock(ImageApi.class);
|
||||
ContainerApi containerApi = mock(ContainerApi.class);
|
||||
VolumeApi volumeApi = mock(VolumeApi.class);
|
||||
given(docker.image()).willReturn(imageApi);
|
||||
given(docker.container()).willReturn(containerApi);
|
||||
given(docker.volume()).willReturn(volumeApi);
|
||||
return docker;
|
||||
}
|
||||
|
||||
private BuildRequest getTestRequest() {
|
||||
TarArchive content = mock(TarArchive.class);
|
||||
ImageReference name = ImageReference.of("my-application");
|
||||
BuildRequest request = BuildRequest.of(name, (owner) -> content);
|
||||
return request;
|
||||
}
|
||||
|
||||
private Image loadImage(String name) throws IOException {
|
||||
return Image.of(getClass().getResourceAsStream(name));
|
||||
}
|
||||
|
||||
private Answer<Image> withPulledImage(Image image) {
|
||||
return (invocation) -> {
|
||||
TotalProgressPullListener listener = invocation.getArgument(1, TotalProgressPullListener.class);
|
||||
listener.onStart();
|
||||
listener.onFinish();
|
||||
return image;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
static class TestPrintStream extends PrintStream {
|
||||
|
||||
TestPrintStream() {
|
||||
super(new ByteArrayOutputStream());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.out.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.build;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Clock;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.compress.archivers.ArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.compress.utils.IOUtils;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.type.Image;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ImageArchive;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ImageConfig;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ImageReference;
|
||||
import org.springframework.boot.buildpack.platform.json.AbstractJsonTests;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link EphemeralBuilder}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class EphemeralBuilderTests extends AbstractJsonTests {
|
||||
|
||||
@TempDir
|
||||
File temp;
|
||||
|
||||
private final BuildOwner owner = BuildOwner.of(123, 456);
|
||||
|
||||
private Image image;
|
||||
|
||||
private BuilderMetadata metadata;
|
||||
|
||||
private Map<String, String> env;
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
this.image = Image.of(getContent("image.json"));
|
||||
this.metadata = BuilderMetadata.fromImage(this.image);
|
||||
this.env = Collections.singletonMap("spring", "boot");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getNameHasRandomName() throws Exception {
|
||||
EphemeralBuilder b1 = new EphemeralBuilder(this.owner, this.image, this.metadata, this.env);
|
||||
EphemeralBuilder b2 = new EphemeralBuilder(this.owner, this.image, this.metadata, this.env);
|
||||
assertThat(b1.getName().toString()).startsWith("pack.local/builder/").endsWith(":latest");
|
||||
assertThat(b1.getName().toString()).isNotEqualTo(b2.getName().toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getArchiveHasCreatedByConfig() throws Exception {
|
||||
EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.metadata, this.env);
|
||||
ImageConfig config = builder.getArchive().getImageConfig();
|
||||
BuilderMetadata ephemeralMetadata = BuilderMetadata.fromImageConfig(config);
|
||||
assertThat(ephemeralMetadata.getCreatedBy().getName()).isEqualTo("Spring Boot");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getArchiveHasTag() throws Exception {
|
||||
EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.metadata, this.env);
|
||||
ImageReference tag = builder.getArchive().getTag();
|
||||
assertThat(tag.toString()).startsWith("pack.local/builder/").endsWith(":latest");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getArchiveHasCreateDate() throws Exception {
|
||||
Clock clock = Clock.fixed(Instant.now(), ZoneOffset.UTC);
|
||||
EphemeralBuilder builder = new EphemeralBuilder(clock, this.owner, this.image, this.metadata, this.env);
|
||||
assertThat(builder.getArchive().getCreateDate()).isEqualTo(Instant.now(clock));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getArchiveContainsDefaultDirsLayer() throws Exception {
|
||||
EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.metadata, this.env);
|
||||
File folder = unpack(getLayer(builder.getArchive(), 0), "dirs");
|
||||
assertThat(new File(folder, "workspace")).isDirectory();
|
||||
assertThat(new File(folder, "layers")).isDirectory();
|
||||
assertThat(new File(folder, "cnb")).isDirectory();
|
||||
assertThat(new File(folder, "cnb/buildpacks")).isDirectory();
|
||||
assertThat(new File(folder, "platform")).isDirectory();
|
||||
assertThat(new File(folder, "platform/env")).isDirectory();
|
||||
}
|
||||
|
||||
@Test
|
||||
void getArchiveContainsStackLayer() throws Exception {
|
||||
EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.metadata, this.env);
|
||||
File folder = unpack(getLayer(builder.getArchive(), 1), "stack");
|
||||
File tomlFile = new File(folder, "cnb/stack.toml");
|
||||
assertThat(tomlFile).exists();
|
||||
String toml = FileCopyUtils
|
||||
.copyToString(new InputStreamReader(new FileInputStream(tomlFile), StandardCharsets.UTF_8));
|
||||
assertThat(toml).contains("[run-image]").contains("image = ");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getArchiveContainsEnvLayer() throws Exception {
|
||||
EphemeralBuilder builder = new EphemeralBuilder(this.owner, this.image, this.metadata, this.env);
|
||||
File folder = unpack(getLayer(builder.getArchive(), 2), "env");
|
||||
assertThat(new File(folder, "platform/env/spring")).usingCharset(StandardCharsets.UTF_8).hasContent("boot");
|
||||
}
|
||||
|
||||
private TarArchiveInputStream getLayer(ImageArchive archive, int index) throws Exception {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
archive.writeTo(outputStream);
|
||||
TarArchiveInputStream tar = new TarArchiveInputStream(new ByteArrayInputStream(outputStream.toByteArray()));
|
||||
for (int i = 0; i <= index; i++) {
|
||||
tar.getNextEntry();
|
||||
}
|
||||
return new TarArchiveInputStream(tar);
|
||||
}
|
||||
|
||||
private File unpack(TarArchiveInputStream archive, String name) throws Exception {
|
||||
File folder = new File(this.temp, name);
|
||||
folder.mkdirs();
|
||||
ArchiveEntry entry = archive.getNextEntry();
|
||||
while (entry != null) {
|
||||
File file = new File(folder, entry.getName());
|
||||
if (entry.isDirectory()) {
|
||||
file.mkdirs();
|
||||
}
|
||||
else {
|
||||
file.getParentFile().mkdirs();
|
||||
try (OutputStream out = new FileOutputStream(file)) {
|
||||
IOUtils.copy(archive, out);
|
||||
}
|
||||
}
|
||||
entry = archive.getNextEntry();
|
||||
}
|
||||
return folder;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.build;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.JsonMappingException;
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import com.fasterxml.jackson.databind.node.ArrayNode;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.DockerApi;
|
||||
import org.springframework.boot.buildpack.platform.docker.DockerApi.ContainerApi;
|
||||
import org.springframework.boot.buildpack.platform.docker.DockerApi.ImageApi;
|
||||
import org.springframework.boot.buildpack.platform.docker.DockerApi.VolumeApi;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ContainerConfig;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ContainerContent;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ContainerReference;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ImageReference;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.VolumeName;
|
||||
import org.springframework.boot.buildpack.platform.io.IOConsumer;
|
||||
import org.springframework.boot.buildpack.platform.io.TarArchive;
|
||||
import org.springframework.boot.buildpack.platform.json.SharedObjectMapper;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link Lifecycle}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class LifecycleTests {
|
||||
|
||||
private TestPrintStream out;
|
||||
|
||||
private DockerApi docker;
|
||||
|
||||
private Lifecycle lifecycle;
|
||||
|
||||
private Map<String, ContainerConfig> configs = new LinkedHashMap<>();
|
||||
|
||||
private Map<String, ContainerContent> content = new LinkedHashMap<>();
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
this.out = new TestPrintStream();
|
||||
this.docker = mockDockerApi();
|
||||
BuildRequest request = getTestRequest();
|
||||
this.lifecycle = createLifecycle(request);
|
||||
}
|
||||
|
||||
private DockerApi mockDockerApi() {
|
||||
DockerApi docker = mock(DockerApi.class);
|
||||
ImageApi imageApi = mock(ImageApi.class);
|
||||
ContainerApi containerApi = mock(ContainerApi.class);
|
||||
VolumeApi volumeApi = mock(VolumeApi.class);
|
||||
given(docker.image()).willReturn(imageApi);
|
||||
given(docker.container()).willReturn(containerApi);
|
||||
given(docker.volume()).willReturn(volumeApi);
|
||||
return docker;
|
||||
}
|
||||
|
||||
@Test
|
||||
void executeExecutesPhases() throws Exception {
|
||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||
this.lifecycle.execute();
|
||||
assertPhaseWasRun("detector", withExpectedConfig("lifecycle-detector.json"));
|
||||
assertPhaseWasRun("restorer", withExpectedConfig("lifecycle-restorer.json"));
|
||||
assertPhaseWasRun("analyzer", withExpectedConfig("lifecycle-analyzer.json"));
|
||||
assertPhaseWasRun("builder", withExpectedConfig("lifecycle-builder.json"));
|
||||
assertPhaseWasRun("exporter", withExpectedConfig("lifecycle-exporter.json"));
|
||||
assertPhaseWasRun("cacher", withExpectedConfig("lifecycle-cacher.json"));
|
||||
assertThat(this.out.toString()).contains("Successfully built image 'docker.io/library/my-application:latest'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void executeOnlyUploadsContentOnce() throws Exception {
|
||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||
this.lifecycle.execute();
|
||||
assertThat(this.content).hasSize(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
void executeWhenAleadyRunThrowsException() throws Exception {
|
||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||
this.lifecycle.execute();
|
||||
assertThatIllegalStateException().isThrownBy(this.lifecycle::execute)
|
||||
.withMessage("Lifecycle has already been executed");
|
||||
}
|
||||
|
||||
@Test
|
||||
void executeWhenCleanCacheClearsCache() throws Exception {
|
||||
given(this.docker.container().create(any())).willAnswer(answerWithGeneratedContainerId());
|
||||
given(this.docker.container().create(any(), any())).willAnswer(answerWithGeneratedContainerId());
|
||||
BuildRequest request = getTestRequest().withCleanCache(true);
|
||||
createLifecycle(request).execute();
|
||||
VolumeName name = VolumeName.of("pack-cache-b35197ac41ea.build");
|
||||
verify(this.docker.volume()).delete(name, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
void closeClearsVolumes() throws Exception {
|
||||
this.lifecycle.close();
|
||||
verify(this.docker.volume()).delete(VolumeName.of("pack-layers-aaaaaaaaaa"), true);
|
||||
verify(this.docker.volume()).delete(VolumeName.of("pack-app-aaaaaaaaaa"), true);
|
||||
}
|
||||
|
||||
private BuildRequest getTestRequest() {
|
||||
TarArchive content = mock(TarArchive.class);
|
||||
ImageReference name = ImageReference.of("my-application");
|
||||
BuildRequest request = BuildRequest.of(name, (owner) -> content);
|
||||
return request;
|
||||
}
|
||||
|
||||
private Lifecycle createLifecycle(BuildRequest request) throws IOException {
|
||||
EphemeralBuilder builder = mockEphemeralBuilder();
|
||||
return new TestLifecycle(BuildLog.to(this.out), this.docker, request, ImageReference.of("cloudfoundry/run"),
|
||||
builder);
|
||||
}
|
||||
|
||||
private EphemeralBuilder mockEphemeralBuilder() throws IOException {
|
||||
EphemeralBuilder builder = mock(EphemeralBuilder.class);
|
||||
byte[] metadataContent = FileCopyUtils.copyToByteArray(getClass().getResourceAsStream("builder-metadata.json"));
|
||||
BuilderMetadata metadata = BuilderMetadata.fromJson(new String(metadataContent, StandardCharsets.UTF_8));
|
||||
given(builder.getName()).willReturn(ImageReference.of("pack.local/ephemeral-builder"));
|
||||
given(builder.getBuilderMetadata()).willReturn(metadata);
|
||||
return builder;
|
||||
}
|
||||
|
||||
private Answer<ContainerReference> answerWithGeneratedContainerId() {
|
||||
return (invocation) -> {
|
||||
ContainerConfig config = invocation.getArgument(0, ContainerConfig.class);
|
||||
ArrayNode command = getCommand(config);
|
||||
String name = command.get(0).asText().substring(1).replaceAll("/", "-");
|
||||
this.configs.put(name, config);
|
||||
if (invocation.getArguments().length > 1) {
|
||||
this.content.put(name, invocation.getArgument(1, ContainerContent.class));
|
||||
}
|
||||
return ContainerReference.of(name);
|
||||
};
|
||||
}
|
||||
|
||||
private ArrayNode getCommand(ContainerConfig config) throws JsonProcessingException, JsonMappingException {
|
||||
JsonNode node = SharedObjectMapper.get().readTree(config.toString());
|
||||
return (ArrayNode) node.at("/Cmd");
|
||||
}
|
||||
|
||||
private void assertPhaseWasRun(String name, IOConsumer<ContainerConfig> configConsumer) throws IOException {
|
||||
ContainerReference containerReference = ContainerReference.of("lifecycle-" + name);
|
||||
verify(this.docker.container()).start(containerReference);
|
||||
verify(this.docker.container()).logs(eq(containerReference), any());
|
||||
verify(this.docker.container()).remove(containerReference, true);
|
||||
configConsumer.accept(this.configs.get(containerReference.toString()));
|
||||
}
|
||||
|
||||
private IOConsumer<ContainerConfig> withExpectedConfig(String name) {
|
||||
return (config) -> {
|
||||
InputStream in = getClass().getResourceAsStream(name);
|
||||
String json = FileCopyUtils.copyToString(new InputStreamReader(in, StandardCharsets.UTF_8));
|
||||
assertThat(config.toString()).isEqualToIgnoringWhitespace(json);
|
||||
};
|
||||
}
|
||||
|
||||
static class TestLifecycle extends Lifecycle {
|
||||
|
||||
TestLifecycle(BuildLog log, DockerApi docker, BuildRequest request, ImageReference runImageReferece,
|
||||
EphemeralBuilder builder) {
|
||||
super(log, docker, request, runImageReferece, builder);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected VolumeName createRandomVolumeName(String prefix) {
|
||||
return VolumeName.of(prefix + "aaaaaaaaaa");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static class TestPrintStream extends PrintStream {
|
||||
|
||||
TestPrintStream() {
|
||||
super(new ByteArrayOutputStream());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.out.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.build;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link LifecycleVersion}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class LifecycleVersionTests {
|
||||
|
||||
@Test
|
||||
void parseWhenValueIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> LifecycleVersion.parse(null))
|
||||
.withMessage("Value must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseWhenTooLongThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> LifecycleVersion.parse("v1.2.3.4"))
|
||||
.withMessage("Malformed version number '1.2.3.4'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseWhenNonNumericThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> LifecycleVersion.parse("v1.2.3a"))
|
||||
.withMessage("Malformed version number '1.2.3a'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void compareTo() {
|
||||
LifecycleVersion v4 = LifecycleVersion.parse("0.0.4");
|
||||
assertThat(LifecycleVersion.parse("0.0.3").compareTo(v4)).isNegative();
|
||||
assertThat(LifecycleVersion.parse("0.0.4").compareTo(v4)).isZero();
|
||||
assertThat(LifecycleVersion.parse("0.0.5").compareTo(v4)).isPositive();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEqualOrGreaterThan() {
|
||||
LifecycleVersion v4 = LifecycleVersion.parse("0.0.4");
|
||||
assertThat(LifecycleVersion.parse("0.0.3").isEqualOrGreaterThan(v4)).isFalse();
|
||||
assertThat(LifecycleVersion.parse("0.0.4").isEqualOrGreaterThan(v4)).isTrue();
|
||||
assertThat(LifecycleVersion.parse("0.0.5").isEqualOrGreaterThan(v4)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void parseReturnsVersion() {
|
||||
assertThat(LifecycleVersion.parse("1.2.3").toString()).isEqualTo("v1.2.3");
|
||||
assertThat(LifecycleVersion.parse("1.2").toString()).isEqualTo("v1.2.0");
|
||||
assertThat(LifecycleVersion.parse("1").toString()).isEqualTo("v1.0.0");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.build;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ContainerConfig.Update;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.VolumeName;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
/**
|
||||
* Tests for {@link Phase}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class PhaseTests {
|
||||
|
||||
private static final String[] NO_ARGS = {};
|
||||
|
||||
@Test
|
||||
void getNameReturnsName() {
|
||||
Phase phase = new Phase("test", false);
|
||||
assertThat(phase.getName()).isEqualTo("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringReturnsName() {
|
||||
Phase phase = new Phase("test", false);
|
||||
assertThat(phase).hasToString("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void applyUpdatesConfiguration() {
|
||||
Phase phase = new Phase("test", false);
|
||||
Update update = mock(Update.class);
|
||||
phase.apply(update);
|
||||
verify(update).withCommand("/lifecycle/test", NO_ARGS);
|
||||
verify(update).withLabel("author", "spring-boot");
|
||||
verifyNoMoreInteractions(update);
|
||||
}
|
||||
|
||||
@Test
|
||||
void applyWhenWithDaemonAccessUpdatesConfigurationWithRootUserAndDomainSocketBinding() {
|
||||
Phase phase = new Phase("test", false);
|
||||
phase.withDaemonAccess();
|
||||
Update update = mock(Update.class);
|
||||
phase.apply(update);
|
||||
verify(update).withUser("root");
|
||||
verify(update).withBind("/var/run/docker.sock", "/var/run/docker.sock");
|
||||
verify(update).withCommand("/lifecycle/test", NO_ARGS);
|
||||
verify(update).withLabel("author", "spring-boot");
|
||||
verifyNoMoreInteractions(update);
|
||||
}
|
||||
|
||||
@Test
|
||||
void applyWhenWithLogLevelArgAndVerboseLoggingUpdatesConfigurationWithLogLevel() {
|
||||
Phase phase = new Phase("test", true);
|
||||
phase.withLogLevelArg();
|
||||
Update update = mock(Update.class);
|
||||
phase.apply(update);
|
||||
verify(update).withCommand("/lifecycle/test", "-log-level", "debug");
|
||||
verify(update).withLabel("author", "spring-boot");
|
||||
verifyNoMoreInteractions(update);
|
||||
}
|
||||
|
||||
@Test
|
||||
void applyWhenWithLogLevelArgAndNonVerboseLoggingDoesNotUpdateLogLevel() {
|
||||
Phase phase = new Phase("test", false);
|
||||
phase.withLogLevelArg();
|
||||
Update update = mock(Update.class);
|
||||
phase.apply(update);
|
||||
verify(update).withCommand("/lifecycle/test");
|
||||
verify(update).withLabel("author", "spring-boot");
|
||||
verifyNoMoreInteractions(update);
|
||||
}
|
||||
|
||||
@Test
|
||||
void applyWhenWithArgsUpdatesConfigurationWithArguments() {
|
||||
Phase phase = new Phase("test", false);
|
||||
phase.withArgs("a", "b", "c");
|
||||
Update update = mock(Update.class);
|
||||
phase.apply(update);
|
||||
verify(update).withCommand("/lifecycle/test", "a", "b", "c");
|
||||
verify(update).withLabel("author", "spring-boot");
|
||||
verifyNoMoreInteractions(update);
|
||||
}
|
||||
|
||||
@Test
|
||||
void applyWhenWithBindsUpdatesConfigurationWithBinds() {
|
||||
Phase phase = new Phase("test", false);
|
||||
VolumeName volumeName = VolumeName.of("test");
|
||||
phase.withBinds(volumeName, "/test");
|
||||
Update update = mock(Update.class);
|
||||
phase.apply(update);
|
||||
verify(update).withCommand("/lifecycle/test");
|
||||
verify(update).withLabel("author", "spring-boot");
|
||||
verify(update).withBind(volumeName, "/test");
|
||||
verifyNoMoreInteractions(update);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.build;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Collections;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.LogUpdateEvent;
|
||||
import org.springframework.boot.buildpack.platform.docker.TotalProgressEvent;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.Image;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ImageReference;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.VolumeName;
|
||||
import org.springframework.util.FileCopyUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link PrintStreamBuildLog}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class PrintStreamBuildLogTests {
|
||||
|
||||
@Test
|
||||
void printsExpectedOutput() throws Exception {
|
||||
TestPrintStream out = new TestPrintStream();
|
||||
PrintStreamBuildLog log = new PrintStreamBuildLog(out);
|
||||
BuildRequest request = mock(BuildRequest.class);
|
||||
ImageReference name = ImageReference.of("my-app:latest");
|
||||
ImageReference builderImageReference = ImageReference.of("cnb/builder");
|
||||
Image builderImage = mock(Image.class);
|
||||
given(builderImage.getDigests()).willReturn(Collections.singletonList("00000001"));
|
||||
ImageReference runImageReference = ImageReference.of("cnb/runner");
|
||||
Image runImage = mock(Image.class);
|
||||
given(runImage.getDigests()).willReturn(Collections.singletonList("00000002"));
|
||||
given(request.getName()).willReturn(name);
|
||||
log.start(request);
|
||||
Consumer<TotalProgressEvent> pullBuildImageConsumer = log.pullingBuilder(request, builderImageReference);
|
||||
pullBuildImageConsumer.accept(new TotalProgressEvent(100));
|
||||
log.pulledBulder(request, builderImage);
|
||||
Consumer<TotalProgressEvent> pullRunImageConsumer = log.pullingRunImage(request, runImageReference);
|
||||
pullRunImageConsumer.accept(new TotalProgressEvent(100));
|
||||
log.pulledRunImage(request, runImage);
|
||||
log.executingLifecycle(request, LifecycleVersion.parse("0.5"), VolumeName.of("pack-abc.cache"));
|
||||
Consumer<LogUpdateEvent> phase1Consumer = log.runningPhase(request, "alphabet");
|
||||
phase1Consumer.accept(mockLogEvent("one"));
|
||||
phase1Consumer.accept(mockLogEvent("two"));
|
||||
phase1Consumer.accept(mockLogEvent("three"));
|
||||
Consumer<LogUpdateEvent> phase2Consumer = log.runningPhase(request, "basket");
|
||||
phase2Consumer.accept(mockLogEvent("spring"));
|
||||
phase2Consumer.accept(mockLogEvent("boot"));
|
||||
log.executedLifecycle(request);
|
||||
String expected = FileCopyUtils.copyToString(new InputStreamReader(
|
||||
getClass().getResourceAsStream("print-stream-build-log.txt"), StandardCharsets.UTF_8));
|
||||
assertThat(out.toString()).isEqualToIgnoringNewLines(expected);
|
||||
}
|
||||
|
||||
private LogUpdateEvent mockLogEvent(String string) {
|
||||
LogUpdateEvent event = mock(LogUpdateEvent.class);
|
||||
given(event.toString()).willReturn(string);
|
||||
return event;
|
||||
}
|
||||
|
||||
static class TestPrintStream extends PrintStream {
|
||||
|
||||
TestPrintStream() {
|
||||
super(new ByteArrayOutputStream());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.out.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.build;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.type.Image;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ImageConfig;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link StackId}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class StackIdTests {
|
||||
|
||||
@Test
|
||||
void fromImageWhenImageIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> StackId.fromImage(null))
|
||||
.withMessage("Image must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromImageWhenLabelIsMissingThrowsException() {
|
||||
Image image = mock(Image.class);
|
||||
ImageConfig imageConfig = mock(ImageConfig.class);
|
||||
given(image.getConfig()).willReturn(imageConfig);
|
||||
assertThatIllegalStateException().isThrownBy(() -> StackId.fromImage(image))
|
||||
.withMessage("Missing 'io.buildpacks.stack.id' stack label");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromImageCreatesStackId() {
|
||||
Image image = mock(Image.class);
|
||||
ImageConfig imageConfig = mock(ImageConfig.class);
|
||||
given(image.getConfig()).willReturn(imageConfig);
|
||||
given(imageConfig.getLabels()).willReturn(Collections.singletonMap("io.buildpacks.stack.id", "test"));
|
||||
StackId stackId = StackId.fromImage(image);
|
||||
assertThat(stackId.toString()).isEqualTo("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofCreatesStackId() {
|
||||
StackId stackId = StackId.of("test");
|
||||
assertThat(stackId.toString()).isEqualTo("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void equalsAndHashCode() {
|
||||
StackId s1 = StackId.of("a");
|
||||
StackId s2 = StackId.of("a");
|
||||
StackId s3 = StackId.of("b");
|
||||
assertThat(s1.hashCode()).isEqualTo(s2.hashCode());
|
||||
assertThat(s1).isEqualTo(s1).isEqualTo(s2).isNotEqualTo(s3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringReturnsValue() {
|
||||
StackId stackId = StackId.of("test");
|
||||
assertThat(stackId.toString()).isEqualTo("test");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ImageReference;
|
||||
import org.springframework.boot.testsupport.testcontainers.DisabledIfDockerUnavailable;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link DockerApi}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
@DisabledIfDockerUnavailable
|
||||
class DockerApiIntegrationTests {
|
||||
|
||||
private final DockerApi docker = new DockerApi();
|
||||
|
||||
@Test
|
||||
void pullImage() throws IOException {
|
||||
this.docker.image().pull(ImageReference.of("cloudfoundry/cnb:bionic"),
|
||||
new TotalProgressPullListener(new TotalProgressBar("Pulling: ")));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,393 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Nested;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.InOrder;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.DockerApi.ContainerApi;
|
||||
import org.springframework.boot.buildpack.platform.docker.DockerApi.ImageApi;
|
||||
import org.springframework.boot.buildpack.platform.docker.DockerApi.VolumeApi;
|
||||
import org.springframework.boot.buildpack.platform.docker.Http.Response;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ContainerConfig;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ContainerContent;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ContainerReference;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.Image;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ImageArchive;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.ImageReference;
|
||||
import org.springframework.boot.buildpack.platform.docker.type.VolumeName;
|
||||
import org.springframework.boot.buildpack.platform.io.Content;
|
||||
import org.springframework.boot.buildpack.platform.io.IOConsumer;
|
||||
import org.springframework.boot.buildpack.platform.io.Owner;
|
||||
import org.springframework.boot.buildpack.platform.io.TarArchive;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.inOrder;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerApi}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DockerApiTests {
|
||||
|
||||
private static final String API_URL = "docker://localhost/v1.40";
|
||||
|
||||
private static final String IMAGES_URL = API_URL + "/images";
|
||||
|
||||
private static final String CONTAINERS_URL = API_URL + "/containers";
|
||||
|
||||
private static final String VOLUMES_URL = API_URL + "/volumes";
|
||||
|
||||
@Mock
|
||||
private HttpClientHttp httpClient;
|
||||
|
||||
private DockerApi dockerApi;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
this.dockerApi = new DockerApi(this.httpClient);
|
||||
}
|
||||
|
||||
private HttpClientHttp httpClient() {
|
||||
return this.httpClient;
|
||||
}
|
||||
|
||||
private Response emptyResponse() throws IOException {
|
||||
return responseOf(null);
|
||||
}
|
||||
|
||||
private Response responseOf(String name) throws IOException {
|
||||
return new Response() {
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getContent() throws IOException {
|
||||
if (name == null) {
|
||||
return null;
|
||||
}
|
||||
return getClass().getResourceAsStream(name);
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
@Nested
|
||||
class ImageDockerApiTests {
|
||||
|
||||
private ImageApi api;
|
||||
|
||||
@Mock
|
||||
private UpdateListener<PullImageUpdateEvent> pullListener;
|
||||
|
||||
@Mock
|
||||
private UpdateListener<LoadImageUpdateEvent> loadListener;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<IOConsumer<OutputStream>> writer;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
this.api = DockerApiTests.this.dockerApi.image();
|
||||
}
|
||||
|
||||
@Test
|
||||
void pullWhenReferenceIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.api.pull(null, this.pullListener))
|
||||
.withMessage("Reference must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void pullWhenListenerIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.api.pull(ImageReference.of("ubuntu"), null))
|
||||
.withMessage("Listener must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void pullPullsImageAndProducesEvents() throws Exception {
|
||||
ImageReference reference = ImageReference.of("cloudfoundry/cnb:bionic");
|
||||
URI createUri = new URI(IMAGES_URL + "/create?fromImage=docker.io%2Fcloudfoundry%2Fcnb%3Abionic");
|
||||
String imageHash = "4acb6bfd6c4f0cabaf7f3690e444afe51f1c7de54d51da7e63fac709c56f1c30";
|
||||
URI imageUri = new URI(IMAGES_URL + "/docker.io/cloudfoundry/cnb@sha256:" + imageHash + "/json");
|
||||
given(httpClient().post(createUri)).willReturn(responseOf("pull-stream.json"));
|
||||
given(httpClient().get(imageUri)).willReturn(responseOf("type/image.json"));
|
||||
Image image = this.api.pull(reference, this.pullListener);
|
||||
assertThat(image.getLayers()).hasSize(46);
|
||||
InOrder ordered = inOrder(this.pullListener);
|
||||
ordered.verify(this.pullListener).onStart();
|
||||
ordered.verify(this.pullListener, times(595)).onUpdate(any());
|
||||
ordered.verify(this.pullListener).onFinish();
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadWhenArchiveIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.api.load(null, UpdateListener.none()))
|
||||
.withMessage("Archive must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadWhenListenerIsNullThrowsException() {
|
||||
ImageArchive archive = mock(ImageArchive.class);
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.api.load(archive, null))
|
||||
.withMessage("Listener must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void loadLoadsImage() throws Exception {
|
||||
Image image = Image.of(getClass().getResourceAsStream("type/image.json"));
|
||||
ImageArchive archive = ImageArchive.from(image);
|
||||
URI loadUri = new URI(IMAGES_URL + "/load");
|
||||
given(httpClient().post(eq(loadUri), eq("application/x-tar"), any()))
|
||||
.willReturn(responseOf("load-stream.json"));
|
||||
this.api.load(archive, this.loadListener);
|
||||
InOrder ordered = inOrder(this.loadListener);
|
||||
ordered.verify(this.loadListener).onStart();
|
||||
ordered.verify(this.loadListener).onUpdate(any());
|
||||
ordered.verify(this.loadListener).onFinish();
|
||||
verify(httpClient()).post(any(), any(), this.writer.capture());
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
this.writer.getValue().accept(out);
|
||||
assertThat(out.toByteArray()).hasSizeGreaterThan(21000);
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeWhenReferenceIsNulllThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.api.remove(null, true))
|
||||
.withMessage("Reference must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeRemovesContainer() throws Exception {
|
||||
ImageReference reference = ImageReference
|
||||
.of("ubuntu@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d");
|
||||
URI removeUri = new URI(IMAGES_URL
|
||||
+ "/docker.io/library/ubuntu@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d");
|
||||
given(httpClient().delete(removeUri)).willReturn(emptyResponse());
|
||||
this.api.remove(reference, false);
|
||||
verify(httpClient()).delete(removeUri);
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeWhenForceIsTrueRemovesContainer() throws Exception {
|
||||
ImageReference reference = ImageReference
|
||||
.of("ubuntu@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d");
|
||||
URI removeUri = new URI(IMAGES_URL
|
||||
+ "/docker.io/library/ubuntu@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d?force=1");
|
||||
given(httpClient().delete(removeUri)).willReturn(emptyResponse());
|
||||
this.api.remove(reference, true);
|
||||
verify(httpClient()).delete(removeUri);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
class ContainerDockerApiTests {
|
||||
|
||||
private ContainerApi api;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<IOConsumer<OutputStream>> writer;
|
||||
|
||||
@Mock
|
||||
private UpdateListener<LogUpdateEvent> logListener;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
this.api = DockerApiTests.this.dockerApi.container();
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenConfigIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.api.create(null))
|
||||
.withMessage("Config must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createCreatesContainer() throws Exception {
|
||||
ImageReference imageReference = ImageReference.of("ubuntu:bionic");
|
||||
ContainerConfig config = ContainerConfig.of(imageReference, (update) -> update.withCommand("/bin/bash"));
|
||||
URI createUri = new URI(CONTAINERS_URL + "/create");
|
||||
given(httpClient().post(eq(createUri), eq("application/json"), any()))
|
||||
.willReturn(responseOf("create-container-response.json"));
|
||||
ContainerReference containerReference = this.api.create(config);
|
||||
assertThat(containerReference.toString()).isEqualTo("e90e34656806");
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
verify(httpClient()).post(any(), any(), this.writer.capture());
|
||||
this.writer.getValue().accept(out);
|
||||
assertThat(out.toByteArray()).hasSizeGreaterThan(130);
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenHasContentContainerWithContent() throws Exception {
|
||||
ImageReference imageReference = ImageReference.of("ubuntu:bionic");
|
||||
ContainerConfig config = ContainerConfig.of(imageReference, (update) -> update.withCommand("/bin/bash"));
|
||||
TarArchive archive = TarArchive.of((layout) -> {
|
||||
layout.folder("/test", Owner.ROOT);
|
||||
layout.file("/test/file", Owner.ROOT, Content.of("test"));
|
||||
});
|
||||
ContainerContent content = ContainerContent.of(archive);
|
||||
URI createUri = new URI(CONTAINERS_URL + "/create");
|
||||
given(httpClient().post(eq(createUri), eq("application/json"), any()))
|
||||
.willReturn(responseOf("create-container-response.json"));
|
||||
URI uploadUri = new URI(CONTAINERS_URL + "/e90e34656806/archive?path=%2F");
|
||||
given(httpClient().put(eq(uploadUri), eq("application/x-tar"), any())).willReturn(emptyResponse());
|
||||
ContainerReference containerReference = this.api.create(config, content);
|
||||
assertThat(containerReference.toString()).isEqualTo("e90e34656806");
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
verify(httpClient()).post(any(), any(), this.writer.capture());
|
||||
this.writer.getValue().accept(out);
|
||||
assertThat(out.toByteArray()).hasSizeGreaterThan(130);
|
||||
verify(httpClient()).put(any(), any(), this.writer.capture());
|
||||
this.writer.getValue().accept(out);
|
||||
assertThat(out.toByteArray()).hasSizeGreaterThan(2000);
|
||||
}
|
||||
|
||||
@Test
|
||||
void startWhenReferenceIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.api.start(null))
|
||||
.withMessage("Reference must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void startStartsContainer() throws Exception {
|
||||
ContainerReference reference = ContainerReference.of("e90e34656806");
|
||||
URI startContainerUri = new URI(CONTAINERS_URL + "/e90e34656806/start");
|
||||
given(httpClient().post(startContainerUri)).willReturn(emptyResponse());
|
||||
this.api.start(reference);
|
||||
verify(httpClient()).post(startContainerUri);
|
||||
}
|
||||
|
||||
@Test
|
||||
void logsWhenReferenceIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.api.logs(null, UpdateListener.none()))
|
||||
.withMessage("Reference must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void logsWhenListenerIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.api.logs(ContainerReference.of("e90e34656806"), null))
|
||||
.withMessage("Listener must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void logsProducesEvents() throws Exception {
|
||||
ContainerReference reference = ContainerReference.of("e90e34656806");
|
||||
URI logsUri = new URI(CONTAINERS_URL + "/e90e34656806/logs?stdout=1&stderr=1&follow=1");
|
||||
given(httpClient().get(logsUri)).willReturn(responseOf("log-update-event.stream"));
|
||||
this.api.logs(reference, this.logListener);
|
||||
InOrder ordered = inOrder(this.logListener);
|
||||
ordered.verify(this.logListener).onStart();
|
||||
ordered.verify(this.logListener, times(7)).onUpdate(any());
|
||||
ordered.verify(this.logListener).onFinish();
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeWhenReferenceIsNulllThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.api.remove(null, true))
|
||||
.withMessage("Reference must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeRemovesContainer() throws Exception {
|
||||
ContainerReference reference = ContainerReference.of("e90e34656806");
|
||||
URI removeUri = new URI(CONTAINERS_URL + "/e90e34656806");
|
||||
given(httpClient().delete(removeUri)).willReturn(emptyResponse());
|
||||
this.api.remove(reference, false);
|
||||
verify(httpClient()).delete(removeUri);
|
||||
}
|
||||
|
||||
@Test
|
||||
void removeWhenForceIsTrueRemovesContainer() throws Exception {
|
||||
ContainerReference reference = ContainerReference.of("e90e34656806");
|
||||
URI removeUri = new URI(CONTAINERS_URL + "/e90e34656806?force=1");
|
||||
given(httpClient().delete(removeUri)).willReturn(emptyResponse());
|
||||
this.api.remove(reference, true);
|
||||
verify(httpClient()).delete(removeUri);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Nested
|
||||
class VolumeDockerApiTests {
|
||||
|
||||
private VolumeApi api;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<IOConsumer<OutputStream>> writer;
|
||||
|
||||
@Mock
|
||||
private UpdateListener<LogUpdateEvent> logListener;
|
||||
|
||||
@BeforeEach
|
||||
void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
this.api = DockerApiTests.this.dockerApi.volume();
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteWhenNameIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.api.delete(null, false))
|
||||
.withMessage("Name must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteDeletesContainer() throws Exception {
|
||||
VolumeName name = VolumeName.of("test");
|
||||
URI removeUri = new URI(VOLUMES_URL + "/test");
|
||||
given(httpClient().delete(removeUri)).willReturn(emptyResponse());
|
||||
this.api.delete(name, false);
|
||||
verify(httpClient()).delete(removeUri);
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteWhenForceIsTrueDeletesContainer() throws Exception {
|
||||
VolumeName name = VolumeName.of("test");
|
||||
URI removeUri = new URI(VOLUMES_URL + "/test?force=1");
|
||||
given(httpClient().delete(removeUri)).willReturn(emptyResponse());
|
||||
this.api.delete(name, true);
|
||||
verify(httpClient()).delete(removeUri);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker;
|
||||
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.Collections;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link DockerException}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DockerExceptionTests {
|
||||
|
||||
private static final URI URI;
|
||||
static {
|
||||
try {
|
||||
URI = new URI("docker://localhost");
|
||||
}
|
||||
catch (URISyntaxException ex) {
|
||||
throw new IllegalStateException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Errors NO_ERRORS = new Errors(Collections.emptyList());
|
||||
|
||||
private static final Errors ERRORS = new Errors(Collections.singletonList(new Errors.Error("code", "message")));
|
||||
|
||||
@Test
|
||||
void createWhenUriIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new DockerException(null, 404, null, NO_ERRORS))
|
||||
.withMessage("URI must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void create() {
|
||||
DockerException exception = new DockerException(URI, 404, "missing", ERRORS);
|
||||
assertThat(exception.getMessage()).isEqualTo(
|
||||
"Docker API call to 'docker://localhost' failed with status code 404 \"missing\" [code: message]");
|
||||
assertThat(exception.getStatusCode()).isEqualTo(404);
|
||||
assertThat(exception.getReasonPhrase()).isEqualTo("missing");
|
||||
assertThat(exception.getErrors()).isSameAs(ERRORS);
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenReasonPhraseIsNull() {
|
||||
DockerException exception = new DockerException(URI, 404, null, ERRORS);
|
||||
assertThat(exception.getMessage())
|
||||
.isEqualTo("Docker API call to 'docker://localhost' failed with status code 404 [code: message]");
|
||||
assertThat(exception.getStatusCode()).isEqualTo(404);
|
||||
assertThat(exception.getReasonPhrase()).isNull();
|
||||
assertThat(exception.getErrors()).isSameAs(ERRORS);
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenErrorsIsNull() {
|
||||
DockerException exception = new DockerException(URI, 404, "missing", null);
|
||||
assertThat(exception.getErrors()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenErrorsIsEmpty() {
|
||||
DockerException exception = new DockerException(URI, 404, "missing", NO_ERRORS);
|
||||
assertThat(exception.getMessage())
|
||||
.isEqualTo("Docker API call to 'docker://localhost' failed with status code 404 \"missing\"");
|
||||
assertThat(exception.getStatusCode()).isEqualTo(404);
|
||||
assertThat(exception.getReasonPhrase()).isEqualTo("missing");
|
||||
assertThat(exception.getErrors()).isSameAs(NO_ERRORS);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.Errors.Error;
|
||||
import org.springframework.boot.buildpack.platform.json.AbstractJsonTests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link Errors}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ErrorsTests extends AbstractJsonTests {
|
||||
|
||||
@Test
|
||||
void readValueDeserializesJson() throws Exception {
|
||||
Errors errors = this.getObjectMapper().readValue(getContent("errors.json"), Errors.class);
|
||||
Iterator<Error> iterator = errors.iterator();
|
||||
Error error1 = iterator.next();
|
||||
Error error2 = iterator.next();
|
||||
assertThat(iterator.hasNext()).isFalse();
|
||||
assertThat(error1.getCode()).isEqualTo("TEST1");
|
||||
assertThat(error1.getMessage()).isEqualTo("Test One");
|
||||
assertThat(error2.getCode()).isEqualTo("TEST2");
|
||||
assertThat(error2.getMessage()).isEqualTo("Test Two");
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringHasErrorDetails() throws Exception {
|
||||
Errors errors = this.getObjectMapper().readValue(getContent("errors.json"), Errors.class);
|
||||
assertThat(errors.toString()).isEqualTo("[TEST1: Test One, TEST2: Test Two]");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
import org.apache.http.HttpEntityEnclosingRequest;
|
||||
import org.apache.http.HttpHeaders;
|
||||
import org.apache.http.StatusLine;
|
||||
import org.apache.http.client.ClientProtocolException;
|
||||
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||
import org.apache.http.client.methods.HttpDelete;
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.client.methods.HttpPut;
|
||||
import org.apache.http.client.methods.HttpUriRequest;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.Http.Response;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
/**
|
||||
* Tests for {@link HttpClientHttp}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class HttpClientHttpTests {
|
||||
|
||||
private static final String APPLICATION_JSON = "application/json";
|
||||
|
||||
@Mock
|
||||
private CloseableHttpClient client;
|
||||
|
||||
@Mock
|
||||
private CloseableHttpResponse response;
|
||||
|
||||
@Mock
|
||||
private StatusLine statusLine;
|
||||
|
||||
@Mock
|
||||
private HttpEntity entity;
|
||||
|
||||
@Mock
|
||||
private InputStream content;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<HttpUriRequest> requestCaptor;
|
||||
|
||||
private HttpClientHttp http;
|
||||
|
||||
private URI uri;
|
||||
|
||||
@BeforeEach
|
||||
void setup() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
given(this.client.execute(any())).willReturn(this.response);
|
||||
given(this.response.getEntity()).willReturn(this.entity);
|
||||
given(this.response.getStatusLine()).willReturn(this.statusLine);
|
||||
this.http = new HttpClientHttp(this.client);
|
||||
this.uri = new URI("docker://localhost/example");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getShouldExecuteHttpGet() throws Exception {
|
||||
given(this.entity.getContent()).willReturn(this.content);
|
||||
given(this.statusLine.getStatusCode()).willReturn(200);
|
||||
Response response = this.http.get(this.uri);
|
||||
verify(this.client).execute(this.requestCaptor.capture());
|
||||
HttpUriRequest request = this.requestCaptor.getValue();
|
||||
assertThat(request).isInstanceOf(HttpGet.class);
|
||||
assertThat(request.getURI()).isEqualTo(this.uri);
|
||||
assertThat(request.getFirstHeader(HttpHeaders.CONTENT_TYPE)).isNull();
|
||||
assertThat(response.getContent()).isSameAs(this.content);
|
||||
}
|
||||
|
||||
@Test
|
||||
void postShouldExecuteHttpPost() throws Exception {
|
||||
given(this.entity.getContent()).willReturn(this.content);
|
||||
given(this.statusLine.getStatusCode()).willReturn(200);
|
||||
Response response = this.http.post(this.uri);
|
||||
verify(this.client).execute(this.requestCaptor.capture());
|
||||
HttpUriRequest request = this.requestCaptor.getValue();
|
||||
assertThat(request).isInstanceOf(HttpPost.class);
|
||||
assertThat(request.getURI()).isEqualTo(this.uri);
|
||||
assertThat(request.getFirstHeader(HttpHeaders.CONTENT_TYPE)).isNull();
|
||||
assertThat(response.getContent()).isSameAs(this.content);
|
||||
}
|
||||
|
||||
@Test
|
||||
void postWithContentShouldExecuteHttpPost() throws Exception {
|
||||
given(this.entity.getContent()).willReturn(this.content);
|
||||
given(this.statusLine.getStatusCode()).willReturn(200);
|
||||
Response response = this.http.post(this.uri, APPLICATION_JSON,
|
||||
(out) -> StreamUtils.copy("test", StandardCharsets.UTF_8, out));
|
||||
verify(this.client).execute(this.requestCaptor.capture());
|
||||
HttpUriRequest request = this.requestCaptor.getValue();
|
||||
HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
|
||||
assertThat(request).isInstanceOf(HttpPost.class);
|
||||
assertThat(request.getURI()).isEqualTo(this.uri);
|
||||
assertThat(request.getFirstHeader(HttpHeaders.CONTENT_TYPE).getValue()).isEqualTo(APPLICATION_JSON);
|
||||
assertThat(entity.isRepeatable()).isFalse();
|
||||
assertThat(entity.getContentLength()).isEqualTo(-1);
|
||||
assertThat(entity.isStreaming()).isTrue();
|
||||
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> entity.getContent());
|
||||
assertThat(writeToString(entity)).isEqualTo("test");
|
||||
assertThat(response.getContent()).isSameAs(this.content);
|
||||
}
|
||||
|
||||
@Test
|
||||
void putWithContentShouldExecuteHttpPut() throws Exception {
|
||||
given(this.entity.getContent()).willReturn(this.content);
|
||||
given(this.statusLine.getStatusCode()).willReturn(200);
|
||||
Response response = this.http.put(this.uri, APPLICATION_JSON,
|
||||
(out) -> StreamUtils.copy("test", StandardCharsets.UTF_8, out));
|
||||
verify(this.client).execute(this.requestCaptor.capture());
|
||||
HttpUriRequest request = this.requestCaptor.getValue();
|
||||
HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
|
||||
assertThat(request).isInstanceOf(HttpPut.class);
|
||||
assertThat(request.getURI()).isEqualTo(this.uri);
|
||||
assertThat(request.getFirstHeader(HttpHeaders.CONTENT_TYPE).getValue()).isEqualTo(APPLICATION_JSON);
|
||||
assertThat(entity.isRepeatable()).isFalse();
|
||||
assertThat(entity.getContentLength()).isEqualTo(-1);
|
||||
assertThat(entity.isStreaming()).isTrue();
|
||||
assertThatExceptionOfType(UnsupportedOperationException.class).isThrownBy(() -> entity.getContent());
|
||||
assertThat(writeToString(entity)).isEqualTo("test");
|
||||
assertThat(response.getContent()).isSameAs(this.content);
|
||||
}
|
||||
|
||||
@Test
|
||||
void deleteShouldExecuteHttpDelete() throws IOException {
|
||||
given(this.entity.getContent()).willReturn(this.content);
|
||||
given(this.statusLine.getStatusCode()).willReturn(200);
|
||||
Response response = this.http.delete(this.uri);
|
||||
verify(this.client).execute(this.requestCaptor.capture());
|
||||
HttpUriRequest request = this.requestCaptor.getValue();
|
||||
assertThat(request).isInstanceOf(HttpDelete.class);
|
||||
assertThat(request.getURI()).isEqualTo(this.uri);
|
||||
assertThat(request.getFirstHeader(HttpHeaders.CONTENT_TYPE)).isNull();
|
||||
assertThat(response.getContent()).isSameAs(this.content);
|
||||
}
|
||||
|
||||
@Test
|
||||
void executeWhenResposeIsIn400RangeShouldThrowDockerException() throws ClientProtocolException, IOException {
|
||||
given(this.entity.getContent()).willReturn(getClass().getResourceAsStream("errors.json"));
|
||||
given(this.statusLine.getStatusCode()).willReturn(404);
|
||||
assertThatExceptionOfType(DockerException.class).isThrownBy(() -> this.http.get(this.uri))
|
||||
.satisfies((ex) -> assertThat(ex.getErrors()).hasSize(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
void executeWhenResposeIsIn500RangeShouldThrowDockerException() throws ClientProtocolException, IOException {
|
||||
given(this.statusLine.getStatusCode()).willReturn(500);
|
||||
assertThatExceptionOfType(DockerException.class).isThrownBy(() -> this.http.get(this.uri))
|
||||
.satisfies((ex) -> assertThat(ex.getErrors()).isNull());
|
||||
}
|
||||
|
||||
private String writeToString(HttpEntity entity) throws IOException {
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
entity.writeTo(out);
|
||||
return new String(out.toByteArray(), StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.ProgressUpdateEvent.ProgressDetail;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link LoadImageUpdateEvent}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class LoadImageUpdateEventTests extends ProgressUpdateEventTests {
|
||||
|
||||
@Test
|
||||
void getStreamReturnsStream() {
|
||||
LoadImageUpdateEvent event = (LoadImageUpdateEvent) createEvent();
|
||||
assertThat(event.getStream()).isEqualTo("stream");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProgressUpdateEvent createEvent(String status, ProgressDetail progressDetail, String progress) {
|
||||
return new LoadImageUpdateEvent("stream", status, progressDetail, progress);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link LogUpdateEvent}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class LogUpdateEventTests {
|
||||
|
||||
@Test
|
||||
void readAllWhenSimpleStreamReturnsEvents() throws Exception {
|
||||
List<LogUpdateEvent> events = readAll("log-update-event.stream");
|
||||
assertThat(events).hasSize(7);
|
||||
assertThat(events.get(0).toString())
|
||||
.isEqualTo("Analyzing image '307c032c4ceaa6330b6c02af945a1fe56a8c3c27c28268574b217c1d38b093cf'");
|
||||
assertThat(events.get(1).toString())
|
||||
.isEqualTo("Writing metadata for uncached layer 'org.cloudfoundry.openjdk:openjdk-jre'");
|
||||
assertThat(events.get(2).toString())
|
||||
.isEqualTo("Using cached launch layer 'org.cloudfoundry.jvmapplication:executable-jar'");
|
||||
}
|
||||
|
||||
@Test
|
||||
void readAllWhenAnsiStreamReturnsEvents() throws Exception {
|
||||
List<LogUpdateEvent> events = readAll("log-update-event-ansi.stream");
|
||||
assertThat(events).hasSize(20);
|
||||
assertThat(events.get(0).toString()).isEqualTo("");
|
||||
assertThat(events.get(1).toString()).isEqualTo("Cloud Foundry OpenJDK Buildpack v1.0.64");
|
||||
assertThat(events.get(2).toString()).isEqualTo(" OpenJDK JRE 11.0.5: Reusing cached layer");
|
||||
}
|
||||
|
||||
private List<LogUpdateEvent> readAll(String name) throws IOException {
|
||||
List<LogUpdateEvent> events = new ArrayList<>();
|
||||
try (InputStream inputStream = getClass().getResourceAsStream(name)) {
|
||||
LogUpdateEvent.readAll(inputStream, events::add);
|
||||
}
|
||||
return events;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.ProgressUpdateEvent.ProgressDetail;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ProgressUpdateEvent}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
abstract class ProgressUpdateEventTests {
|
||||
|
||||
@Test
|
||||
void getStatusReturnsStatus() {
|
||||
ProgressUpdateEvent event = createEvent();
|
||||
assertThat(event.getStatus()).isEqualTo("status");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getProgressDetailsReturnsProgresssDetails() {
|
||||
ProgressUpdateEvent event = createEvent();
|
||||
assertThat(event.getProgressDetail().getCurrent()).isEqualTo(1);
|
||||
assertThat(event.getProgressDetail().getTotal()).isEqualTo(2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getProgressReturnsProgress() {
|
||||
ProgressUpdateEvent event = createEvent();
|
||||
assertThat(event.getProgress()).isEqualTo("progress");
|
||||
}
|
||||
|
||||
@Test
|
||||
void progressDetailIsEmptyWhenCurrentIsNullReturnsTrue() {
|
||||
ProgressDetail detail = new ProgressDetail(null, 2);
|
||||
assertThat(ProgressDetail.isEmpty(detail)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void progressDetailIsEmptyWhenTotalIsNullReturnsTrue() {
|
||||
ProgressDetail detail = new ProgressDetail(1, null);
|
||||
assertThat(ProgressDetail.isEmpty(detail)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void progressDetailIsEmptyWhenTotalAndCurrentAreNotNullReturnsFalse() {
|
||||
ProgressDetail detail = new ProgressDetail(1, 2);
|
||||
assertThat(ProgressDetail.isEmpty(detail)).isFalse();
|
||||
}
|
||||
|
||||
protected ProgressUpdateEvent createEvent() {
|
||||
return createEvent("status", new ProgressDetail(1, 2), "progress");
|
||||
}
|
||||
|
||||
protected abstract ProgressUpdateEvent createEvent(String status, ProgressDetail progressDetail, String progress);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.docker.ProgressUpdateEvent.ProgressDetail;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link PullImageUpdateEvent}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class PullImageUpdateEventTests extends ProgressUpdateEventTests {
|
||||
|
||||
@Test
|
||||
void getIdReturnsId() {
|
||||
PullImageUpdateEvent event = (PullImageUpdateEvent) createEvent();
|
||||
assertThat(event.getId()).isEqualTo("id");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ProgressUpdateEvent createEvent(String status, ProgressDetail progressDetail, String progress) {
|
||||
return new PullImageUpdateEvent("id", status, progressDetail, progress);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.json.AbstractJsonTests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link PullImageUpdateEvent}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class PullUpdateEventTests extends AbstractJsonTests {
|
||||
|
||||
@Test
|
||||
void readValueWhenFullDeserializesJson() throws Exception {
|
||||
PullImageUpdateEvent event = getObjectMapper().readValue(getContent("pull-update-full.json"),
|
||||
PullImageUpdateEvent.class);
|
||||
assertThat(event.getId()).isEqualTo("4f4fb700ef54");
|
||||
assertThat(event.getStatus()).isEqualTo("Extracting");
|
||||
assertThat(event.getProgressDetail().getCurrent()).isEqualTo(16);
|
||||
assertThat(event.getProgressDetail().getTotal()).isEqualTo(32);
|
||||
assertThat(event.getProgress()).isEqualTo("[==================================================>] 32B/32B");
|
||||
}
|
||||
|
||||
@Test
|
||||
void readValueWhenMinimalDeserializesJson() throws Exception {
|
||||
PullImageUpdateEvent event = getObjectMapper().readValue(getContent("pull-update-minimal.json"),
|
||||
PullImageUpdateEvent.class);
|
||||
assertThat(event.getId()).isNull();
|
||||
assertThat(event.getStatus()).isEqualTo("Status: Downloaded newer image for cloudfoundry/cnb:bionic");
|
||||
assertThat(event.getProgressDetail()).isNull();
|
||||
assertThat(event.getProgress()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void readValueWhenEmptyDetailsDeserializesJson() throws Exception {
|
||||
PullImageUpdateEvent event = getObjectMapper().readValue(getContent("pull-with-empty-details.json"),
|
||||
PullImageUpdateEvent.class);
|
||||
assertThat(event.getId()).isEqualTo("d837a2a1365e");
|
||||
assertThat(event.getStatus()).isEqualTo("Pulling fs layer");
|
||||
assertThat(event.getProgressDetail()).isNull();
|
||||
assertThat(event.getProgress()).isNull();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link TotalProgressBar}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class TotalProgressBarTests {
|
||||
|
||||
@Test
|
||||
void withPrefixAndBookends() {
|
||||
TestPrintStream out = new TestPrintStream();
|
||||
TotalProgressBar bar = new TotalProgressBar("prefix:", '#', true, out);
|
||||
assertThat(out).hasToString("prefix: [ ");
|
||||
bar.accept(new TotalProgressEvent(10));
|
||||
assertThat(out.toString()).isEqualTo("prefix: [ #####");
|
||||
bar.accept(new TotalProgressEvent(50));
|
||||
assertThat(out.toString()).isEqualTo("prefix: [ #########################");
|
||||
bar.accept(new TotalProgressEvent(100));
|
||||
assertThat(out.toString()).isEqualTo("prefix: [ ################################################## ]\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
void withoutPrefix() {
|
||||
TestPrintStream out = new TestPrintStream();
|
||||
TotalProgressBar bar = new TotalProgressBar(null, '#', true, out);
|
||||
assertThat(out).hasToString("[ ");
|
||||
bar.accept(new TotalProgressEvent(10));
|
||||
assertThat(out.toString()).isEqualTo("[ #####");
|
||||
bar.accept(new TotalProgressEvent(50));
|
||||
assertThat(out.toString()).isEqualTo("[ #########################");
|
||||
bar.accept(new TotalProgressEvent(100));
|
||||
assertThat(out.toString()).isEqualTo("[ ################################################## ]\n");
|
||||
}
|
||||
|
||||
@Test
|
||||
void withoutBookends() {
|
||||
TestPrintStream out = new TestPrintStream();
|
||||
TotalProgressBar bar = new TotalProgressBar("", '.', false, out);
|
||||
assertThat(out).hasToString("");
|
||||
bar.accept(new TotalProgressEvent(10));
|
||||
assertThat(out.toString()).isEqualTo(".....");
|
||||
bar.accept(new TotalProgressEvent(50));
|
||||
assertThat(out.toString()).isEqualTo(".........................");
|
||||
bar.accept(new TotalProgressEvent(100));
|
||||
assertThat(out.toString()).isEqualTo("..................................................\n");
|
||||
}
|
||||
|
||||
static class TestPrintStream extends PrintStream {
|
||||
|
||||
TestPrintStream() {
|
||||
super(new ByteArrayOutputStream());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.out.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link TotalProgressEvent}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class TotalProgressEventTests {
|
||||
|
||||
@Test
|
||||
void create() {
|
||||
assertThat(new TotalProgressEvent(0).getPercent()).isEqualTo(0);
|
||||
assertThat(new TotalProgressEvent(10).getPercent()).isEqualTo(10);
|
||||
assertThat(new TotalProgressEvent(100).getPercent()).isEqualTo(100);
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenPercentLessThanZeroThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new TotalProgressEvent(-1))
|
||||
.withMessage("Percent must be in the range 0 to 100");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenEventMoreThanOneHundredThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new TotalProgressEvent(101))
|
||||
.withMessage("Percent must be in the range 0 to 100");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.json.AbstractJsonTests;
|
||||
import org.springframework.boot.buildpack.platform.json.JsonStream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link TotalProgressPullListener}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class TotalProgressPullListenerTests extends AbstractJsonTests {
|
||||
|
||||
@Test
|
||||
void totalProgress() throws Exception {
|
||||
List<Integer> progress = new ArrayList<>();
|
||||
TotalProgressPullListener listener = new TotalProgressPullListener((event) -> progress.add(event.getPercent()));
|
||||
run(listener);
|
||||
int last = 0;
|
||||
for (Integer update : progress) {
|
||||
assertThat(update).isGreaterThanOrEqualTo(last);
|
||||
last = update;
|
||||
}
|
||||
assertThat(last).isEqualTo(100);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Disabled("For visual inspection")
|
||||
void totalProgressUpdatesSmoothly() throws Exception {
|
||||
TestTotalProgressPullListener listener = new TestTotalProgressPullListener(
|
||||
new TotalProgressBar("Pulling layers:"));
|
||||
run(listener);
|
||||
}
|
||||
|
||||
private void run(TotalProgressPullListener listener) throws IOException {
|
||||
JsonStream jsonStream = new JsonStream(getObjectMapper());
|
||||
listener.onStart();
|
||||
jsonStream.get(getContent("pull-stream.json"), PullImageUpdateEvent.class, listener::onUpdate);
|
||||
listener.onFinish();
|
||||
}
|
||||
|
||||
private static class TestTotalProgressPullListener extends TotalProgressPullListener {
|
||||
|
||||
TestTotalProgressPullListener(Consumer<TotalProgressEvent> consumer) {
|
||||
super(consumer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdate(PullImageUpdateEvent event) {
|
||||
super.onUpdate(event);
|
||||
try {
|
||||
Thread.sleep(10);
|
||||
}
|
||||
catch (InterruptedException ex) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker.type;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.skyscreamer.jsonassert.JSONAssert;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.json.AbstractJsonTests;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link ContainerConfig}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ContainerConfigTests extends AbstractJsonTests {
|
||||
|
||||
@Test
|
||||
void ofWhenImageReferenceIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> ContainerConfig.of(null, (update) -> {
|
||||
})).withMessage("ImageReference must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenUpdateIsNullThrowsException() {
|
||||
ImageReference imageReference = ImageReference.of("ubuntu:bionic");
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> ContainerConfig.of(imageReference, null))
|
||||
.withMessage("Update must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void writeToWritesJson() throws Exception {
|
||||
ImageReference imageReference = ImageReference.of("ubuntu:bionic");
|
||||
ContainerConfig containerConfig = ContainerConfig.of(imageReference, (update) -> {
|
||||
update.withUser("root");
|
||||
update.withCommand("ls", "-l");
|
||||
update.withArgs("-h");
|
||||
update.withLabel("spring", "boot");
|
||||
update.withBind("bind-source", "bind-dest");
|
||||
});
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
containerConfig.writeTo(outputStream);
|
||||
String actualJson = new String(outputStream.toByteArray(), StandardCharsets.UTF_8);
|
||||
String expectedJson = StreamUtils.copyToString(getContent("container-config.json"), StandardCharsets.UTF_8);
|
||||
JSONAssert.assertEquals(expectedJson, actualJson, false);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker.type;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.io.TarArchive;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link ContainerContent}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ContainerContentTests {
|
||||
|
||||
@Test
|
||||
void ofWhenArchiveIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> ContainerContent.of(null))
|
||||
.withMessage("Archive must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenDestinationPathIsNullThrowsException() {
|
||||
TarArchive archive = mock(TarArchive.class);
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> ContainerContent.of(archive, null))
|
||||
.withMessage("DestinationPath must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenDestinationPathIsEmptyThrowsException() {
|
||||
TarArchive archive = mock(TarArchive.class);
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> ContainerContent.of(archive, ""))
|
||||
.withMessage("DestinationPath must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofCreatesContainerContent() {
|
||||
TarArchive archive = mock(TarArchive.class);
|
||||
ContainerContent content = ContainerContent.of(archive);
|
||||
assertThat(content.getArchive()).isSameAs(archive);
|
||||
assertThat(content.getDestinationPath()).isEqualTo("/");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWithDestinationPathCreatesContainerContent() {
|
||||
TarArchive archive = mock(TarArchive.class);
|
||||
ContainerContent content = ContainerContent.of(archive, "/test");
|
||||
assertThat(content.getArchive()).isSameAs(archive);
|
||||
assertThat(content.getDestinationPath()).isEqualTo("/test");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker.type;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link ContainerReference}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ContainerReferenceTests {
|
||||
|
||||
@Test
|
||||
void ofCreatesInstance() {
|
||||
ContainerReference reference = ContainerReference
|
||||
.of("92691aec176333f7ae890de9aaeeafef11166efcaa3908edf83eb44a5c943781");
|
||||
assertThat(reference.toString()).isEqualTo("92691aec176333f7ae890de9aaeeafef11166efcaa3908edf83eb44a5c943781");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> ContainerReference.of(null))
|
||||
.withMessage("Value must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenEmptyThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> ContainerReference.of(""))
|
||||
.withMessage("Value must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hashCodeAndEquals() {
|
||||
ContainerReference r1 = ContainerReference
|
||||
.of("92691aec176333f7ae890de9aaeeafef11166efcaa3908edf83eb44a5c943781");
|
||||
ContainerReference r2 = ContainerReference
|
||||
.of("92691aec176333f7ae890de9aaeeafef11166efcaa3908edf83eb44a5c943781");
|
||||
ContainerReference r3 = ContainerReference
|
||||
.of("02691aec176333f7ae890de9aaeeafef11166efcaa3908edf83eb44a5c943781");
|
||||
assertThat(r1.hashCode()).isEqualTo(r2.hashCode());
|
||||
assertThat(r1).isEqualTo(r1).isEqualTo(r2).isNotEqualTo(r3);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker.type;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.time.Instant;
|
||||
import java.time.OffsetDateTime;
|
||||
import java.time.ZoneOffset;
|
||||
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.skyscreamer.jsonassert.JSONAssert;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.io.Owner;
|
||||
import org.springframework.boot.buildpack.platform.json.AbstractJsonTests;
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ImageArchive}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ImageArchiveTests extends AbstractJsonTests {
|
||||
|
||||
static final Instant CREATE_DATE = OffsetDateTime.of(1906, 12, 9, 11, 30, 0, 0, ZoneOffset.UTC).toInstant();
|
||||
|
||||
@Test
|
||||
void fromImageWritesToValidArchiveTar() throws Exception {
|
||||
Image image = Image.of(getContent("image.json"));
|
||||
ImageArchive archive = ImageArchive.from(image, (update) -> {
|
||||
update.withNewLayer(Layer.of((layout) -> layout.folder("/spring", Owner.ROOT)));
|
||||
update.withCreateDate(CREATE_DATE);
|
||||
update.withTag(ImageReference.of("pack.local/builder/6b7874626575656b6162"));
|
||||
});
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
archive.writeTo(outputStream);
|
||||
try (TarArchiveInputStream tar = new TarArchiveInputStream(
|
||||
new ByteArrayInputStream(outputStream.toByteArray()))) {
|
||||
TarArchiveEntry layerEntry = tar.getNextTarEntry();
|
||||
byte[] layerContent = read(tar, layerEntry.getSize());
|
||||
TarArchiveEntry configEntry = tar.getNextTarEntry();
|
||||
byte[] configContent = read(tar, configEntry.getSize());
|
||||
TarArchiveEntry manifestEntry = tar.getNextTarEntry();
|
||||
byte[] manifestContent = read(tar, manifestEntry.getSize());
|
||||
assertThat(tar.getNextTarEntry()).isNull();
|
||||
assertExpectedLayer(layerEntry, layerContent);
|
||||
assertExpectedConfig(configEntry, configContent);
|
||||
assertExpectedManifest(manifestEntry, manifestContent);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertExpectedLayer(TarArchiveEntry entry, byte[] content) throws Exception {
|
||||
assertThat(entry.getName()).isEqualTo("/bb09e17fd1bd2ee47155f1349645fcd9fff31e1247c7ed99cad469f1c16a4216.tar");
|
||||
try (TarArchiveInputStream tar = new TarArchiveInputStream(new ByteArrayInputStream(content))) {
|
||||
TarArchiveEntry contentEntry = tar.getNextTarEntry();
|
||||
assertThat(contentEntry.getName()).isEqualTo("/spring/");
|
||||
}
|
||||
}
|
||||
|
||||
private void assertExpectedConfig(TarArchiveEntry entry, byte[] content) throws Exception {
|
||||
assertThat(entry.getName()).isEqualTo("/d1872169d781cff5e1aa22d111f636bef0c57e1c358ca3861e3d33a5bdb1b4a5.json");
|
||||
String actualJson = new String(content, StandardCharsets.UTF_8);
|
||||
String expectedJson = StreamUtils.copyToString(getContent("image-archive-config.json"), StandardCharsets.UTF_8);
|
||||
JSONAssert.assertEquals(expectedJson, actualJson, false);
|
||||
}
|
||||
|
||||
private void assertExpectedManifest(TarArchiveEntry entry, byte[] content) throws Exception {
|
||||
assertThat(entry.getName()).isEqualTo("/manifest.json");
|
||||
String actualJson = new String(content, StandardCharsets.UTF_8);
|
||||
String expectedJson = StreamUtils.copyToString(getContent("image-archive-manifest.json"),
|
||||
StandardCharsets.UTF_8);
|
||||
JSONAssert.assertEquals(expectedJson, actualJson, false);
|
||||
}
|
||||
|
||||
private byte[] read(TarArchiveInputStream tar, long size) throws IOException {
|
||||
byte[] content = new byte[(int) size];
|
||||
tar.read(content);
|
||||
return content;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker.type;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.json.AbstractJsonTests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
|
||||
/**
|
||||
* Tests for {@link ImageConfig}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ImageConfigTests extends AbstractJsonTests {
|
||||
|
||||
@Test
|
||||
void getEnvContainsParsedValues() throws Exception {
|
||||
ImageConfig imageConfig = getImageConfig();
|
||||
Map<String, String> env = imageConfig.getEnv();
|
||||
assertThat(env).contains(entry("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"),
|
||||
entry("CNB_USER_ID", "2000"), entry("CNB_GROUP_ID", "2000"),
|
||||
entry("CNB_STACK_ID", "org.cloudfoundry.stacks.cflinuxfs3"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getLabelsReturnsLabels() throws Exception {
|
||||
ImageConfig imageConfig = getImageConfig();
|
||||
Map<String, String> lables = imageConfig.getLabels();
|
||||
assertThat(lables).hasSize(4).contains(entry("io.buildpacks.stack.id", "org.cloudfoundry.stacks.cflinuxfs3"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateWithLabelUpdatesLabels() throws Exception {
|
||||
ImageConfig imageConfig = getImageConfig();
|
||||
ImageConfig updatedImageConfig = imageConfig
|
||||
.copy((update) -> update.withLabel("io.buildpacks.stack.id", "test"));
|
||||
assertThat(imageConfig.getLabels()).hasSize(4)
|
||||
.contains(entry("io.buildpacks.stack.id", "org.cloudfoundry.stacks.cflinuxfs3"));
|
||||
assertThat(updatedImageConfig.getLabels()).hasSize(4).contains(entry("io.buildpacks.stack.id", "test"));
|
||||
}
|
||||
|
||||
private ImageConfig getImageConfig() throws IOException {
|
||||
return new ImageConfig(getObjectMapper().readTree(getContent("image-config.json")));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker.type;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link ImageName}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ImageNameTests {
|
||||
|
||||
@Test
|
||||
void ofWhenNameOnlyCreatesImageName() {
|
||||
ImageName imageName = ImageName.of("ubuntu");
|
||||
assertThat(imageName.toString()).isEqualTo("docker.io/library/ubuntu");
|
||||
assertThat(imageName.getDomain()).isEqualTo("docker.io");
|
||||
assertThat(imageName.getName()).isEqualTo("library/ubuntu");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenSlashedNameCreatesImageName() {
|
||||
ImageName imageName = ImageName.of("canonical/ubuntu");
|
||||
assertThat(imageName.toString()).isEqualTo("docker.io/canonical/ubuntu");
|
||||
assertThat(imageName.getDomain()).isEqualTo("docker.io");
|
||||
assertThat(imageName.getName()).isEqualTo("canonical/ubuntu");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenLocalhostNameCreatesImageName() {
|
||||
ImageName imageName = ImageName.of("localhost/canonical/ubuntu");
|
||||
assertThat(imageName.toString()).isEqualTo("localhost/canonical/ubuntu");
|
||||
assertThat(imageName.getDomain()).isEqualTo("localhost");
|
||||
assertThat(imageName.getName()).isEqualTo("canonical/ubuntu");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenDomainAndNameCreatesImageName() {
|
||||
ImageName imageName = ImageName.of("repo.spring.io/canonical/ubuntu");
|
||||
assertThat(imageName.toString()).isEqualTo("repo.spring.io/canonical/ubuntu");
|
||||
assertThat(imageName.getDomain()).isEqualTo("repo.spring.io");
|
||||
assertThat(imageName.getName()).isEqualTo("canonical/ubuntu");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenDomainNameAndPortCreatesImageName() {
|
||||
ImageName imageName = ImageName.of("repo.spring.io:8080/canonical/ubuntu");
|
||||
assertThat(imageName.toString()).isEqualTo("repo.spring.io:8080/canonical/ubuntu");
|
||||
assertThat(imageName.getDomain()).isEqualTo("repo.spring.io:8080");
|
||||
assertThat(imageName.getName()).isEqualTo("canonical/ubuntu");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenSimpleNameAndPortCreatesImageName() {
|
||||
ImageName imageName = ImageName.of("repo:8080/canonical/ubuntu");
|
||||
assertThat(imageName.toString()).isEqualTo("repo:8080/canonical/ubuntu");
|
||||
assertThat(imageName.getDomain()).isEqualTo("repo:8080");
|
||||
assertThat(imageName.getName()).isEqualTo("canonical/ubuntu");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenLegacyDomainUsesNewDomain() {
|
||||
ImageName imageName = ImageName.of("index.docker.io/ubuntu");
|
||||
assertThat(imageName.toString()).isEqualTo("docker.io/library/ubuntu");
|
||||
assertThat(imageName.getDomain()).isEqualTo("docker.io");
|
||||
assertThat(imageName.getName()).isEqualTo("library/ubuntu");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenNameIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> ImageName.of(null))
|
||||
.withMessage("Value must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenNameIsEmptyThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> ImageName.of("")).withMessage("Value must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hashCodeAndEquals() {
|
||||
ImageName n1 = ImageName.of("ubuntu");
|
||||
ImageName n2 = ImageName.of("library/ubuntu");
|
||||
ImageName n3 = ImageName.of("docker.io/library/ubuntu");
|
||||
ImageName n4 = ImageName.of("index.docker.io/library/ubuntu");
|
||||
ImageName n5 = ImageName.of("alpine");
|
||||
assertThat(n1.hashCode()).isEqualTo(n2.hashCode()).isEqualTo(n3.hashCode()).isEqualTo(n4.hashCode());
|
||||
assertThat(n1).isEqualTo(n1).isEqualTo(n2).isEqualTo(n3).isEqualTo(n4).isNotEqualTo(n5);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker.type;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
||||
/**
|
||||
* Tests for {@link ImageReference}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ImageReferenceTests {
|
||||
|
||||
@Test
|
||||
void ofSimpleName() {
|
||||
ImageReference reference = ImageReference.of("ubuntu");
|
||||
assertThat(reference.getDomain()).isEqualTo("docker.io");
|
||||
assertThat(reference.getName()).isEqualTo("library/ubuntu");
|
||||
assertThat(reference.getTag()).isNull();
|
||||
assertThat(reference.getDigest()).isNull();
|
||||
assertThat(reference.toString()).isEqualTo("docker.io/library/ubuntu");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofLibrarySlashName() {
|
||||
ImageReference reference = ImageReference.of("library/ubuntu");
|
||||
assertThat(reference.getDomain()).isEqualTo("docker.io");
|
||||
assertThat(reference.getName()).isEqualTo("library/ubuntu");
|
||||
assertThat(reference.getTag()).isNull();
|
||||
assertThat(reference.getDigest()).isNull();
|
||||
assertThat(reference.toString()).isEqualTo("docker.io/library/ubuntu");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofSlashName() {
|
||||
ImageReference reference = ImageReference.of("adoptopenjdk/openjdk11");
|
||||
assertThat(reference.getDomain()).isEqualTo("docker.io");
|
||||
assertThat(reference.getName()).isEqualTo("adoptopenjdk/openjdk11");
|
||||
assertThat(reference.getTag()).isNull();
|
||||
assertThat(reference.getDigest()).isNull();
|
||||
assertThat(reference.toString()).isEqualTo("docker.io/adoptopenjdk/openjdk11");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofCustomDomain() {
|
||||
ImageReference reference = ImageReference.of("repo.example.com/java/jdk");
|
||||
assertThat(reference.getDomain()).isEqualTo("repo.example.com");
|
||||
assertThat(reference.getName()).isEqualTo("java/jdk");
|
||||
assertThat(reference.getTag()).isNull();
|
||||
assertThat(reference.getDigest()).isNull();
|
||||
assertThat(reference.toString()).isEqualTo("repo.example.com/java/jdk");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofCustomDomainAndPort() {
|
||||
ImageReference reference = ImageReference.of("repo.example.com:8080/java/jdk");
|
||||
assertThat(reference.getDomain()).isEqualTo("repo.example.com:8080");
|
||||
assertThat(reference.getName()).isEqualTo("java/jdk");
|
||||
assertThat(reference.getTag()).isNull();
|
||||
assertThat(reference.getDigest()).isNull();
|
||||
assertThat(reference.toString()).isEqualTo("repo.example.com:8080/java/jdk");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofLegacyDomain() {
|
||||
ImageReference reference = ImageReference.of("index.docker.io/ubuntu");
|
||||
assertThat(reference.getDomain()).isEqualTo("docker.io");
|
||||
assertThat(reference.getName()).isEqualTo("library/ubuntu");
|
||||
assertThat(reference.getTag()).isNull();
|
||||
assertThat(reference.getDigest()).isNull();
|
||||
assertThat(reference.toString()).isEqualTo("docker.io/library/ubuntu");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofNameAndTag() {
|
||||
ImageReference reference = ImageReference.of("ubuntu:bionic");
|
||||
assertThat(reference.getDomain()).isEqualTo("docker.io");
|
||||
assertThat(reference.getName()).isEqualTo("library/ubuntu");
|
||||
assertThat(reference.getTag()).isEqualTo("bionic");
|
||||
assertThat(reference.getDigest()).isNull();
|
||||
assertThat(reference.toString()).isEqualTo("docker.io/library/ubuntu:bionic");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofNameAndDigest() {
|
||||
ImageReference reference = ImageReference
|
||||
.of("ubuntu@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d");
|
||||
assertThat(reference.getDomain()).isEqualTo("docker.io");
|
||||
assertThat(reference.getName()).isEqualTo("library/ubuntu");
|
||||
assertThat(reference.getTag()).isNull();
|
||||
assertThat(reference.getDigest())
|
||||
.isEqualTo("sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d");
|
||||
assertThat(reference.toString()).isEqualTo(
|
||||
"docker.io/library/ubuntu@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofNameAndTagAndDigest() {
|
||||
ImageReference reference = ImageReference
|
||||
.of("ubuntu:bionic@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d");
|
||||
assertThat(reference.getDomain()).isEqualTo("docker.io");
|
||||
assertThat(reference.getName()).isEqualTo("library/ubuntu");
|
||||
assertThat(reference.getTag()).isEqualTo("bionic");
|
||||
assertThat(reference.getDigest())
|
||||
.isEqualTo("sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d");
|
||||
assertThat(reference.toString()).isEqualTo(
|
||||
"docker.io/library/ubuntu:bionic@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofCustomDomainAndPortWithTag() {
|
||||
ImageReference reference = ImageReference.of(
|
||||
"example.com:8080/canonical/ubuntu:bionic@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d");
|
||||
assertThat(reference.getDomain()).isEqualTo("example.com:8080");
|
||||
assertThat(reference.getName()).isEqualTo("canonical/ubuntu");
|
||||
assertThat(reference.getTag()).isEqualTo("bionic");
|
||||
assertThat(reference.getDigest())
|
||||
.isEqualTo("sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d");
|
||||
assertThat(reference.toString()).isEqualTo(
|
||||
"example.com:8080/canonical/ubuntu:bionic@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofImageName() {
|
||||
ImageReference reference = ImageReference.of(ImageName.of("ubuntu"));
|
||||
assertThat(reference.toString()).isEqualTo("docker.io/library/ubuntu");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofImageNameAndTag() {
|
||||
ImageReference reference = ImageReference.of(ImageName.of("ubuntu"), "bionic");
|
||||
assertThat(reference.toString()).isEqualTo("docker.io/library/ubuntu:bionic");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofImageNameTagAndDigest() {
|
||||
ImageReference reference = ImageReference.of(ImageName.of("ubuntu"), "bionic",
|
||||
"sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d");
|
||||
assertThat(reference.toString()).isEqualTo(
|
||||
"docker.io/library/ubuntu:bionic@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d");
|
||||
}
|
||||
|
||||
@Test
|
||||
void forJarFile() {
|
||||
assertForJarFile("spring-boot.2.0.0.BUILD-SNAPSHOT.jar", "library/spring-boot", "2.0.0.BUILD-SNAPSHOT");
|
||||
assertForJarFile("spring-boot.2.0.0.M1.jar", "library/spring-boot", "2.0.0.M1");
|
||||
assertForJarFile("spring-boot.2.0.0.RC1.jar", "library/spring-boot", "2.0.0.RC1");
|
||||
assertForJarFile("spring-boot.2.0.0.RELEASE.jar", "library/spring-boot", "2.0.0.RELEASE");
|
||||
assertForJarFile("sample-0.0.1-SNAPSHOT.jar", "library/sample", "0.0.1-SNAPSHOT");
|
||||
assertForJarFile("sample-0.0.1.jar", "library/sample", "0.0.1");
|
||||
}
|
||||
|
||||
private void assertForJarFile(String jarFile, String expectedName, String expectedTag) {
|
||||
ImageReference reference = ImageReference.forJarFile(new File(jarFile));
|
||||
assertThat(reference.getName()).isEqualTo(expectedName);
|
||||
assertThat(reference.getTag()).isEqualTo(expectedTag);
|
||||
}
|
||||
|
||||
@Test
|
||||
void randomGeneratesRandomName() {
|
||||
String prefix = "pack.local/builder/";
|
||||
ImageReference random = ImageReference.random(prefix);
|
||||
assertThat(random.toString()).startsWith(prefix).hasSize(prefix.length() + 10);
|
||||
ImageReference another = ImageReference.random(prefix);
|
||||
int attempts = 0;
|
||||
while (another.equals(random)) {
|
||||
assertThat(attempts).as("Duplicate results").isLessThan(10);
|
||||
another = ImageReference.random(prefix);
|
||||
attempts++;
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void randomWithLengthGeneratesRandomName() {
|
||||
String prefix = "pack.local/builder/";
|
||||
ImageReference random = ImageReference.random(prefix, 20);
|
||||
assertThat(random.toString()).startsWith(prefix).hasSize(prefix.length() + 20);
|
||||
}
|
||||
|
||||
@Test
|
||||
void randomWherePrefixIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> ImageReference.random(null))
|
||||
.withMessage("Prefix must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void inTaggedFormWhenHasDigestThrowsException() {
|
||||
ImageReference reference = ImageReference
|
||||
.of("ubuntu@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d");
|
||||
assertThatIllegalStateException().isThrownBy(() -> reference.inTaggedForm()).withMessage(
|
||||
"Image reference 'docker.io/library/ubuntu@sha256:6e9f67fa63b0323e9a1e587fd71c561ba48a034504fb804fd26fd8800039835d' cannot contain a digest");
|
||||
}
|
||||
|
||||
@Test
|
||||
void inTaggedFormWhenHasNoTagUsesLatest() {
|
||||
ImageReference reference = ImageReference.of("ubuntu");
|
||||
assertThat(reference.inTaggedForm().toString()).isEqualTo("docker.io/library/ubuntu:latest");
|
||||
}
|
||||
|
||||
@Test
|
||||
void inTaggedFormWhenHasTagUsesTag() {
|
||||
ImageReference reference = ImageReference.of("ubuntu:bionic");
|
||||
assertThat(reference.inTaggedForm().toString()).isEqualTo("docker.io/library/ubuntu:bionic");
|
||||
}
|
||||
|
||||
@Test
|
||||
void equalsAndHashCode() {
|
||||
ImageReference r1 = ImageReference.of("ubuntu:bionic");
|
||||
ImageReference r2 = ImageReference.of("docker.io/library/ubuntu:bionic");
|
||||
ImageReference r3 = ImageReference.of("docker.io/library/ubuntu:latest");
|
||||
assertThat(r1.hashCode()).isEqualTo(r2.hashCode());
|
||||
assertThat(r1).isEqualTo(r1).isEqualTo(r2).isNotEqualTo(r3);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker.type;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.json.AbstractJsonTests;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.entry;
|
||||
|
||||
/**
|
||||
* Tests for {@link Image}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ImageTests extends AbstractJsonTests {
|
||||
|
||||
@Test
|
||||
void getConfigEnvContainsParsedValues() throws Exception {
|
||||
Image image = getImage();
|
||||
Map<String, String> env = image.getConfig().getEnv();
|
||||
assertThat(env).contains(entry("PATH", "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"),
|
||||
entry("CNB_USER_ID", "2000"), entry("CNB_GROUP_ID", "2000"),
|
||||
entry("CNB_STACK_ID", "org.cloudfoundry.stacks.cflinuxfs3"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getConfigLabelsReturnsLabels() throws Exception {
|
||||
Image image = getImage();
|
||||
Map<String, String> lables = image.getConfig().getLabels();
|
||||
assertThat(lables).contains(entry("io.buildpacks.stack.id", "org.cloudfoundry.stacks.cflinuxfs3"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void getLayersReturnsImageLayers() throws Exception {
|
||||
Image image = getImage();
|
||||
List<LayerId> layers = image.getLayers();
|
||||
assertThat(layers).hasSize(46);
|
||||
assertThat(layers.get(0).toString())
|
||||
.isEqualTo("sha256:733a8e5ce32984099ef675fce04730f6e2a6dcfdf5bd292fea01a8f936265342");
|
||||
assertThat(layers.get(45).toString())
|
||||
.isEqualTo("sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getOsReturnsOs() throws Exception {
|
||||
Image image = getImage();
|
||||
assertThat(image.getOs()).isEqualTo("linux");
|
||||
}
|
||||
|
||||
private Image getImage() throws IOException {
|
||||
return Image.of(getContent("image.json"));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker.type;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Test for {@link LayerId}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class LayerIdTests {
|
||||
|
||||
@Test
|
||||
void ofReturnsLayerId() {
|
||||
LayerId id = LayerId.of("sha256:9a183e56c86d376b408bdf922746d0a657f62b0e18c7c8f82a496b87710c576f");
|
||||
assertThat(id.getAlgorithm()).isEqualTo("sha256");
|
||||
assertThat(id.getHash()).isEqualTo("9a183e56c86d376b408bdf922746d0a657f62b0e18c7c8f82a496b87710c576f");
|
||||
assertThat(id.toString()).isEqualTo("sha256:9a183e56c86d376b408bdf922746d0a657f62b0e18c7c8f82a496b87710c576f");
|
||||
}
|
||||
|
||||
@Test
|
||||
void hashCodeAndEquals() {
|
||||
LayerId id1 = LayerId.of("sha256:9a183e56c86d376b408bdf922746d0a657f62b0e18c7c8f82a496b87710c576f");
|
||||
LayerId id2 = LayerId.of("sha256:9a183e56c86d376b408bdf922746d0a657f62b0e18c7c8f82a496b87710c576f");
|
||||
LayerId id3 = LayerId.of("sha256:ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
|
||||
assertThat(id1.hashCode()).isEqualTo(id2.hashCode());
|
||||
assertThat(id1).isEqualTo(id1).isEqualTo(id2).isNotEqualTo(id3);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenValueIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> LayerId.of((String) null))
|
||||
.withMessage("Value must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenValueIsEmptyThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> LayerId.of(" ")).withMessage("Value must not be empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofSha256Digest() throws Exception {
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
digest.update("test".getBytes(StandardCharsets.UTF_8));
|
||||
LayerId id = LayerId.ofSha256Digest(digest.digest());
|
||||
assertThat(id.toString()).isEqualTo("sha256:9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofSha256DigestWhenNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> LayerId.ofSha256Digest((byte[]) null))
|
||||
.withMessage("Digest must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofSha256DigestWhenWrongLengthThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> LayerId.ofSha256Digest(new byte[31]))
|
||||
.withMessage("Digest must be exactly 32 bytes");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker.type;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.io.Content;
|
||||
import org.springframework.boot.buildpack.platform.io.IOConsumer;
|
||||
import org.springframework.boot.buildpack.platform.io.Layout;
|
||||
import org.springframework.boot.buildpack.platform.io.Owner;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link Layer}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class LayerTests {
|
||||
|
||||
@Test
|
||||
void ofWhenLayoutIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> Layer.of((IOConsumer<Layout>) null))
|
||||
.withMessage("Layout must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromTarArchiveWhenTarArchiveIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> Layer.fromTarArchive(null))
|
||||
.withMessage("TarArchive must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofCreatesLayer() throws Exception {
|
||||
Layer layer = Layer.of((layout) -> {
|
||||
layout.folder("/folder", Owner.ROOT);
|
||||
layout.file("/folder/file", Owner.ROOT, Content.of("test"));
|
||||
});
|
||||
assertThat(layer.getId().toString())
|
||||
.isEqualTo("sha256:8b8a3cea2ba716da6bbb0a3bf7472f235fa08c71a27cec5fbf2de1cf1baa513f");
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
layer.writeTo(outputStream);
|
||||
try (TarArchiveInputStream tarStream = new TarArchiveInputStream(
|
||||
new ByteArrayInputStream(outputStream.toByteArray()))) {
|
||||
assertThat(tarStream.getNextTarEntry().getName()).isEqualTo("/folder/");
|
||||
assertThat(tarStream.getNextTarEntry().getName()).isEqualTo("/folder/file");
|
||||
assertThat(tarStream.getNextTarEntry()).isNull();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker.type;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link RandomString}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class RandomStringTests {
|
||||
|
||||
@Test
|
||||
void generateWhenPrefixIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> RandomString.generate(null, 10))
|
||||
.withMessage("Prefix must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void generateGeneratesRandomString() {
|
||||
String s1 = RandomString.generate("abc-", 10);
|
||||
String s2 = RandomString.generate("abc-", 10);
|
||||
String s3 = RandomString.generate("abc-", 20);
|
||||
assertThat(s1).hasSize(14).startsWith("abc-").isNotEqualTo(s2);
|
||||
assertThat(s3).hasSize(24).startsWith("abc-");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.docker.type;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link VolumeName}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class VolumeNameTests {
|
||||
|
||||
@Test
|
||||
void randomWhenPrefixIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> VolumeName.random(null))
|
||||
.withMessage("Prefix must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void randomGeneratesRandomString() {
|
||||
VolumeName v1 = VolumeName.random("abc-");
|
||||
VolumeName v2 = VolumeName.random("abc-");
|
||||
assertThat(v1.toString()).startsWith("abc-").hasSize(14);
|
||||
assertThat(v2.toString()).startsWith("abc-").hasSize(14);
|
||||
assertThat(v1).isNotEqualTo(v2);
|
||||
assertThat(v1.toString()).isNotEqualTo(v2.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void randomStringWithLengthGeneratesRandomString() {
|
||||
VolumeName v1 = VolumeName.random("abc-", 20);
|
||||
VolumeName v2 = VolumeName.random("abc-", 20);
|
||||
assertThat(v1.toString()).startsWith("abc-").hasSize(24);
|
||||
assertThat(v2.toString()).startsWith("abc-").hasSize(24);
|
||||
assertThat(v1).isNotEqualTo(v2);
|
||||
assertThat(v1.toString()).isNotEqualTo(v2.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
void basedOnWhenSourceIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> VolumeName.basedOn(null, "prefix", "suffix", 6))
|
||||
.withMessage("Source must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void basedOnWhenNameExtractorIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> VolumeName.basedOn("test", null, "prefix", "suffix", 6))
|
||||
.withMessage("NameExtractor must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void basedOnWhenPrefixIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> VolumeName.basedOn("test", null, "suffix", 6))
|
||||
.withMessage("Prefix must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void basedOnWhenSuffixIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> VolumeName.basedOn("test", "prefix", null, 6))
|
||||
.withMessage("Suffix must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void basedOnGeneratesHashBasedName() {
|
||||
VolumeName name = VolumeName.basedOn("index.docker.io/library/myapp:latest", "pack-cache-", ".build", 6);
|
||||
assertThat(name.toString()).isEqualTo("pack-cache-40a311b545d7.build");
|
||||
}
|
||||
|
||||
@Test
|
||||
void basedOnWhenSizeIsTooBigThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> VolumeName.basedOn("name", "prefix", "suffix", 33))
|
||||
.withMessage("DigestLength must be less than or equal to 32");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenValueIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> VolumeName.of(null))
|
||||
.withMessage("Value must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofGeneratesValue() {
|
||||
VolumeName name = VolumeName.of("test");
|
||||
assertThat(name.toString()).isEqualTo("test");
|
||||
}
|
||||
|
||||
@Test
|
||||
void equalsAndHashCode() {
|
||||
VolumeName n1 = VolumeName.of("test1");
|
||||
VolumeName n2 = VolumeName.of("test1");
|
||||
VolumeName n3 = VolumeName.of("test2");
|
||||
assertThat(n1.hashCode()).isEqualTo(n2.hashCode());
|
||||
assertThat(n1).isEqualTo(n1).isEqualTo(n2).isNotEqualTo(n3);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.io;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link Content}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ContentTests {
|
||||
|
||||
@Test
|
||||
void ofWhenStreamIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> Content.of(1, (IOSupplier<InputStream>) null))
|
||||
.withMessage("Supplier must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenStreamReturnsWritable() throws Exception {
|
||||
byte[] bytes = { 1, 2, 3, 4 };
|
||||
ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
|
||||
Content writable = Content.of(4, () -> inputStream);
|
||||
assertThat(writeToAndGetBytes(writable)).isEqualTo(bytes);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenStringIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> Content.of((String) null))
|
||||
.withMessage("String must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenStringReturnsWritable() throws Exception {
|
||||
Content writable = Content.of("spring");
|
||||
assertThat(writeToAndGetBytes(writable)).isEqualTo("spring".getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenBytesIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> Content.of((byte[]) null))
|
||||
.withMessage("Bytes must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenBytesReturnsWritable() throws Exception {
|
||||
byte[] bytes = { 1, 2, 3, 4 };
|
||||
Content writable = Content.of(bytes);
|
||||
assertThat(writeToAndGetBytes(writable)).isEqualTo(bytes);
|
||||
}
|
||||
|
||||
private byte[] writeToAndGetBytes(Content writable) throws IOException {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
writable.writeTo(outputStream);
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.io;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DefaultOwner}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class DefaultOwnerTests {
|
||||
|
||||
@Test
|
||||
void getUidReturnsUid() {
|
||||
DefaultOwner owner = new DefaultOwner(123, 456);
|
||||
assertThat(owner.getUid()).isEqualTo(123);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getGidReturnsGid() {
|
||||
DefaultOwner owner = new DefaultOwner(123, 456);
|
||||
assertThat(owner.getGid()).isEqualTo(456);
|
||||
}
|
||||
|
||||
@Test
|
||||
void toStringReturnsString() {
|
||||
DefaultOwner owner = new DefaultOwner(123, 456);
|
||||
assertThat(owner).hasToString("123/456");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.io;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link InspectedContent}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class InspectedContentTests {
|
||||
|
||||
@Test
|
||||
void ofWhenInputStreamThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> InspectedContent.of((InputStream) null))
|
||||
.withMessage("InputStream must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenContentIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> InspectedContent.of((Content) null))
|
||||
.withMessage("Content must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWhenConsumerIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> InspectedContent.of((IOConsumer<OutputStream>) null))
|
||||
.withMessage("Writer must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofFromContent() throws Exception {
|
||||
InspectedContent content = InspectedContent.of(Content.of("test"));
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
content.writeTo(outputStream);
|
||||
assertThat(outputStream.toByteArray()).containsExactly("test".getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofSmallContent() throws Exception {
|
||||
InputStream inputStream = new ByteArrayInputStream(new byte[] { 0, 1, 2 });
|
||||
InspectedContent content = InspectedContent.of(inputStream);
|
||||
assertThat(content.size()).isEqualTo(3);
|
||||
assertThat(readBytes(content)).containsExactly(0, 1, 2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofLargeContent() throws Exception {
|
||||
byte[] bytes = new byte[InspectedContent.MEMORY_LIMIT + 3];
|
||||
System.arraycopy(new byte[] { 0, 1, 2 }, 0, bytes, 0, 3);
|
||||
InputStream inputStream = new ByteArrayInputStream(bytes);
|
||||
InspectedContent content = InspectedContent.of(inputStream);
|
||||
assertThat(content.size()).isEqualTo(bytes.length);
|
||||
assertThat(readBytes(content)).isEqualTo(bytes);
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofWithInspector() throws Exception {
|
||||
InputStream inputStream = new ByteArrayInputStream("test".getBytes(StandardCharsets.UTF_8));
|
||||
MessageDigest digest = MessageDigest.getInstance("SHA-256");
|
||||
InspectedContent.of(inputStream, digest::update);
|
||||
assertThat(digest.digest()).inHexadecimal().contains(0x9f, 0x86, 0xd0, 0x81, 0x88, 0x4c, 0x7d, 0x65, 0x9a, 0x2f,
|
||||
0xea, 0xa0, 0xc5, 0x5a, 0xd0, 0x15, 0xa3, 0xbf, 0x4f, 0x1b, 0x2b, 0x0b, 0x82, 0x2c, 0xd1, 0x5d, 0x6c,
|
||||
0x15, 0xb0, 0xf0, 0x0a, 0x08);
|
||||
}
|
||||
|
||||
private byte[] readBytes(InspectedContent content) throws IOException {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
content.writeTo(outputStream);
|
||||
return outputStream.toByteArray();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.io;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link Owner}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class OwnerTests {
|
||||
|
||||
@Test
|
||||
void ofReturnsNewOwner() {
|
||||
Owner owner = Owner.of(123, 456);
|
||||
assertThat(owner.getUid()).isEqualTo(123);
|
||||
assertThat(owner.getGid()).isEqualTo(456);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.io;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link TarArchive}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class TarArchiveTests {
|
||||
|
||||
@TempDir
|
||||
File tempDir;
|
||||
|
||||
@Test
|
||||
void ofWritesTarContent() throws Exception {
|
||||
Owner owner = Owner.of(123, 456);
|
||||
TarArchive tarArchive = TarArchive.of((content) -> {
|
||||
content.folder("/workspace", owner);
|
||||
content.folder("/layers", owner);
|
||||
content.folder("/cnb", Owner.ROOT);
|
||||
content.folder("/cnb/buildpacks", Owner.ROOT);
|
||||
content.folder("/platform", Owner.ROOT);
|
||||
content.folder("/platform/env", Owner.ROOT);
|
||||
});
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
tarArchive.writeTo(outputStream);
|
||||
try (TarArchiveInputStream tarStream = new TarArchiveInputStream(
|
||||
new ByteArrayInputStream(outputStream.toByteArray()))) {
|
||||
List<TarArchiveEntry> entries = new ArrayList<>();
|
||||
TarArchiveEntry entry = tarStream.getNextTarEntry();
|
||||
while (entry != null) {
|
||||
entries.add(entry);
|
||||
entry = tarStream.getNextTarEntry();
|
||||
}
|
||||
assertThat(entries).hasSize(6);
|
||||
assertThat(entries.get(0).getName()).isEqualTo("/workspace/");
|
||||
assertThat(entries.get(0).getLongUserId()).isEqualTo(123);
|
||||
assertThat(entries.get(0).getLongGroupId()).isEqualTo(456);
|
||||
assertThat(entries.get(2).getName()).isEqualTo("/cnb/");
|
||||
assertThat(entries.get(2).getLongUserId()).isEqualTo(0);
|
||||
assertThat(entries.get(2).getLongGroupId()).isEqualTo(0);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void fromZipFileReturnsZipFileAdapter() throws Exception {
|
||||
Owner owner = Owner.of(123, 456);
|
||||
File file = new File(this.tempDir, "test.zip");
|
||||
writeTestZip(file);
|
||||
TarArchive tarArchive = TarArchive.fromZip(file, owner);
|
||||
assertThat(tarArchive).isInstanceOf(ZipFileTarArchive.class);
|
||||
}
|
||||
|
||||
private void writeTestZip(File file) throws IOException {
|
||||
try (ZipArchiveOutputStream zip = new ZipArchiveOutputStream(file)) {
|
||||
ZipArchiveEntry dirEntry = new ZipArchiveEntry("spring/");
|
||||
zip.putArchiveEntry(dirEntry);
|
||||
zip.closeArchiveEntry();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.io;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Date;
|
||||
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link TarLayoutWriter}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class TarLayoutWriterTests {
|
||||
|
||||
@Test
|
||||
void writesTarArchive() throws Exception {
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
try (TarLayoutWriter writer = new TarLayoutWriter(outputStream)) {
|
||||
writer.folder("/foo", Owner.ROOT);
|
||||
writer.file("/foo/bar.txt", Owner.of(1, 1), Content.of("test"));
|
||||
}
|
||||
try (TarArchiveInputStream tarInputStream = new TarArchiveInputStream(
|
||||
new ByteArrayInputStream(outputStream.toByteArray()))) {
|
||||
TarArchiveEntry folderEntry = tarInputStream.getNextTarEntry();
|
||||
TarArchiveEntry fileEntry = tarInputStream.getNextTarEntry();
|
||||
byte[] fileContent = new byte[(int) fileEntry.getSize()];
|
||||
tarInputStream.read(fileContent);
|
||||
assertThat(tarInputStream.getNextEntry()).isNull();
|
||||
assertThat(folderEntry.getName()).isEqualTo("/foo/");
|
||||
assertThat(folderEntry.getMode()).isEqualTo(0755);
|
||||
assertThat(folderEntry.getLongUserId()).isEqualTo(0);
|
||||
assertThat(folderEntry.getLongGroupId()).isEqualTo(0);
|
||||
assertThat(folderEntry.getModTime()).isEqualTo(new Date(TarLayoutWriter.NORMALIZED_MOD_TIME));
|
||||
assertThat(fileEntry.getName()).isEqualTo("/foo/bar.txt");
|
||||
assertThat(fileEntry.getMode()).isEqualTo(0644);
|
||||
assertThat(fileEntry.getLongUserId()).isEqualTo(1);
|
||||
assertThat(fileEntry.getLongGroupId()).isEqualTo(1);
|
||||
assertThat(fileEntry.getModTime()).isEqualTo(new Date(TarLayoutWriter.NORMALIZED_MOD_TIME));
|
||||
assertThat(fileContent).isEqualTo("test".getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,97 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.io;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
|
||||
import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import org.springframework.util.StreamUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
/**
|
||||
* Tests for {@link ZipFileTarArchive}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class ZipFileTarArchiveTests {
|
||||
|
||||
@TempDir
|
||||
File tempDir;
|
||||
|
||||
@Test
|
||||
void createWhenZipIsNullThrowsException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ZipFileTarArchive(null, Owner.ROOT))
|
||||
.withMessage("Zip must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWhenOwnerIsNullThrowsException() throws Exception {
|
||||
File file = new File(this.tempDir, "test.zip");
|
||||
writeTestZip(file);
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ZipFileTarArchive(file, null))
|
||||
.withMessage("Owner must not be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
void writeToAdaptsContent() throws Exception {
|
||||
Owner owner = Owner.of(123, 456);
|
||||
File file = new File(this.tempDir, "test.zip");
|
||||
writeTestZip(file);
|
||||
TarArchive tarArchive = TarArchive.fromZip(file, owner);
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
tarArchive.writeTo(outputStream);
|
||||
try (TarArchiveInputStream tarStream = new TarArchiveInputStream(
|
||||
new ByteArrayInputStream(outputStream.toByteArray()))) {
|
||||
TarArchiveEntry dirEntry = tarStream.getNextTarEntry();
|
||||
assertThat(dirEntry.getName()).isEqualTo("spring/");
|
||||
assertThat(dirEntry.getLongUserId()).isEqualTo(123);
|
||||
assertThat(dirEntry.getLongGroupId()).isEqualTo(456);
|
||||
TarArchiveEntry fileEntry = tarStream.getNextTarEntry();
|
||||
assertThat(fileEntry.getName()).isEqualTo("spring/boot");
|
||||
assertThat(fileEntry.getLongUserId()).isEqualTo(123);
|
||||
assertThat(fileEntry.getLongGroupId()).isEqualTo(456);
|
||||
assertThat(fileEntry.getSize()).isEqualTo(4);
|
||||
String fileContent = StreamUtils.copyToString(tarStream, StandardCharsets.UTF_8);
|
||||
assertThat(fileContent).isEqualTo("test");
|
||||
}
|
||||
}
|
||||
|
||||
private void writeTestZip(File file) throws IOException {
|
||||
try (ZipArchiveOutputStream zip = new ZipArchiveOutputStream(file)) {
|
||||
ZipArchiveEntry dirEntry = new ZipArchiveEntry("spring/");
|
||||
zip.putArchiveEntry(dirEntry);
|
||||
zip.closeArchiveEntry();
|
||||
ZipArchiveEntry fileEntry = new ZipArchiveEntry("spring/boot");
|
||||
zip.putArchiveEntry(fileEntry);
|
||||
zip.write("test".getBytes(StandardCharsets.UTF_8));
|
||||
zip.closeArchiveEntry();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.json;
|
||||
|
||||
import java.io.InputStream;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Abstract base class for JSON based tests.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
public abstract class AbstractJsonTests {
|
||||
|
||||
protected final ObjectMapper getObjectMapper() {
|
||||
return SharedObjectMapper.get();
|
||||
}
|
||||
|
||||
protected final InputStream getContent(String name) {
|
||||
InputStream result = getClass().getResourceAsStream(name);
|
||||
assertThat(result).as("JSON source " + name).isNotNull();
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.json;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonCreator;
|
||||
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link JsonStream}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class JsonStreamTests extends AbstractJsonTests {
|
||||
|
||||
private JsonStream jsonStream;
|
||||
|
||||
JsonStreamTests() {
|
||||
this.jsonStream = new JsonStream(getObjectMapper());
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenReadingObjectNodeReturnsNodes() throws Exception {
|
||||
List<ObjectNode> result = new ArrayList<>();
|
||||
this.jsonStream.get(getContent("stream.json"), result::add);
|
||||
assertThat(result).hasSize(595);
|
||||
assertThat(result.get(594).toString()).contains("Status: Downloaded newer image for cloudfoundry/cnb:bionic");
|
||||
}
|
||||
|
||||
@Test
|
||||
void getWhenReadTypesReturnsTypes() throws Exception {
|
||||
List<TestEvent> result = new ArrayList<>();
|
||||
this.jsonStream.get(getContent("stream.json"), TestEvent.class, result::add);
|
||||
assertThat(result).hasSize(595);
|
||||
assertThat(result.get(1).getId()).isEqualTo("5667fdb72017");
|
||||
assertThat(result.get(594).getStatus()).isEqualTo("Status: Downloaded newer image for cloudfoundry/cnb:bionic");
|
||||
}
|
||||
|
||||
/**
|
||||
* Event for type deserialization tests.
|
||||
*/
|
||||
static class TestEvent {
|
||||
|
||||
private final String id;
|
||||
|
||||
private final String status;
|
||||
|
||||
@JsonCreator
|
||||
TestEvent(String id, String status) {
|
||||
this.id = id;
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
String getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
String getStatus() {
|
||||
return this.status;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.json;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
|
||||
import com.fasterxml.jackson.databind.JsonNode;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.json.MappedObjectTests.TestMappedObject.Person;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link MappedObject}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MappedObjectTests extends AbstractJsonTests {
|
||||
|
||||
private final TestMappedObject mapped;
|
||||
|
||||
MappedObjectTests() throws IOException {
|
||||
this.mapped = TestMappedObject.of(getContent("test-mapped-object.json"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void ofReadsJson() throws Exception {
|
||||
assertThat(this.mapped.getNode()).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void valueAtWhenStringReturnsValue() {
|
||||
assertThat(this.mapped.valueAt("/string", String.class)).isEqualTo("stringvalue");
|
||||
}
|
||||
|
||||
@Test
|
||||
void valueAtWhenStringArrayReturnsValue() {
|
||||
assertThat(this.mapped.valueAt("/stringarray", String[].class)).containsExactly("a", "b");
|
||||
}
|
||||
|
||||
@Test
|
||||
void valueAtWhenMissingReturnsNull() {
|
||||
assertThat(this.mapped.valueAt("/missing", String.class)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void valueAtWhenInterfaceReturnsProxy() {
|
||||
Person person = this.mapped.valueAt("/person", Person.class);
|
||||
assertThat(person.getName().getFirst()).isEqualTo("spring");
|
||||
assertThat(person.getName().getLast()).isEqualTo("boot");
|
||||
}
|
||||
|
||||
@Test
|
||||
void valueAtWhenInterfaceAndMissingReturnsProxy() {
|
||||
Person person = this.mapped.valueAt("/missing", Person.class);
|
||||
assertThat(person.getName().getFirst()).isNull();
|
||||
assertThat(person.getName().getLast()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
void valueAtWhenActualPropertyStartsWithUppercaseReturnsValue() {
|
||||
assertThat(this.mapped.valueAt("/startsWithUppercase", String.class)).isEqualTo("value");
|
||||
}
|
||||
|
||||
@Test
|
||||
void valueAtWhenDefaultMethodReturnsValue() {
|
||||
Person person = this.mapped.valueAt("/person", Person.class);
|
||||
assertThat(person.getName().getFullName()).isEqualTo("dr spring boot");
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link MappedObject} for testing.
|
||||
*/
|
||||
static class TestMappedObject extends MappedObject {
|
||||
|
||||
TestMappedObject(JsonNode node) {
|
||||
super(node, MethodHandles.lookup());
|
||||
}
|
||||
|
||||
static TestMappedObject of(InputStream content) throws IOException {
|
||||
return of(content, TestMappedObject::new);
|
||||
}
|
||||
|
||||
interface Person {
|
||||
|
||||
Name getName();
|
||||
|
||||
interface Name {
|
||||
|
||||
String getFirst();
|
||||
|
||||
String getLast();
|
||||
|
||||
default String getFullName() {
|
||||
String title = valueAt(this, "/title", String.class);
|
||||
return title + " " + getFirst() + " " + getLast();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.json;
|
||||
|
||||
import com.fasterxml.jackson.databind.DeserializationFeature;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
|
||||
import com.fasterxml.jackson.databind.SerializationFeature;
|
||||
import com.fasterxml.jackson.module.paramnames.ParameterNamesModule;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link SharedObjectMapper}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class SharedObjectMapperTests {
|
||||
|
||||
@Test
|
||||
void getReturnsConfiguredObjectMapper() {
|
||||
ObjectMapper mapper = SharedObjectMapper.get();
|
||||
assertThat(mapper).isNotNull();
|
||||
assertThat(mapper.getRegisteredModuleIds()).contains(new ParameterNamesModule().getTypeId());
|
||||
assertThat(SerializationFeature.INDENT_OUTPUT
|
||||
.enabledIn(mapper.getSerializationConfig().getSerializationFeatures())).isTrue();
|
||||
assertThat(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES
|
||||
.enabledIn(mapper.getDeserializationConfig().getDeserializationFeatures())).isFalse();
|
||||
assertThat(mapper.getSerializationConfig().getPropertyNamingStrategy())
|
||||
.isEqualTo(PropertyNamingStrategy.LOWER_CAMEL_CASE);
|
||||
assertThat(mapper.getDeserializationConfig().getPropertyNamingStrategy())
|
||||
.isEqualTo(PropertyNamingStrategy.LOWER_CAMEL_CASE);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.socket;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.boot.buildpack.platform.socket.FileDescriptor.Handle;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Test for {@link FileDescriptor}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class FileDescriptorTests {
|
||||
|
||||
private int sourceHandle = 123;
|
||||
|
||||
private int closedHandle = 0;
|
||||
|
||||
@Test
|
||||
void acquireReturnsHandle() throws Exception {
|
||||
FileDescriptor descriptor = new FileDescriptor(this.sourceHandle, this::close);
|
||||
try (Handle handle = descriptor.acquire()) {
|
||||
assertThat(handle.intValue()).isEqualTo(this.sourceHandle);
|
||||
assertThat(handle.isClosed()).isFalse();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void acquireWhenClosedReturnsClosedHandle() throws Exception {
|
||||
FileDescriptor descriptor = new FileDescriptor(this.sourceHandle, this::close);
|
||||
descriptor.close();
|
||||
try (Handle handle = descriptor.acquire()) {
|
||||
assertThat(handle.intValue()).isEqualTo(-1);
|
||||
assertThat(handle.isClosed()).isTrue();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void acquireWhenPendingCloseReturnsClosedHandle() throws Exception {
|
||||
FileDescriptor descriptor = new FileDescriptor(this.sourceHandle, this::close);
|
||||
try (Handle handle1 = descriptor.acquire()) {
|
||||
descriptor.close();
|
||||
try (Handle handle2 = descriptor.acquire()) {
|
||||
assertThat(handle2.intValue()).isEqualTo(-1);
|
||||
assertThat(handle2.isClosed()).isTrue();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void finalizeTriggersClose() {
|
||||
FileDescriptor descriptor = new FileDescriptor(this.sourceHandle, this::close);
|
||||
descriptor.close();
|
||||
assertThat(this.closedHandle).isEqualTo(this.sourceHandle);
|
||||
}
|
||||
|
||||
@Test
|
||||
void closeWhenHandleAcquiredClosesOnRelease() throws Exception {
|
||||
FileDescriptor descriptor = new FileDescriptor(this.sourceHandle, this::close);
|
||||
try (Handle handle = descriptor.acquire()) {
|
||||
descriptor.close();
|
||||
assertThat(this.closedHandle).isEqualTo(0);
|
||||
}
|
||||
assertThat(this.closedHandle).isEqualTo(this.sourceHandle);
|
||||
}
|
||||
|
||||
@Test
|
||||
void closeWhenHandleNotAcquiredClosesImmediately() {
|
||||
FileDescriptor descriptor = new FileDescriptor(this.sourceHandle, this::close);
|
||||
descriptor.close();
|
||||
assertThat(this.closedHandle).isEqualTo(this.sourceHandle);
|
||||
}
|
||||
|
||||
private void close(int handle) {
|
||||
this.closedHandle = handle;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2012-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.boot.buildpack.platform.toml;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link Toml}.
|
||||
*
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class TomlTests {
|
||||
|
||||
@Test
|
||||
void createsTomlMarkup() {
|
||||
Toml toml = new Toml();
|
||||
toml.table("run-image");
|
||||
toml.string("image", "cnb/test");
|
||||
toml.array("mirrors", "a", "b", "c");
|
||||
String expected = "";
|
||||
expected += "[run-image]\n";
|
||||
expected += "image = \"cnb/test\"\n";
|
||||
expected += "mirrors = [\"a\", \"b\", \"c\"]\n";
|
||||
assertThat(toml.toString()).isEqualTo(expected);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
{
|
||||
"description": "Ubuntu bionic base image with buildpacks for Java, NodeJS and Golang",
|
||||
"buildpacks": [
|
||||
{
|
||||
"id": "org.cloudfoundry.debug",
|
||||
"version": "v1.0.106",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.go",
|
||||
"version": "v0.0.2",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.springautoreconfiguration",
|
||||
"version": "v1.0.113",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.buildsystem",
|
||||
"version": "v1.0.133",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.procfile",
|
||||
"version": "v1.0.41",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.nodejs",
|
||||
"version": "v0.0.5",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.distzip",
|
||||
"version": "v1.0.101",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.jdbc",
|
||||
"version": "v1.0.107",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.azureapplicationinsights",
|
||||
"version": "v1.0.105",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.springboot",
|
||||
"version": "v1.0.112",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.openjdk",
|
||||
"version": "v1.0.58",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.tomcat",
|
||||
"version": "v1.1.24",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.googlestackdriver",
|
||||
"version": "v1.0.54",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.jmx",
|
||||
"version": "v1.0.107",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.archiveexpanding",
|
||||
"version": "v1.0.99",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.jvmapplication",
|
||||
"version": "v1.0.82",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.dep",
|
||||
"version": "0.0.64",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.go-compiler",
|
||||
"version": "0.0.55",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.go-mod",
|
||||
"version": "0.0.58",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.node-engine",
|
||||
"version": "0.0.102",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.npm",
|
||||
"version": "0.0.63",
|
||||
"latest": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.yarn",
|
||||
"version": "0.0.69",
|
||||
"latest": true
|
||||
}
|
||||
],
|
||||
"groups": [
|
||||
{
|
||||
"buildpacks": [
|
||||
{
|
||||
"id": "org.cloudfoundry.archiveexpanding",
|
||||
"version": "v1.0.99",
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.openjdk",
|
||||
"version": "v1.0.58"
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.buildsystem",
|
||||
"version": "v1.0.133",
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.jvmapplication",
|
||||
"version": "v1.0.82"
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.tomcat",
|
||||
"version": "v1.1.24",
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.springboot",
|
||||
"version": "v1.0.112",
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.distzip",
|
||||
"version": "v1.0.101",
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.procfile",
|
||||
"version": "v1.0.41",
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.azureapplicationinsights",
|
||||
"version": "v1.0.105",
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.debug",
|
||||
"version": "v1.0.106",
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.googlestackdriver",
|
||||
"version": "v1.0.54",
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.jdbc",
|
||||
"version": "v1.0.107",
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.jmx",
|
||||
"version": "v1.0.107",
|
||||
"optional": true
|
||||
},
|
||||
{
|
||||
"id": "org.cloudfoundry.springautoreconfiguration",
|
||||
"version": "v1.0.113",
|
||||
"optional": true
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"buildpacks": [
|
||||
{
|
||||
"id": "org.cloudfoundry.nodejs",
|
||||
"version": "v0.0.5"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"buildpacks": [
|
||||
{
|
||||
"id": "org.cloudfoundry.go",
|
||||
"version": "v0.0.2"
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"stack": {
|
||||
"runImage": {
|
||||
"image": "cloudfoundry/run:base-cnb",
|
||||
"mirrors": null
|
||||
}
|
||||
},
|
||||
"lifecycle": {
|
||||
"version": "0.5.0",
|
||||
"api": {
|
||||
"buildpack": "0.2",
|
||||
"platform": "0.1"
|
||||
}
|
||||
},
|
||||
"createdBy": {
|
||||
"name": "Pack CLI",
|
||||
"version": "dev-2019-11-19-22:34:59"
|
||||
}
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"User" : "root",
|
||||
"Image" : "pack.local/ephemeral-builder",
|
||||
"Cmd" : [ "/lifecycle/analyzer", "-daemon", "-layers", "/layers", "docker.io/library/my-application:latest" ],
|
||||
"Labels" : {
|
||||
"author" : "spring-boot"
|
||||
},
|
||||
"HostConfig" : {
|
||||
"Binds" : [ "/var/run/docker.sock:/var/run/docker.sock", "pack-layers-aaaaaaaaaa:/layers", "pack-app-aaaaaaaaaa:/workspace" ]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"Image" : "pack.local/ephemeral-builder",
|
||||
"Cmd" : [ "/lifecycle/builder", "-layers", "/layers", "-app", "/workspace", "-platform", "/platform" ],
|
||||
"Labels" : {
|
||||
"author" : "spring-boot"
|
||||
},
|
||||
"HostConfig" : {
|
||||
"Binds" : [ "pack-layers-aaaaaaaaaa:/layers", "pack-app-aaaaaaaaaa:/workspace" ]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"User" : "root",
|
||||
"Image" : "pack.local/ephemeral-builder",
|
||||
"Cmd" : [ "/lifecycle/cacher", "-path", "/cache", "-layers", "/layers" ],
|
||||
"Labels" : {
|
||||
"author" : "spring-boot"
|
||||
},
|
||||
"HostConfig" : {
|
||||
"Binds" : [ "/var/run/docker.sock:/var/run/docker.sock", "pack-layers-aaaaaaaaaa:/layers", "pack-app-aaaaaaaaaa:/workspace", "pack-cache-b35197ac41ea.build:/cache" ]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"Image" : "pack.local/ephemeral-builder",
|
||||
"Cmd" : [ "/lifecycle/detector", "-app", "/workspace", "-platform", "/platform" ],
|
||||
"Labels" : {
|
||||
"author" : "spring-boot"
|
||||
},
|
||||
"HostConfig" : {
|
||||
"Binds" : [ "pack-layers-aaaaaaaaaa:/layers", "pack-app-aaaaaaaaaa:/workspace" ]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"User" : "root",
|
||||
"Image" : "pack.local/ephemeral-builder",
|
||||
"Cmd" : [ "/lifecycle/exporter", "-image", "docker.io/cloudfoundry/run", "-layers", "/layers", "-app", "/workspace", "-daemon", "-launch-cache", "/launch-cache", "docker.io/library/my-application:latest" ],
|
||||
"Labels" : {
|
||||
"author" : "spring-boot"
|
||||
},
|
||||
"HostConfig" : {
|
||||
"Binds" : [ "/var/run/docker.sock:/var/run/docker.sock", "pack-layers-aaaaaaaaaa:/layers", "pack-app-aaaaaaaaaa:/workspace", "pack-cache-b35197ac41ea.launch:/launch-cache" ]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"User" : "root",
|
||||
"Image" : "pack.local/ephemeral-builder",
|
||||
"Cmd" : [ "/lifecycle/restorer", "-path", "/cache", "-layers", "/layers" ],
|
||||
"Labels" : {
|
||||
"author" : "spring-boot"
|
||||
},
|
||||
"HostConfig" : {
|
||||
"Binds" : [ "/var/run/docker.sock:/var/run/docker.sock", "pack-layers-aaaaaaaaaa:/layers", "pack-app-aaaaaaaaaa:/workspace", "pack-cache-b35197ac41ea.build:/cache" ]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
Building image 'docker.io/library/my-app:latest'
|
||||
|
||||
> Pulling builder image 'docker.io/cnb/builder' ..................................................
|
||||
> Pulled builder image '00000001'
|
||||
> Pulling run image 'docker.io/cnb/runner' ..................................................
|
||||
> Pulled run image '00000002'
|
||||
> Executing lifecycle version v0.5.0
|
||||
> Using build cache volume 'pack-abc.cache'
|
||||
|
||||
> Running alphabet
|
||||
[alphabet] one
|
||||
[alphabet] two
|
||||
[alphabet] three
|
||||
|
||||
> Running basket
|
||||
[basket] spring
|
||||
[basket] boot
|
||||
|
||||
Successfully built image 'docker.io/library/my-app:latest'
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"Id": "e90e34656806",
|
||||
"Warnings": []
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"errors": [
|
||||
{
|
||||
"code": "TEST1",
|
||||
"message": "Test One",
|
||||
"detail": 123
|
||||
},
|
||||
{
|
||||
"code": "TEST2",
|
||||
"message": "Test Two",
|
||||
"detail": "fail"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"stream":"Loaded image: pack.local/builder/auqfjjbaod:latest\n"}
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,598 @@
|
||||
{
|
||||
"status": "Pulling from cloudfoundry/cnb",
|
||||
"id": "bionic"
|
||||
}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"5667fdb72017"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"d83811f270d5"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"ee671aafb583"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"7fc152dfb3a6"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"4ab897fa6fbf"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"d837a2a1365e"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"988ae18fe41a"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"eeb8ef83b565"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"357fefdf9bc9"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"45b746196f82"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"fbf4ce20f8c2"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"90aca3c647fe"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"1dd62f37c84c"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"3192b2fa42db"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"ae190b8f66a7"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"97bb6e138460"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"eeb8ef83b565"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"2edb982d5170"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"357fefdf9bc9"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"7ddc8e6d6da9"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"0df6fd234b59"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"45b746196f82"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"8fc1ba8efe21"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"1f6f45e783b5"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"43ea61082f68"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"7fc152dfb3a6"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"b8cf53bbc6ba"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"fbf4ce20f8c2"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"25efb07e4521"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"90aca3c647fe"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"1c3245356213"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"1dd62f37c84c"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"61ebb123c1eb"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"0964b769d2c9"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"3192b2fa42db"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"87f7843f43cd"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"a89dbf94d794"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"ae190b8f66a7"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"f0d43ddca77f"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"7c674f0cb40c"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"97bb6e138460"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"b48a885b52bc"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"272cdf839cbb"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"50d054c97f4f"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"4c6bbd90b64d"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"2edb982d5170"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"4f4fb700ef54"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"7ddc8e6d6da9"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"b8cf53bbc6ba"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"25efb07e4521"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"0df6fd234b59"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"1c3245356213"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"61ebb123c1eb"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"8fc1ba8efe21"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"0964b769d2c9"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"87f7843f43cd"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"1f6f45e783b5"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"a89dbf94d794"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"43ea61082f68"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"f0d43ddca77f"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"7c674f0cb40c"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"b48a885b52bc"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"272cdf839cbb"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"50d054c97f4f"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"4c6bbd90b64d"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"4f4fb700ef54"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"4ab897fa6fbf"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"d837a2a1365e"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"988ae18fe41a"}
|
||||
{"status":"Downloading","progressDetail":{"current":487,"total":850},"progress":"[============================\u003e ] 487B/850B","id":"ee671aafb583"}
|
||||
{"status":"Downloading","progressDetail":{"current":485,"total":35355},"progress":"[\u003e ] 485B/35.35kB","id":"d83811f270d5"}
|
||||
{"status":"Downloading","progressDetail":{"current":35355,"total":35355},"progress":"[==================================================\u003e] 35.35kB/35.35kB","id":"d83811f270d5"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"d83811f270d5"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"d83811f270d5"}
|
||||
{"status":"Downloading","progressDetail":{"current":277600,"total":26683298},"progress":"[\u003e ] 277.6kB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":850,"total":850},"progress":"[==================================================\u003e] 850B/850B","id":"ee671aafb583"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"ee671aafb583"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"ee671aafb583"}
|
||||
{"status":"Downloading","progressDetail":{"current":2218692,"total":26683298},"progress":"[====\u003e ] 2.219MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":4160196,"total":26683298},"progress":"[=======\u003e ] 4.16MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":6109892,"total":26683298},"progress":"[===========\u003e ] 6.11MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":7772868,"total":26683298},"progress":"[==============\u003e ] 7.773MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":9444036,"total":26683298},"progress":"[=================\u003e ] 9.444MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":163,"total":163},"progress":"[==================================================\u003e] 163B/163B","id":"7fc152dfb3a6"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"7fc152dfb3a6"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"7fc152dfb3a6"}
|
||||
{"status":"Downloading","progressDetail":{"current":10832580,"total":26683298},"progress":"[====================\u003e ] 10.83MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":531179,"total":88111129},"progress":"[\u003e ] 531.2kB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":11668164,"total":26683298},"progress":"[=====================\u003e ] 11.67MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":1604331,"total":88111129},"progress":"[\u003e ] 1.604MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":12495556,"total":26683298},"progress":"[=======================\u003e ] 12.5MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":3209963,"total":88111129},"progress":"[=\u003e ] 3.21MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":13331140,"total":26683298},"progress":"[========================\u003e ] 13.33MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":4283115,"total":88111129},"progress":"[==\u003e ] 4.283MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":14166724,"total":26683298},"progress":"[==========================\u003e ] 14.17MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":5888747,"total":88111129},"progress":"[===\u003e ] 5.889MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":15280836,"total":26683298},"progress":"[============================\u003e ] 15.28MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":14318,"total":1391657},"progress":"[\u003e ] 14.32kB/1.392MB","id":"d837a2a1365e"}
|
||||
{"status":"Downloading","progressDetail":{"current":6961899,"total":88111129},"progress":"[===\u003e ] 6.962MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":16116420,"total":26683298},"progress":"[==============================\u003e ] 16.12MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":936688,"total":1391657},"progress":"[=================================\u003e ] 936.7kB/1.392MB","id":"d837a2a1365e"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"d837a2a1365e"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"d837a2a1365e"}
|
||||
{"status":"Downloading","progressDetail":{"current":8022763,"total":88111129},"progress":"[====\u003e ] 8.023MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":16931524,"total":26683298},"progress":"[===============================\u003e ] 16.93MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":18045636,"total":26683298},"progress":"[=================================\u003e ] 18.05MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":9632491,"total":88111129},"progress":"[=====\u003e ] 9.632MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":10709739,"total":88111129},"progress":"[======\u003e ] 10.71MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":19143364,"total":26683298},"progress":"[===================================\u003e ] 19.14MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":11778795,"total":88111129},"progress":"[======\u003e ] 11.78MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":20249284,"total":26683298},"progress":"[=====================================\u003e ] 20.25MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":12851947,"total":88111129},"progress":"[=======\u003e ] 12.85MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":21072580,"total":26683298},"progress":"[=======================================\u003e ] 21.07MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":14133,"total":1328346},"progress":"[\u003e ] 14.13kB/1.328MB","id":"988ae18fe41a"}
|
||||
{"status":"Downloading","progressDetail":{"current":13933291,"total":88111129},"progress":"[=======\u003e ] 13.93MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":21908164,"total":26683298},"progress":"[=========================================\u003e ] 21.91MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":973511,"total":1328346},"progress":"[====================================\u003e ] 973.5kB/1.328MB","id":"988ae18fe41a"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"988ae18fe41a"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"988ae18fe41a"}
|
||||
{"status":"Downloading","progressDetail":{"current":15014635,"total":88111129},"progress":"[========\u003e ] 15.01MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":22747844,"total":26683298},"progress":"[==========================================\u003e ] 22.75MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":16075499,"total":88111129},"progress":"[=========\u003e ] 16.08MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":23575236,"total":26683298},"progress":"[============================================\u003e ] 23.58MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":24414916,"total":26683298},"progress":"[=============================================\u003e ] 24.41MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":17132267,"total":88111129},"progress":"[=========\u003e ] 17.13MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":25250500,"total":26683298},"progress":"[===============================================\u003e ] 25.25MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":18213611,"total":88111129},"progress":"[==========\u003e ] 18.21MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":26073796,"total":26683298},"progress":"[================================================\u003e ] 26.07MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":19286763,"total":88111129},"progress":"[==========\u003e ] 19.29MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":490,"total":4478},"progress":"[=====\u003e ] 490B/4.478kB","id":"eeb8ef83b565"}
|
||||
{"status":"Downloading","progressDetail":{"current":4478,"total":4478},"progress":"[==================================================\u003e] 4.478kB/4.478kB","id":"eeb8ef83b565"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"eeb8ef83b565"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"eeb8ef83b565"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"5667fdb72017"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":20892395,"total":88111129},"progress":"[===========\u003e ] 20.89MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":294912,"total":26683298},"progress":"[\u003e ] 294.9kB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":23050987,"total":88111129},"progress":"[=============\u003e ] 23.05MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":2654208,"total":26683298},"progress":"[====\u003e ] 2.654MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":25205483,"total":88111129},"progress":"[==============\u003e ] 25.21MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":6193152,"total":26683298},"progress":"[===========\u003e ] 6.193MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":27355883,"total":88111129},"progress":"[===============\u003e ] 27.36MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":8552448,"total":26683298},"progress":"[================\u003e ] 8.552MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":197,"total":197},"progress":"[==================================================\u003e] 197B/197B","id":"357fefdf9bc9"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"357fefdf9bc9"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"357fefdf9bc9"}
|
||||
{"status":"Extracting","progressDetail":{"current":11796480,"total":26683298},"progress":"[======================\u003e ] 11.8MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":29510379,"total":88111129},"progress":"[================\u003e ] 29.51MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":277600,"total":27504647},"progress":"[\u003e ] 277.6kB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":15040512,"total":26683298},"progress":"[============================\u003e ] 15.04MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":1391300,"total":27504647},"progress":"[==\u003e ] 1.391MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":31132395,"total":88111129},"progress":"[=================\u003e ] 31.13MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":17989632,"total":26683298},"progress":"[=================================\u003e ] 17.99MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":32754411,"total":88111129},"progress":"[==================\u003e ] 32.75MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2230980,"total":27504647},"progress":"[====\u003e ] 2.231MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":22118400,"total":26683298},"progress":"[=========================================\u003e ] 22.12MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":33835755,"total":88111129},"progress":"[===================\u003e ] 33.84MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3078852,"total":27504647},"progress":"[=====\u003e ] 3.079MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":24477696,"total":26683298},"progress":"[=============================================\u003e ] 24.48MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":52419,"total":5205016},"progress":"[\u003e ] 52.42kB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Downloading","progressDetail":{"current":34917099,"total":88111129},"progress":"[===================\u003e ] 34.92MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3922628,"total":27504647},"progress":"[=======\u003e ] 3.923MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":912096,"total":5205016},"progress":"[========\u003e ] 912.1kB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Extracting","progressDetail":{"current":26247168,"total":26683298},"progress":"[=================================================\u003e ] 26.25MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":4487876,"total":27504647},"progress":"[========\u003e ] 4.488MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":35986155,"total":88111129},"progress":"[====================\u003e ] 35.99MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":26683298,"total":26683298},"progress":"[==================================================\u003e] 26.68MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":1805024,"total":5205016},"progress":"[=================\u003e ] 1.805MB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Downloading","progressDetail":{"current":5044932,"total":27504647},"progress":"[=========\u003e ] 5.045MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":36522731,"total":88111129},"progress":"[====================\u003e ] 36.52MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2550496,"total":5205016},"progress":"[========================\u003e ] 2.55MB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Downloading","progressDetail":{"current":5601988,"total":27504647},"progress":"[==========\u003e ] 5.602MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":3381984,"total":5205016},"progress":"[================================\u003e ] 3.382MB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Downloading","progressDetail":{"current":37063403,"total":88111129},"progress":"[=====================\u003e ] 37.06MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":6159044,"total":27504647},"progress":"[===========\u003e ] 6.159MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":4152032,"total":5205016},"progress":"[=======================================\u003e ] 4.152MB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Downloading","progressDetail":{"current":37604075,"total":88111129},"progress":"[=====================\u003e ] 37.6MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"5667fdb72017"}
|
||||
{"status":"Extracting","progressDetail":{"current":32768,"total":35355},"progress":"[==============================================\u003e ] 32.77kB/35.35kB","id":"d83811f270d5"}
|
||||
{"status":"Extracting","progressDetail":{"current":35355,"total":35355},"progress":"[==================================================\u003e] 35.35kB/35.35kB","id":"d83811f270d5"}
|
||||
{"status":"Downloading","progressDetail":{"current":5004000,"total":5205016},"progress":"[================================================\u003e ] 5.004MB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Downloading","progressDetail":{"current":6716100,"total":27504647},"progress":"[============\u003e ] 6.716MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"fbf4ce20f8c2"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"fbf4ce20f8c2"}
|
||||
{"status":"Downloading","progressDetail":{"current":38144747,"total":88111129},"progress":"[=====================\u003e ] 38.14MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"d83811f270d5"}
|
||||
{"status":"Extracting","progressDetail":{"current":850,"total":850},"progress":"[==================================================\u003e] 850B/850B","id":"ee671aafb583"}
|
||||
{"status":"Extracting","progressDetail":{"current":850,"total":850},"progress":"[==================================================\u003e] 850B/850B","id":"ee671aafb583"}
|
||||
{"status":"Downloading","progressDetail":{"current":7293636,"total":27504647},"progress":"[=============\u003e ] 7.294MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":39213803,"total":88111129},"progress":"[======================\u003e ] 39.21MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":8129220,"total":27504647},"progress":"[==============\u003e ] 8.129MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"ee671aafb583"}
|
||||
{"status":"Extracting","progressDetail":{"current":163,"total":163},"progress":"[==================================================\u003e] 163B/163B","id":"7fc152dfb3a6"}
|
||||
{"status":"Extracting","progressDetail":{"current":163,"total":163},"progress":"[==================================================\u003e] 163B/163B","id":"7fc152dfb3a6"}
|
||||
{"status":"Downloading","progressDetail":{"current":40295147,"total":88111129},"progress":"[======================\u003e ] 40.3MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":8964804,"total":27504647},"progress":"[================\u003e ] 8.965MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"7fc152dfb3a6"}
|
||||
{"status":"Downloading","progressDetail":{"current":9800388,"total":27504647},"progress":"[=================\u003e ] 9.8MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":41368299,"total":88111129},"progress":"[=======================\u003e ] 41.37MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":49680,"total":4964709},"progress":"[\u003e ] 49.68kB/4.965MB","id":"90aca3c647fe"}
|
||||
{"status":"Downloading","progressDetail":{"current":10635972,"total":27504647},"progress":"[===================\u003e ] 10.64MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":908013,"total":4964709},"progress":"[=========\u003e ] 908kB/4.965MB","id":"90aca3c647fe"}
|
||||
{"status":"Downloading","progressDetail":{"current":41908971,"total":88111129},"progress":"[=======================\u003e ] 41.91MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":11193028,"total":27504647},"progress":"[====================\u003e ] 11.19MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":2038509,"total":4964709},"progress":"[====================\u003e ] 2.039MB/4.965MB","id":"90aca3c647fe"}
|
||||
{"status":"Downloading","progressDetail":{"current":42449643,"total":88111129},"progress":"[========================\u003e ] 42.45MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":11750084,"total":27504647},"progress":"[=====================\u003e ] 11.75MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":3316461,"total":4964709},"progress":"[=================================\u003e ] 3.316MB/4.965MB","id":"90aca3c647fe"}
|
||||
{"status":"Downloading","progressDetail":{"current":4791021,"total":4964709},"progress":"[================================================\u003e ] 4.791MB/4.965MB","id":"90aca3c647fe"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"90aca3c647fe"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"90aca3c647fe"}
|
||||
{"status":"Downloading","progressDetail":{"current":12315332,"total":27504647},"progress":"[======================\u003e ] 12.32MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":42990315,"total":88111129},"progress":"[========================\u003e ] 42.99MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":13155012,"total":27504647},"progress":"[=======================\u003e ] 13.16MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":43530987,"total":88111129},"progress":"[========================\u003e ] 43.53MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":13990596,"total":27504647},"progress":"[=========================\u003e ] 13.99MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":44063467,"total":88111129},"progress":"[=========================\u003e ] 44.06MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":15112900,"total":27504647},"progress":"[===========================\u003e ] 15.11MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":45132523,"total":88111129},"progress":"[=========================\u003e ] 45.13MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":16235204,"total":27504647},"progress":"[=============================\u003e ] 16.24MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":52418,"total":5149051},"progress":"[\u003e ] 52.42kB/5.149MB","id":"1dd62f37c84c"}
|
||||
{"status":"Downloading","progressDetail":{"current":1195147,"total":5149051},"progress":"[===========\u003e ] 1.195MB/5.149MB","id":"1dd62f37c84c"}
|
||||
{"status":"Downloading","progressDetail":{"current":16792260,"total":27504647},"progress":"[==============================\u003e ] 16.79MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":45673195,"total":88111129},"progress":"[=========================\u003e ] 45.67MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2702475,"total":5149051},"progress":"[==========================\u003e ] 2.702MB/5.149MB","id":"1dd62f37c84c"}
|
||||
{"status":"Downloading","progressDetail":{"current":4078320,"total":5149051},"progress":"[=======================================\u003e ] 4.078MB/5.149MB","id":"1dd62f37c84c"}
|
||||
{"status":"Downloading","progressDetail":{"current":17349316,"total":27504647},"progress":"[===============================\u003e ] 17.35MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"1dd62f37c84c"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"1dd62f37c84c"}
|
||||
{"status":"Downloading","progressDetail":{"current":46213867,"total":88111129},"progress":"[==========================\u003e ] 46.21MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":17918660,"total":27504647},"progress":"[================================\u003e ] 17.92MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":19040964,"total":27504647},"progress":"[==================================\u003e ] 19.04MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":47295211,"total":88111129},"progress":"[==========================\u003e ] 47.3MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":20183748,"total":27504647},"progress":"[====================================\u003e ] 20.18MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":48368363,"total":88111129},"progress":"[===========================\u003e ] 48.37MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":21301956,"total":27504647},"progress":"[======================================\u003e ] 21.3MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":22432452,"total":27504647},"progress":"[========================================\u003e ] 22.43MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":38884,"total":3855277},"progress":"[\u003e ] 38.88kB/3.855MB","id":"3192b2fa42db"}
|
||||
{"status":"Downloading","progressDetail":{"current":49445611,"total":88111129},"progress":"[============================\u003e ] 49.45MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":977632,"total":3855277},"progress":"[============\u003e ] 977.6kB/3.855MB","id":"3192b2fa42db"}
|
||||
{"status":"Downloading","progressDetail":{"current":23268036,"total":27504647},"progress":"[==========================================\u003e ] 23.27MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":49986283,"total":88111129},"progress":"[============================\u003e ] 49.99MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1895136,"total":3855277},"progress":"[========================\u003e ] 1.895MB/3.855MB","id":"3192b2fa42db"}
|
||||
{"status":"Downloading","progressDetail":{"current":23833284,"total":27504647},"progress":"[===========================================\u003e ] 23.83MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":2939616,"total":3855277},"progress":"[======================================\u003e ] 2.94MB/3.855MB","id":"3192b2fa42db"}
|
||||
{"status":"Downloading","progressDetail":{"current":24390340,"total":27504647},"progress":"[============================================\u003e ] 24.39MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"3192b2fa42db"}
|
||||
{"status":"Downloading","progressDetail":{"current":50518763,"total":88111129},"progress":"[============================\u003e ] 50.52MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":24947396,"total":27504647},"progress":"[=============================================\u003e ] 24.95MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":51059435,"total":88111129},"progress":"[============================\u003e ] 51.06MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":25803460,"total":27504647},"progress":"[==============================================\u003e ] 25.8MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":26942148,"total":27504647},"progress":"[================================================\u003e ] 26.94MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":52140779,"total":88111129},"progress":"[=============================\u003e ] 52.14MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":27504647,"total":27504647},"progress":"[==================================================\u003e] 27.5MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"45b746196f82"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":53222123,"total":88111129},"progress":"[==============================\u003e ] 53.22MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":51194,"total":4983195},"progress":"[\u003e ] 51.19kB/4.983MB","id":"ae190b8f66a7"}
|
||||
{"status":"Downloading","progressDetail":{"current":54299371,"total":88111129},"progress":"[==============================\u003e ] 54.3MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1268464,"total":4983195},"progress":"[============\u003e ] 1.268MB/4.983MB","id":"ae190b8f66a7"}
|
||||
{"status":"Downloading","progressDetail":{"current":54827755,"total":88111129},"progress":"[===============================\u003e ] 54.83MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2767600,"total":4983195},"progress":"[===========================\u003e ] 2.768MB/4.983MB","id":"ae190b8f66a7"}
|
||||
{"status":"Downloading","progressDetail":{"current":4528880,"total":4983195},"progress":"[=============================================\u003e ] 4.529MB/4.983MB","id":"ae190b8f66a7"}
|
||||
{"status":"Downloading","progressDetail":{"current":55368427,"total":88111129},"progress":"[===============================\u003e ] 55.37MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"ae190b8f66a7"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"ae190b8f66a7"}
|
||||
{"status":"Downloading","progressDetail":{"current":63614,"total":6103207},"progress":"[\u003e ] 63.61kB/6.103MB","id":"97bb6e138460"}
|
||||
{"status":"Downloading","progressDetail":{"current":56449771,"total":88111129},"progress":"[================================\u003e ] 56.45MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1530606,"total":6103207},"progress":"[============\u003e ] 1.531MB/6.103MB","id":"97bb6e138460"}
|
||||
{"status":"Downloading","progressDetail":{"current":3193582,"total":6103207},"progress":"[==========================\u003e ] 3.194MB/6.103MB","id":"97bb6e138460"}
|
||||
{"status":"Downloading","progressDetail":{"current":56990443,"total":88111129},"progress":"[================================\u003e ] 56.99MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":4786926,"total":6103207},"progress":"[=======================================\u003e ] 4.787MB/6.103MB","id":"97bb6e138460"}
|
||||
{"status":"Downloading","progressDetail":{"current":57531115,"total":88111129},"progress":"[================================\u003e ] 57.53MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"97bb6e138460"}
|
||||
{"status":"Downloading","progressDetail":{"current":489,"total":787},"progress":"[===============================\u003e ] 489B/787B","id":"2edb982d5170"}
|
||||
{"status":"Downloading","progressDetail":{"current":58612459,"total":88111129},"progress":"[=================================\u003e ] 58.61MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":787,"total":787},"progress":"[==================================================\u003e] 787B/787B","id":"2edb982d5170"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"2edb982d5170"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"2edb982d5170"}
|
||||
{"status":"Downloading","progressDetail":{"current":60213995,"total":88111129},"progress":"[==================================\u003e ] 60.21MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":61827819,"total":88111129},"progress":"[===================================\u003e ] 61.83MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":63449835,"total":88111129},"progress":"[====================================\u003e ] 63.45MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":65071851,"total":88111129},"progress":"[====================================\u003e ] 65.07MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":49803,"total":4894860},"progress":"[\u003e ] 49.8kB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Downloading","progressDetail":{"current":49681,"total":4953791},"progress":"[\u003e ] 49.68kB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Downloading","progressDetail":{"current":912099,"total":4894860},"progress":"[=========\u003e ] 912.1kB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Downloading","progressDetail":{"current":66145003,"total":88111129},"progress":"[=====================================\u003e ] 66.15MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":748270,"total":4953791},"progress":"[=======\u003e ] 748.3kB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Downloading","progressDetail":{"current":1702627,"total":4894860},"progress":"[=================\u003e ] 1.703MB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Downloading","progressDetail":{"current":67205867,"total":88111129},"progress":"[======================================\u003e ] 67.21MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1678062,"total":4953791},"progress":"[================\u003e ] 1.678MB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Downloading","progressDetail":{"current":2194147,"total":4894860},"progress":"[======================\u003e ] 2.194MB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Downloading","progressDetail":{"current":67746539,"total":88111129},"progress":"[======================================\u003e ] 67.75MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2648814,"total":4953791},"progress":"[==========================\u003e ] 2.649MB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Downloading","progressDetail":{"current":2743011,"total":4894860},"progress":"[============================\u003e ] 2.743MB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Downloading","progressDetail":{"current":68287211,"total":88111129},"progress":"[======================================\u003e ] 68.29MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3697390,"total":4953791},"progress":"[=====================================\u003e ] 3.697MB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Downloading","progressDetail":{"current":3381987,"total":4894860},"progress":"[==================================\u003e ] 3.382MB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Downloading","progressDetail":{"current":4774638,"total":4953791},"progress":"[================================================\u003e ] 4.775MB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Downloading","progressDetail":{"current":68827883,"total":88111129},"progress":"[=======================================\u003e ] 68.83MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":4953791,"total":4953791},"progress":"[==================================================\u003e] 4.954MB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"0df6fd234b59"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"0df6fd234b59"}
|
||||
{"status":"Downloading","progressDetail":{"current":4004579,"total":4894860},"progress":"[========================================\u003e ] 4.005MB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Downloading","progressDetail":{"current":4893411,"total":4894860},"progress":"[=================================================\u003e ] 4.893MB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"7ddc8e6d6da9"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"7ddc8e6d6da9"}
|
||||
{"status":"Downloading","progressDetail":{"current":69909227,"total":88111129},"progress":"[=======================================\u003e ] 69.91MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":71527147,"total":88111129},"progress":"[========================================\u003e ] 71.53MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":73149163,"total":88111129},"progress":"[=========================================\u003e ] 73.15MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":74771179,"total":88111129},"progress":"[==========================================\u003e ] 74.77MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":63573,"total":6137526},"progress":"[\u003e ] 63.57kB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Downloading","progressDetail":{"current":75311851,"total":88111129},"progress":"[==========================================\u003e ] 75.31MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1317559,"total":6137526},"progress":"[==========\u003e ] 1.318MB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Downloading","progressDetail":{"current":2710199,"total":6137526},"progress":"[======================\u003e ] 2.71MB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Downloading","progressDetail":{"current":38729,"total":3854415},"progress":"[\u003e ] 38.73kB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Downloading","progressDetail":{"current":76368619,"total":88111129},"progress":"[===========================================\u003e ] 76.37MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3783351,"total":6137526},"progress":"[==============================\u003e ] 3.783MB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Downloading","progressDetail":{"current":658157,"total":3854415},"progress":"[========\u003e ] 658.2kB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Downloading","progressDetail":{"current":4520631,"total":6137526},"progress":"[====================================\u003e ] 4.521MB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Downloading","progressDetail":{"current":1350381,"total":3854415},"progress":"[=================\u003e ] 1.35MB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Downloading","progressDetail":{"current":5364407,"total":6137526},"progress":"[===========================================\u003e ] 5.364MB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Downloading","progressDetail":{"current":77445867,"total":88111129},"progress":"[===========================================\u003e ] 77.45MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2153197,"total":3854415},"progress":"[===========================\u003e ] 2.153MB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"8fc1ba8efe21"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"8fc1ba8efe21"}
|
||||
{"status":"Downloading","progressDetail":{"current":77986539,"total":88111129},"progress":"[============================================\u003e ] 77.99MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3021549,"total":3854415},"progress":"[=======================================\u003e ] 3.022MB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"1f6f45e783b5"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"1f6f45e783b5"}
|
||||
{"status":"Downloading","progressDetail":{"current":79067883,"total":88111129},"progress":"[============================================\u003e ] 79.07MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":80149227,"total":88111129},"progress":"[=============================================\u003e ] 80.15MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":81767147,"total":88111129},"progress":"[==============================================\u003e ] 81.77MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":52419,"total":5222290},"progress":"[\u003e ] 52.42kB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Downloading","progressDetail":{"current":1055455,"total":5222290},"progress":"[==========\u003e ] 1.055MB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Downloading","progressDetail":{"current":83372779,"total":88111129},"progress":"[===============================================\u003e ] 83.37MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2333407,"total":5222290},"progress":"[======================\u003e ] 2.333MB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Downloading","progressDetail":{"current":35991,"total":3564359},"progress":"[\u003e ] 35.99kB/3.564MB","id":"b8cf53bbc6ba"}
|
||||
{"status":"Downloading","progressDetail":{"current":84454123,"total":88111129},"progress":"[===============================================\u003e ] 84.45MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3300063,"total":5222290},"progress":"[===============================\u003e ] 3.3MB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Downloading","progressDetail":{"current":752366,"total":3564359},"progress":"[==========\u003e ] 752.4kB/3.564MB","id":"b8cf53bbc6ba"}
|
||||
{"status":"Downloading","progressDetail":{"current":3979999,"total":5222290},"progress":"[======================================\u003e ] 3.98MB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Downloading","progressDetail":{"current":1743598,"total":3564359},"progress":"[========================\u003e ] 1.744MB/3.564MB","id":"b8cf53bbc6ba"}
|
||||
{"status":"Downloading","progressDetail":{"current":85527275,"total":88111129},"progress":"[================================================\u003e ] 85.53MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":4537055,"total":5222290},"progress":"[===========================================\u003e ] 4.537MB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Downloading","progressDetail":{"current":2833134,"total":3564359},"progress":"[=======================================\u003e ] 2.833MB/3.564MB","id":"b8cf53bbc6ba"}
|
||||
{"status":"Downloading","progressDetail":{"current":5077727,"total":5222290},"progress":"[================================================\u003e ] 5.078MB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"b8cf53bbc6ba"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"b8cf53bbc6ba"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"43ea61082f68"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"43ea61082f68"}
|
||||
{"status":"Downloading","progressDetail":{"current":86067947,"total":88111129},"progress":"[================================================\u003e ] 86.07MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":87132907,"total":88111129},"progress":"[=================================================\u003e ] 87.13MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"4ab897fa6fbf"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":557056,"total":88111129},"progress":"[\u003e ] 557.1kB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":52418,"total":5120108},"progress":"[\u003e ] 52.42kB/5.12MB","id":"1c3245356213"}
|
||||
{"status":"Downloading","progressDetail":{"current":489,"total":790},"progress":"[==============================\u003e ] 489B/790B","id":"25efb07e4521"}
|
||||
{"status":"Extracting","progressDetail":{"current":5013504,"total":88111129},"progress":"[==\u003e ] 5.014MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":790,"total":790},"progress":"[==================================================\u003e] 790B/790B","id":"25efb07e4521"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"25efb07e4521"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"25efb07e4521"}
|
||||
{"status":"Downloading","progressDetail":{"current":1764079,"total":5120108},"progress":"[=================\u003e ] 1.764MB/5.12MB","id":"1c3245356213"}
|
||||
{"status":"Extracting","progressDetail":{"current":8355840,"total":88111129},"progress":"[====\u003e ] 8.356MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3635951,"total":5120108},"progress":"[===================================\u003e ] 3.636MB/5.12MB","id":"1c3245356213"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"1c3245356213"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"1c3245356213"}
|
||||
{"status":"Extracting","progressDetail":{"current":11141120,"total":88111129},"progress":"[======\u003e ] 11.14MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":52419,"total":5117023},"progress":"[\u003e ] 52.42kB/5.117MB","id":"61ebb123c1eb"}
|
||||
{"status":"Extracting","progressDetail":{"current":13369344,"total":88111129},"progress":"[=======\u003e ] 13.37MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1596142,"total":5117023},"progress":"[===============\u003e ] 1.596MB/5.117MB","id":"61ebb123c1eb"}
|
||||
{"status":"Extracting","progressDetail":{"current":13926400,"total":88111129},"progress":"[=======\u003e ] 13.93MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3242734,"total":5117023},"progress":"[===============================\u003e ] 3.243MB/5.117MB","id":"61ebb123c1eb"}
|
||||
{"status":"Downloading","progressDetail":{"current":55157,"total":5384215},"progress":"[\u003e ] 55.16kB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Downloading","progressDetail":{"current":4635374,"total":5117023},"progress":"[=============================================\u003e ] 4.635MB/5.117MB","id":"61ebb123c1eb"}
|
||||
{"status":"Extracting","progressDetail":{"current":15040512,"total":88111129},"progress":"[========\u003e ] 15.04MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"61ebb123c1eb"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"61ebb123c1eb"}
|
||||
{"status":"Downloading","progressDetail":{"current":989937,"total":5384215},"progress":"[=========\u003e ] 989.9kB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Extracting","progressDetail":{"current":15597568,"total":88111129},"progress":"[========\u003e ] 15.6MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2558705,"total":5384215},"progress":"[=======================\u003e ] 2.559MB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Extracting","progressDetail":{"current":18382848,"total":88111129},"progress":"[==========\u003e ] 18.38MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":4311793,"total":5384215},"progress":"[========================================\u003e ] 4.312MB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Downloading","progressDetail":{"current":53788,"total":5252487},"progress":"[\u003e ] 53.79kB/5.252MB","id":"87f7843f43cd"}
|
||||
{"status":"Extracting","progressDetail":{"current":22839296,"total":88111129},"progress":"[============\u003e ] 22.84MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":5212913,"total":5384215},"progress":"[================================================\u003e ] 5.213MB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Downloading","progressDetail":{"current":846577,"total":5252487},"progress":"[========\u003e ] 846.6kB/5.252MB","id":"87f7843f43cd"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"0964b769d2c9"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"0964b769d2c9"}
|
||||
{"status":"Extracting","progressDetail":{"current":26181632,"total":88111129},"progress":"[==============\u003e ] 26.18MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2628337,"total":5252487},"progress":"[=========================\u003e ] 2.628MB/5.252MB","id":"87f7843f43cd"}
|
||||
{"status":"Extracting","progressDetail":{"current":30638080,"total":88111129},"progress":"[=================\u003e ] 30.64MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":4340465,"total":5252487},"progress":"[=========================================\u003e ] 4.34MB/5.252MB","id":"87f7843f43cd"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"87f7843f43cd"}
|
||||
{"status":"Extracting","progressDetail":{"current":33423360,"total":88111129},"progress":"[==================\u003e ] 33.42MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":51204,"total":5015856},"progress":"[\u003e ] 51.2kB/5.016MB","id":"a89dbf94d794"}
|
||||
{"status":"Extracting","progressDetail":{"current":36208640,"total":88111129},"progress":"[====================\u003e ] 36.21MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1624816,"total":5015856},"progress":"[================\u003e ] 1.625MB/5.016MB","id":"a89dbf94d794"}
|
||||
{"status":"Extracting","progressDetail":{"current":38436864,"total":88111129},"progress":"[=====================\u003e ] 38.44MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3373808,"total":5015856},"progress":"[=================================\u003e ] 3.374MB/5.016MB","id":"a89dbf94d794"}
|
||||
{"status":"Extracting","progressDetail":{"current":40665088,"total":88111129},"progress":"[=======================\u003e ] 40.67MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":53910,"total":5310566},"progress":"[\u003e ] 53.91kB/5.311MB","id":"f0d43ddca77f"}
|
||||
{"status":"Downloading","progressDetail":{"current":4905712,"total":5015856},"progress":"[================================================\u003e ] 4.906MB/5.016MB","id":"a89dbf94d794"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"a89dbf94d794"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"a89dbf94d794"}
|
||||
{"status":"Downloading","progressDetail":{"current":1313521,"total":5310566},"progress":"[============\u003e ] 1.314MB/5.311MB","id":"f0d43ddca77f"}
|
||||
{"status":"Extracting","progressDetail":{"current":44007424,"total":88111129},"progress":"[========================\u003e ] 44.01MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":46792704,"total":88111129},"progress":"[==========================\u003e ] 46.79MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3082993,"total":5310566},"progress":"[=============================\u003e ] 3.083MB/5.311MB","id":"f0d43ddca77f"}
|
||||
{"status":"Downloading","progressDetail":{"current":49836,"total":4915049},"progress":"[\u003e ] 49.84kB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Downloading","progressDetail":{"current":4373233,"total":5310566},"progress":"[=========================================\u003e ] 4.373MB/5.311MB","id":"f0d43ddca77f"}
|
||||
{"status":"Extracting","progressDetail":{"current":48463872,"total":88111129},"progress":"[===========================\u003e ] 48.46MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":711407,"total":4915049},"progress":"[=======\u003e ] 711.4kB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"f0d43ddca77f"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"f0d43ddca77f"}
|
||||
{"status":"Downloading","progressDetail":{"current":1710831,"total":4915049},"progress":"[=================\u003e ] 1.711MB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Extracting","progressDetail":{"current":52363264,"total":88111129},"progress":"[=============================\u003e ] 52.36MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3504879,"total":4915049},"progress":"[===================================\u003e ] 3.505MB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Extracting","progressDetail":{"current":55705600,"total":88111129},"progress":"[===============================\u003e ] 55.71MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":4905711,"total":4915049},"progress":"[=================================================\u003e ] 4.906MB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"7c674f0cb40c"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"7c674f0cb40c"}
|
||||
{"status":"Extracting","progressDetail":{"current":58490880,"total":88111129},"progress":"[=================================\u003e ] 58.49MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":52419,"total":5119213},"progress":"[\u003e ] 52.42kB/5.119MB","id":"b48a885b52bc"}
|
||||
{"status":"Extracting","progressDetail":{"current":61276160,"total":88111129},"progress":"[==================================\u003e ] 61.28MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1333999,"total":5119213},"progress":"[=============\u003e ] 1.334MB/5.119MB","id":"b48a885b52bc"}
|
||||
{"status":"Downloading","progressDetail":{"current":2657007,"total":5119213},"progress":"[=========================\u003e ] 2.657MB/5.119MB","id":"b48a885b52bc"}
|
||||
{"status":"Extracting","progressDetail":{"current":64061440,"total":88111129},"progress":"[====================================\u003e ] 64.06MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"272cdf839cbb"}
|
||||
{"status":"Downloading","progressDetail":{"current":4344559,"total":5119213},"progress":"[==========================================\u003e ] 4.345MB/5.119MB","id":"b48a885b52bc"}
|
||||
{"status":"Extracting","progressDetail":{"current":66289664,"total":88111129},"progress":"[=====================================\u003e ] 66.29MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"b48a885b52bc"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"b48a885b52bc"}
|
||||
{"status":"Extracting","progressDetail":{"current":70746112,"total":88111129},"progress":"[========================================\u003e ] 70.75MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":73531392,"total":88111129},"progress":"[=========================================\u003e ] 73.53MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":77430784,"total":88111129},"progress":"[===========================================\u003e ] 77.43MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"50d054c97f4f"}
|
||||
{"status":"Downloading","progressDetail":{"current":488,"total":1069},"progress":"[======================\u003e ] 488B/1.069kB","id":"4c6bbd90b64d"}
|
||||
{"status":"Extracting","progressDetail":{"current":80216064,"total":88111129},"progress":"[=============================================\u003e ] 80.22MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1069,"total":1069},"progress":"[==================================================\u003e] 1.069kB/1.069kB","id":"4c6bbd90b64d"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"4c6bbd90b64d"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"4c6bbd90b64d"}
|
||||
{"status":"Downloading","progressDetail":{"current":32,"total":32},"progress":"[==================================================\u003e] 32B/32B","id":"4f4fb700ef54"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"4f4fb700ef54"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"4f4fb700ef54"}
|
||||
{"status":"Extracting","progressDetail":{"current":81887232,"total":88111129},"progress":"[==============================================\u003e ] 81.89MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":83558400,"total":88111129},"progress":"[===============================================\u003e ] 83.56MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":85229568,"total":88111129},"progress":"[================================================\u003e ] 85.23MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":86900736,"total":88111129},"progress":"[=================================================\u003e ] 86.9MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":88014848,"total":88111129},"progress":"[=================================================\u003e ] 88.01MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":88111129,"total":88111129},"progress":"[==================================================\u003e] 88.11MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":32768,"total":1391657},"progress":"[=\u003e ] 32.77kB/1.392MB","id":"d837a2a1365e"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":1391657},"progress":"[===========\u003e ] 327.7kB/1.392MB","id":"d837a2a1365e"}
|
||||
{"status":"Extracting","progressDetail":{"current":1391657,"total":1391657},"progress":"[==================================================\u003e] 1.392MB/1.392MB","id":"d837a2a1365e"}
|
||||
{"status":"Extracting","progressDetail":{"current":1391657,"total":1391657},"progress":"[==================================================\u003e] 1.392MB/1.392MB","id":"d837a2a1365e"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"d837a2a1365e"}
|
||||
{"status":"Extracting","progressDetail":{"current":32768,"total":1328346},"progress":"[=\u003e ] 32.77kB/1.328MB","id":"988ae18fe41a"}
|
||||
{"status":"Extracting","progressDetail":{"current":753664,"total":1328346},"progress":"[============================\u003e ] 753.7kB/1.328MB","id":"988ae18fe41a"}
|
||||
{"status":"Extracting","progressDetail":{"current":1328346,"total":1328346},"progress":"[==================================================\u003e] 1.328MB/1.328MB","id":"988ae18fe41a"}
|
||||
{"status":"Extracting","progressDetail":{"current":1328346,"total":1328346},"progress":"[==================================================\u003e] 1.328MB/1.328MB","id":"988ae18fe41a"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"988ae18fe41a"}
|
||||
{"status":"Extracting","progressDetail":{"current":4478,"total":4478},"progress":"[==================================================\u003e] 4.478kB/4.478kB","id":"eeb8ef83b565"}
|
||||
{"status":"Extracting","progressDetail":{"current":4478,"total":4478},"progress":"[==================================================\u003e] 4.478kB/4.478kB","id":"eeb8ef83b565"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"eeb8ef83b565"}
|
||||
{"status":"Extracting","progressDetail":{"current":197,"total":197},"progress":"[==================================================\u003e] 197B/197B","id":"357fefdf9bc9"}
|
||||
{"status":"Extracting","progressDetail":{"current":197,"total":197},"progress":"[==================================================\u003e] 197B/197B","id":"357fefdf9bc9"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"357fefdf9bc9"}
|
||||
{"status":"Extracting","progressDetail":{"current":294912,"total":27504647},"progress":"[\u003e ] 294.9kB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":589824,"total":27504647},"progress":"[=\u003e ] 589.8kB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":5013504,"total":27504647},"progress":"[=========\u003e ] 5.014MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":9142272,"total":27504647},"progress":"[================\u003e ] 9.142MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":13565952,"total":27504647},"progress":"[========================\u003e ] 13.57MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":16515072,"total":27504647},"progress":"[==============================\u003e ] 16.52MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":18579456,"total":27504647},"progress":"[=================================\u003e ] 18.58MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":21528576,"total":27504647},"progress":"[=======================================\u003e ] 21.53MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":25657344,"total":27504647},"progress":"[==============================================\u003e ] 25.66MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":27504647,"total":27504647},"progress":"[==================================================\u003e] 27.5MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5205016},"progress":"[\u003e ] 65.54kB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Extracting","progressDetail":{"current":1048576,"total":5205016},"progress":"[==========\u003e ] 1.049MB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Extracting","progressDetail":{"current":5205016,"total":5205016},"progress":"[==================================================\u003e] 5.205MB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"fbf4ce20f8c2"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":4964709},"progress":"[\u003e ] 65.54kB/4.965MB","id":"90aca3c647fe"}
|
||||
{"status":"Extracting","progressDetail":{"current":1245184,"total":4964709},"progress":"[============\u003e ] 1.245MB/4.965MB","id":"90aca3c647fe"}
|
||||
{"status":"Extracting","progressDetail":{"current":4964709,"total":4964709},"progress":"[==================================================\u003e] 4.965MB/4.965MB","id":"90aca3c647fe"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"90aca3c647fe"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5149051},"progress":"[\u003e ] 65.54kB/5.149MB","id":"1dd62f37c84c"}
|
||||
{"status":"Extracting","progressDetail":{"current":393216,"total":5149051},"progress":"[===\u003e ] 393.2kB/5.149MB","id":"1dd62f37c84c"}
|
||||
{"status":"Extracting","progressDetail":{"current":5149051,"total":5149051},"progress":"[==================================================\u003e] 5.149MB/5.149MB","id":"1dd62f37c84c"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"1dd62f37c84c"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":3855277},"progress":"[\u003e ] 65.54kB/3.855MB","id":"3192b2fa42db"}
|
||||
{"status":"Extracting","progressDetail":{"current":851968,"total":3855277},"progress":"[===========\u003e ] 852kB/3.855MB","id":"3192b2fa42db"}
|
||||
{"status":"Extracting","progressDetail":{"current":3855277,"total":3855277},"progress":"[==================================================\u003e] 3.855MB/3.855MB","id":"3192b2fa42db"}
|
||||
{"status":"Extracting","progressDetail":{"current":3855277,"total":3855277},"progress":"[==================================================\u003e] 3.855MB/3.855MB","id":"3192b2fa42db"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"3192b2fa42db"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":4983195},"progress":"[\u003e ] 65.54kB/4.983MB","id":"ae190b8f66a7"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":4983195},"progress":"[===\u003e ] 327.7kB/4.983MB","id":"ae190b8f66a7"}
|
||||
{"status":"Extracting","progressDetail":{"current":4980736,"total":4983195},"progress":"[=================================================\u003e ] 4.981MB/4.983MB","id":"ae190b8f66a7"}
|
||||
{"status":"Extracting","progressDetail":{"current":4983195,"total":4983195},"progress":"[==================================================\u003e] 4.983MB/4.983MB","id":"ae190b8f66a7"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"ae190b8f66a7"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":6103207},"progress":"[\u003e ] 65.54kB/6.103MB","id":"97bb6e138460"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":6103207},"progress":"[==\u003e ] 327.7kB/6.103MB","id":"97bb6e138460"}
|
||||
{"status":"Extracting","progressDetail":{"current":3670016,"total":6103207},"progress":"[==============================\u003e ] 3.67MB/6.103MB","id":"97bb6e138460"}
|
||||
{"status":"Extracting","progressDetail":{"current":6103207,"total":6103207},"progress":"[==================================================\u003e] 6.103MB/6.103MB","id":"97bb6e138460"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"97bb6e138460"}
|
||||
{"status":"Extracting","progressDetail":{"current":787,"total":787},"progress":"[==================================================\u003e] 787B/787B","id":"2edb982d5170"}
|
||||
{"status":"Extracting","progressDetail":{"current":787,"total":787},"progress":"[==================================================\u003e] 787B/787B","id":"2edb982d5170"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"2edb982d5170"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":4894860},"progress":"[\u003e ] 65.54kB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":4894860},"progress":"[===\u003e ] 327.7kB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Extracting","progressDetail":{"current":3735552,"total":4894860},"progress":"[======================================\u003e ] 3.736MB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Extracting","progressDetail":{"current":4894860,"total":4894860},"progress":"[==================================================\u003e] 4.895MB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"7ddc8e6d6da9"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":4953791},"progress":"[\u003e ] 65.54kB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":4953791},"progress":"[===\u003e ] 327.7kB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Extracting","progressDetail":{"current":4325376,"total":4953791},"progress":"[===========================================\u003e ] 4.325MB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Extracting","progressDetail":{"current":4953791,"total":4953791},"progress":"[==================================================\u003e] 4.954MB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"0df6fd234b59"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":6137526},"progress":"[\u003e ] 65.54kB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":6137526},"progress":"[==\u003e ] 327.7kB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Extracting","progressDetail":{"current":3801088,"total":6137526},"progress":"[==============================\u003e ] 3.801MB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Extracting","progressDetail":{"current":6137526,"total":6137526},"progress":"[==================================================\u003e] 6.138MB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"8fc1ba8efe21"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":3854415},"progress":"[\u003e ] 65.54kB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Extracting","progressDetail":{"current":851968,"total":3854415},"progress":"[===========\u003e ] 852kB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Extracting","progressDetail":{"current":3854415,"total":3854415},"progress":"[==================================================\u003e] 3.854MB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Extracting","progressDetail":{"current":3854415,"total":3854415},"progress":"[==================================================\u003e] 3.854MB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"1f6f45e783b5"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5222290},"progress":"[\u003e ] 65.54kB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Extracting","progressDetail":{"current":458752,"total":5222290},"progress":"[====\u003e ] 458.8kB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Extracting","progressDetail":{"current":4849664,"total":5222290},"progress":"[==============================================\u003e ] 4.85MB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Extracting","progressDetail":{"current":5222290,"total":5222290},"progress":"[==================================================\u003e] 5.222MB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"43ea61082f68"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":3564359},"progress":"[\u003e ] 65.54kB/3.564MB","id":"b8cf53bbc6ba"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":3564359},"progress":"[====\u003e ] 327.7kB/3.564MB","id":"b8cf53bbc6ba"}
|
||||
{"status":"Extracting","progressDetail":{"current":3564359,"total":3564359},"progress":"[==================================================\u003e] 3.564MB/3.564MB","id":"b8cf53bbc6ba"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"b8cf53bbc6ba"}
|
||||
{"status":"Extracting","progressDetail":{"current":790,"total":790},"progress":"[==================================================\u003e] 790B/790B","id":"25efb07e4521"}
|
||||
{"status":"Extracting","progressDetail":{"current":790,"total":790},"progress":"[==================================================\u003e] 790B/790B","id":"25efb07e4521"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"25efb07e4521"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5120108},"progress":"[\u003e ] 65.54kB/5.12MB","id":"1c3245356213"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":5120108},"progress":"[===\u003e ] 327.7kB/5.12MB","id":"1c3245356213"}
|
||||
{"status":"Extracting","progressDetail":{"current":5111808,"total":5120108},"progress":"[=================================================\u003e ] 5.112MB/5.12MB","id":"1c3245356213"}
|
||||
{"status":"Extracting","progressDetail":{"current":5120108,"total":5120108},"progress":"[==================================================\u003e] 5.12MB/5.12MB","id":"1c3245356213"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"1c3245356213"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5117023},"progress":"[\u003e ] 65.54kB/5.117MB","id":"61ebb123c1eb"}
|
||||
{"status":"Extracting","progressDetail":{"current":655360,"total":5117023},"progress":"[======\u003e ] 655.4kB/5.117MB","id":"61ebb123c1eb"}
|
||||
{"status":"Extracting","progressDetail":{"current":4259840,"total":5117023},"progress":"[=========================================\u003e ] 4.26MB/5.117MB","id":"61ebb123c1eb"}
|
||||
{"status":"Extracting","progressDetail":{"current":5117023,"total":5117023},"progress":"[==================================================\u003e] 5.117MB/5.117MB","id":"61ebb123c1eb"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"61ebb123c1eb"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5384215},"progress":"[\u003e ] 65.54kB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":5384215},"progress":"[===\u003e ] 327.7kB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Extracting","progressDetail":{"current":5177344,"total":5384215},"progress":"[================================================\u003e ] 5.177MB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Extracting","progressDetail":{"current":5384215,"total":5384215},"progress":"[==================================================\u003e] 5.384MB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"0964b769d2c9"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5252487},"progress":"[\u003e ] 65.54kB/5.252MB","id":"87f7843f43cd"}
|
||||
{"status":"Extracting","progressDetail":{"current":655360,"total":5252487},"progress":"[======\u003e ] 655.4kB/5.252MB","id":"87f7843f43cd"}
|
||||
{"status":"Extracting","progressDetail":{"current":5252487,"total":5252487},"progress":"[==================================================\u003e] 5.252MB/5.252MB","id":"87f7843f43cd"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"87f7843f43cd"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5015856},"progress":"[\u003e ] 65.54kB/5.016MB","id":"a89dbf94d794"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":5015856},"progress":"[===\u003e ] 327.7kB/5.016MB","id":"a89dbf94d794"}
|
||||
{"status":"Extracting","progressDetail":{"current":3997696,"total":5015856},"progress":"[=======================================\u003e ] 3.998MB/5.016MB","id":"a89dbf94d794"}
|
||||
{"status":"Extracting","progressDetail":{"current":5015856,"total":5015856},"progress":"[==================================================\u003e] 5.016MB/5.016MB","id":"a89dbf94d794"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"a89dbf94d794"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5310566},"progress":"[\u003e ] 65.54kB/5.311MB","id":"f0d43ddca77f"}
|
||||
{"status":"Extracting","progressDetail":{"current":393216,"total":5310566},"progress":"[===\u003e ] 393.2kB/5.311MB","id":"f0d43ddca77f"}
|
||||
{"status":"Extracting","progressDetail":{"current":3407872,"total":5310566},"progress":"[================================\u003e ] 3.408MB/5.311MB","id":"f0d43ddca77f"}
|
||||
{"status":"Extracting","progressDetail":{"current":5310566,"total":5310566},"progress":"[==================================================\u003e] 5.311MB/5.311MB","id":"f0d43ddca77f"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"f0d43ddca77f"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":4915049},"progress":"[\u003e ] 65.54kB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Extracting","progressDetail":{"current":786432,"total":4915049},"progress":"[========\u003e ] 786.4kB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Extracting","progressDetail":{"current":4915049,"total":4915049},"progress":"[==================================================\u003e] 4.915MB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Extracting","progressDetail":{"current":4915049,"total":4915049},"progress":"[==================================================\u003e] 4.915MB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"7c674f0cb40c"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5119213},"progress":"[\u003e ] 65.54kB/5.119MB","id":"b48a885b52bc"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":5119213},"progress":"[===\u003e ] 327.7kB/5.119MB","id":"b48a885b52bc"}
|
||||
{"status":"Extracting","progressDetail":{"current":4390912,"total":5119213},"progress":"[==========================================\u003e ] 4.391MB/5.119MB","id":"b48a885b52bc"}
|
||||
{"status":"Extracting","progressDetail":{"current":5119213,"total":5119213},"progress":"[==================================================\u003e] 5.119MB/5.119MB","id":"b48a885b52bc"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"b48a885b52bc"}
|
||||
{"status":"Extracting","progressDetail":{"current":395,"total":395},"progress":"[==================================================\u003e] 395B/395B","id":"272cdf839cbb"}
|
||||
{"status":"Extracting","progressDetail":{"current":395,"total":395},"progress":"[==================================================\u003e] 395B/395B","id":"272cdf839cbb"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"272cdf839cbb"}
|
||||
{"status":"Extracting","progressDetail":{"current":155,"total":155},"progress":"[==================================================\u003e] 155B/155B","id":"50d054c97f4f"}
|
||||
{"status":"Extracting","progressDetail":{"current":155,"total":155},"progress":"[==================================================\u003e] 155B/155B","id":"50d054c97f4f"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"50d054c97f4f"}
|
||||
{"status":"Extracting","progressDetail":{"current":1069,"total":1069},"progress":"[==================================================\u003e] 1.069kB/1.069kB","id":"4c6bbd90b64d"}
|
||||
{"status":"Extracting","progressDetail":{"current":1069,"total":1069},"progress":"[==================================================\u003e] 1.069kB/1.069kB","id":"4c6bbd90b64d"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"4c6bbd90b64d"}
|
||||
{"status":"Extracting","progressDetail":{"current":32,"total":32},"progress":"[==================================================\u003e] 32B/32B","id":"4f4fb700ef54"}
|
||||
{"status":"Extracting","progressDetail":{"current":32,"total":32},"progress":"[==================================================\u003e] 32B/32B","id":"4f4fb700ef54"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"4f4fb700ef54"}
|
||||
{"status":"Digest: sha256:4acb6bfd6c4f0cabaf7f3690e444afe51f1c7de54d51da7e63fac709c56f1c30"}
|
||||
{"status":"Status: Downloaded newer image for cloudfoundry/cnb:bionic"}
|
||||
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"status": "Extracting",
|
||||
"progressDetail": {
|
||||
"current": 16,
|
||||
"total": 32
|
||||
},
|
||||
"progress": "[==================================================\u003e] 32B/32B",
|
||||
"id": "4f4fb700ef54"
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"status": "Status: Downloaded newer image for cloudfoundry/cnb:bionic"
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"status": "Pulling fs layer",
|
||||
"progressDetail": {
|
||||
},
|
||||
"id": "d837a2a1365e"
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"User": "root",
|
||||
"Image": "docker.io/library/ubuntu:bionic",
|
||||
"Cmd": [
|
||||
"ls",
|
||||
"-l",
|
||||
"-h"
|
||||
],
|
||||
"Labels": {
|
||||
"spring": "boot"
|
||||
},
|
||||
"HostConfig": {
|
||||
"Binds": [
|
||||
"bind-source:bind-dest"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
{
|
||||
"config": {
|
||||
"Hostname": "",
|
||||
"Domainname": "",
|
||||
"User": "vcap",
|
||||
"AttachStdin": false,
|
||||
"AttachStdout": false,
|
||||
"AttachStderr": false,
|
||||
"Tty": false,
|
||||
"OpenStdin": false,
|
||||
"StdinOnce": false,
|
||||
"Env": [
|
||||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin",
|
||||
"CNB_USER_ID=2000",
|
||||
"CNB_GROUP_ID=2000",
|
||||
"CNB_STACK_ID=org.cloudfoundry.stacks.cflinuxfs3"
|
||||
],
|
||||
"Cmd": null,
|
||||
"Image": "sha256:523c8ade6e06f814469b2cf04c8045a74becee17088955f2657958476d3fba1f",
|
||||
"Volumes": null,
|
||||
"WorkingDir": "/layers",
|
||||
"Entrypoint": null,
|
||||
"OnBuild": null,
|
||||
"Labels": {
|
||||
"io.buildpacks.stack.id": "org.cloudfoundry.stacks.cflinuxfs3"
|
||||
}
|
||||
},
|
||||
"created": "1906-12-09T11:30:00Z",
|
||||
"history": [
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
},
|
||||
{
|
||||
|
||||
}
|
||||
],
|
||||
"os": "linux",
|
||||
"rootfs": {
|
||||
"diff_ids": [
|
||||
"sha256:733a8e5ce32984099ef675fce04730f6e2a6dcfdf5bd292fea01a8f936265342",
|
||||
"sha256:7755b972f0b4f49de73ef5114fb3ba9c69d80f217e80da99f56f0d0a5dcb3d70",
|
||||
"sha256:8f0b2d09ab4b38530a1630403967d11a601e56e02e79d3f56370d34fd071fe38",
|
||||
"sha256:8debe4b6b4290dbbfecea9edea61c22fb455e69e3cbc7d63b17f8e1ab8ea669b",
|
||||
"sha256:0c6ddab305e5452850f3c09fe15310dff8dc7221702d736dc7705882c1df9658",
|
||||
"sha256:a9527973bb5d7ccdf88b5be8eb81e024094be1709df659af3127865463c1c188",
|
||||
"sha256:480cd420e43c6895240c87c88969b87417549c02393cde1b6f71a3a3d5a2a620",
|
||||
"sha256:391d950d763a33d8ae0373f218aa59907599f51e42cd864129591887e1291034",
|
||||
"sha256:5b3ec0a6ed9e3de93bb082151f56b1cde5d7e31f2809039a1b5b55a5052fe873",
|
||||
"sha256:ef935546e2c99da3e8962f2eb3cd6813e9e9a8b19bc8d15b56d1cac37f0342d5",
|
||||
"sha256:6d644992d62bd09a2bbf490b7fe3aa1e35e6d0d2479583c2decec7092f193310",
|
||||
"sha256:59d817c36a25078c8ec1f6de0d8336aec598037f89708ed13dbf661557a25084",
|
||||
"sha256:6636ce01d12372e56a89ec77ea8d9ed510f8c701df1220750add4613764c05a4",
|
||||
"sha256:96c7f369c29bbf11b971e4dbb6473e8991b666f9de046a414317634eb0a25d2a",
|
||||
"sha256:3544ba1fa82d1e89619ed04c2485fab3445b1603959d224792d1183dd658033d",
|
||||
"sha256:12d99406b52b526af152628cd72ba6eacf5d18484dc79cfdacd4b38a21620a2b",
|
||||
"sha256:3b3cda9eceb0fca56c274e3be93daf53f59501e6b3628fabbaea8ea416eb757a",
|
||||
"sha256:27ad0fc48c381eb77f69b4e80edccb4d8a2399f5cebd5a8c5a3e1c32313343a6",
|
||||
"sha256:52845fb94361dad36cc4136e49b92c79ca59c16c579e2f51df0c58ba355c4367",
|
||||
"sha256:7bf3a57229276fb913155b077d00a18ec6cba92c7f062728ca1c3bc3503c0b55",
|
||||
"sha256:e5df92d3db931488225ca9f7290de0334225d4bd7c48fc2dcd380d0921bb6680",
|
||||
"sha256:290ac64fbae3288821551371c8dda38fcf5dfa063a54cb270dcc395a090f5173",
|
||||
"sha256:996aee90e29ed78d80a5a0c0e50d60a732a18fddae06f87b68bef183beddd2c4",
|
||||
"sha256:30f6a316d4da01d694d8c17aa84b37f468cccc7184248e255486eb3095ebb87c",
|
||||
"sha256:c694476a7241ba4e4a0663606d4d6eec7ed8624252c010fbef2713968e8f9436",
|
||||
"sha256:ab9aaff2160873663388faea6d987cd8f2b5935137b81c64fde145bf2a330d54",
|
||||
"sha256:e1f3ab860045b96235cbc1b89a3e73add955a303eb42905b570b6012b73b9184",
|
||||
"sha256:0b260d90d097379d4351132b45110d013b98f4a335795baeb95788fcebcb7f3c",
|
||||
"sha256:f0f5ecd72b4e0a38d3ad73b5756d8f209955932e9615715502a61dffe56f401a",
|
||||
"sha256:b4cd790490e41c808e8d65f9ac8f2e58c79bc1a9919a713c4519e77b26dc2053",
|
||||
"sha256:16b88c0e7f950c32c7496117d1efad90a8557a2badcb267d99a19676b1f0b76a",
|
||||
"sha256:49d36ba00b17fb605f374ca7877ae129678de925d10fd1955f07c2b6f74dd1c9",
|
||||
"sha256:b31d189a88ca43fee6077c25bcb623582d569193ed6ac11b4e5623558911e3de",
|
||||
"sha256:3ecfd2822cf64c609c9c8489e2accfbc0b1de0f2a3637ff1b5d30768fb34b40c",
|
||||
"sha256:a7f09c3e09b29c5503962a068f29e8726cb91d1dbce2fab688aee0a98189b2be",
|
||||
"sha256:3d12e651068a0ff19afdd568b5d14ee5292f849542b31d6c9b099a09344e1f4d",
|
||||
"sha256:f01e41975a9335f5983021b081bc700e46b85efb262670223c4db61eea0a3ebd",
|
||||
"sha256:2b1b655bb8752f631e786c4c55670315d8569acccfe26402942977c216f2803a",
|
||||
"sha256:0943c634f5c24311ebdeca6fef5682a4a374c89a831700d188bff7f987470004",
|
||||
"sha256:9a183e56c86d376b408bdf922746d0a657f62b0e18c7c8f82a496b87710c576f",
|
||||
"sha256:d919f3c2f534ddbb0b6057f82bca36051ce80a2a9cd3016c320ae276884311f5",
|
||||
"sha256:108a3eb288f8094aab6ffd822c593902e48e85c8a37b7da2bd21b15f785d92c5",
|
||||
"sha256:f8b5dcfa1d082af23bb2b2c08526131921329d48d1614d9f2f163a997176087a",
|
||||
"sha256:ee13e75c33e0af49fbf6c3aaa5bbd102fc468c2d554c4f94763d35a33964dfe4",
|
||||
"sha256:2571abab1776d4c2e427fba10d61531afff2ab0789f89ef46ce925b6a5d98e0f",
|
||||
"sha256:5f70bf18a086007016e948b04aed3b82103a36bea41755b6cddfaf10ace3c6ef",
|
||||
"sha256:bb09e17fd1bd2ee47155f1349645fcd9fff31e1247c7ed99cad469f1c16a4216"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
[
|
||||
{
|
||||
"Config": "/d1872169d781cff5e1aa22d111f636bef0c57e1c358ca3861e3d33a5bdb1b4a5.json",
|
||||
"Layers": [
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"bb09e17fd1bd2ee47155f1349645fcd9fff31e1247c7ed99cad469f1c16a4216.tar"
|
||||
],
|
||||
"RepoTags": [
|
||||
"pack.local/builder/6b7874626575656b6162:latest"
|
||||
]
|
||||
}
|
||||
]
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,51 @@
|
||||
[
|
||||
{
|
||||
"Config": "fdc5f384ea0818dd99462e53bf2088a0fa42ad4de5878fdf078935192604da6d.json",
|
||||
"Layers": [
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"",
|
||||
"/e39b9186d3d35693645f81db5ec6ced177c4da2d26f71a55de7834fc3b161a60.tar",
|
||||
"/791b31c608b369f0d6e23aaf55dd6bae76ffd92292afd3eb4dd35f8a389636fb.tar",
|
||||
"/66d1ab676a2ecb3852104177d2fd9499d90bbbd97984bccb62180502e15a7086.tar",
|
||||
"/b5787d8d30d02769ebbe6b1ac32d37764feef3cd5cdc68aeffd72bb27d1886e5.tar"
|
||||
],
|
||||
"RepoTags": [
|
||||
"pack.local/builder/6b7874626575656b6162:latest"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -0,0 +1,598 @@
|
||||
{
|
||||
"status": "Pulling from cloudfoundry/cnb",
|
||||
"id": "bionic"
|
||||
}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"5667fdb72017"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"d83811f270d5"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"ee671aafb583"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"7fc152dfb3a6"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"4ab897fa6fbf"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"d837a2a1365e"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"988ae18fe41a"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"eeb8ef83b565"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"357fefdf9bc9"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"45b746196f82"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"fbf4ce20f8c2"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"90aca3c647fe"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"1dd62f37c84c"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"3192b2fa42db"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"ae190b8f66a7"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"97bb6e138460"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"eeb8ef83b565"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"2edb982d5170"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"357fefdf9bc9"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"7ddc8e6d6da9"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"0df6fd234b59"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"45b746196f82"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"8fc1ba8efe21"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"1f6f45e783b5"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"43ea61082f68"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"7fc152dfb3a6"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"b8cf53bbc6ba"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"fbf4ce20f8c2"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"25efb07e4521"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"90aca3c647fe"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"1c3245356213"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"1dd62f37c84c"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"61ebb123c1eb"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"0964b769d2c9"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"3192b2fa42db"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"87f7843f43cd"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"a89dbf94d794"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"ae190b8f66a7"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"f0d43ddca77f"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"7c674f0cb40c"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"97bb6e138460"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"b48a885b52bc"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"272cdf839cbb"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"50d054c97f4f"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"4c6bbd90b64d"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"2edb982d5170"}
|
||||
{"status":"Pulling fs layer","progressDetail":{},"id":"4f4fb700ef54"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"7ddc8e6d6da9"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"b8cf53bbc6ba"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"25efb07e4521"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"0df6fd234b59"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"1c3245356213"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"61ebb123c1eb"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"8fc1ba8efe21"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"0964b769d2c9"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"87f7843f43cd"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"1f6f45e783b5"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"a89dbf94d794"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"43ea61082f68"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"f0d43ddca77f"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"7c674f0cb40c"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"b48a885b52bc"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"272cdf839cbb"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"50d054c97f4f"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"4c6bbd90b64d"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"4f4fb700ef54"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"4ab897fa6fbf"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"d837a2a1365e"}
|
||||
{"status":"Waiting","progressDetail":{},"id":"988ae18fe41a"}
|
||||
{"status":"Downloading","progressDetail":{"current":487,"total":850},"progress":"[============================\u003e ] 487B/850B","id":"ee671aafb583"}
|
||||
{"status":"Downloading","progressDetail":{"current":485,"total":35355},"progress":"[\u003e ] 485B/35.35kB","id":"d83811f270d5"}
|
||||
{"status":"Downloading","progressDetail":{"current":35355,"total":35355},"progress":"[==================================================\u003e] 35.35kB/35.35kB","id":"d83811f270d5"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"d83811f270d5"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"d83811f270d5"}
|
||||
{"status":"Downloading","progressDetail":{"current":277600,"total":26683298},"progress":"[\u003e ] 277.6kB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":850,"total":850},"progress":"[==================================================\u003e] 850B/850B","id":"ee671aafb583"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"ee671aafb583"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"ee671aafb583"}
|
||||
{"status":"Downloading","progressDetail":{"current":2218692,"total":26683298},"progress":"[====\u003e ] 2.219MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":4160196,"total":26683298},"progress":"[=======\u003e ] 4.16MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":6109892,"total":26683298},"progress":"[===========\u003e ] 6.11MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":7772868,"total":26683298},"progress":"[==============\u003e ] 7.773MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":9444036,"total":26683298},"progress":"[=================\u003e ] 9.444MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":163,"total":163},"progress":"[==================================================\u003e] 163B/163B","id":"7fc152dfb3a6"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"7fc152dfb3a6"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"7fc152dfb3a6"}
|
||||
{"status":"Downloading","progressDetail":{"current":10832580,"total":26683298},"progress":"[====================\u003e ] 10.83MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":531179,"total":88111129},"progress":"[\u003e ] 531.2kB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":11668164,"total":26683298},"progress":"[=====================\u003e ] 11.67MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":1604331,"total":88111129},"progress":"[\u003e ] 1.604MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":12495556,"total":26683298},"progress":"[=======================\u003e ] 12.5MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":3209963,"total":88111129},"progress":"[=\u003e ] 3.21MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":13331140,"total":26683298},"progress":"[========================\u003e ] 13.33MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":4283115,"total":88111129},"progress":"[==\u003e ] 4.283MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":14166724,"total":26683298},"progress":"[==========================\u003e ] 14.17MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":5888747,"total":88111129},"progress":"[===\u003e ] 5.889MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":15280836,"total":26683298},"progress":"[============================\u003e ] 15.28MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":14318,"total":1391657},"progress":"[\u003e ] 14.32kB/1.392MB","id":"d837a2a1365e"}
|
||||
{"status":"Downloading","progressDetail":{"current":6961899,"total":88111129},"progress":"[===\u003e ] 6.962MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":16116420,"total":26683298},"progress":"[==============================\u003e ] 16.12MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":936688,"total":1391657},"progress":"[=================================\u003e ] 936.7kB/1.392MB","id":"d837a2a1365e"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"d837a2a1365e"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"d837a2a1365e"}
|
||||
{"status":"Downloading","progressDetail":{"current":8022763,"total":88111129},"progress":"[====\u003e ] 8.023MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":16931524,"total":26683298},"progress":"[===============================\u003e ] 16.93MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":18045636,"total":26683298},"progress":"[=================================\u003e ] 18.05MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":9632491,"total":88111129},"progress":"[=====\u003e ] 9.632MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":10709739,"total":88111129},"progress":"[======\u003e ] 10.71MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":19143364,"total":26683298},"progress":"[===================================\u003e ] 19.14MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":11778795,"total":88111129},"progress":"[======\u003e ] 11.78MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":20249284,"total":26683298},"progress":"[=====================================\u003e ] 20.25MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":12851947,"total":88111129},"progress":"[=======\u003e ] 12.85MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":21072580,"total":26683298},"progress":"[=======================================\u003e ] 21.07MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":14133,"total":1328346},"progress":"[\u003e ] 14.13kB/1.328MB","id":"988ae18fe41a"}
|
||||
{"status":"Downloading","progressDetail":{"current":13933291,"total":88111129},"progress":"[=======\u003e ] 13.93MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":21908164,"total":26683298},"progress":"[=========================================\u003e ] 21.91MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":973511,"total":1328346},"progress":"[====================================\u003e ] 973.5kB/1.328MB","id":"988ae18fe41a"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"988ae18fe41a"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"988ae18fe41a"}
|
||||
{"status":"Downloading","progressDetail":{"current":15014635,"total":88111129},"progress":"[========\u003e ] 15.01MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":22747844,"total":26683298},"progress":"[==========================================\u003e ] 22.75MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":16075499,"total":88111129},"progress":"[=========\u003e ] 16.08MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":23575236,"total":26683298},"progress":"[============================================\u003e ] 23.58MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":24414916,"total":26683298},"progress":"[=============================================\u003e ] 24.41MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":17132267,"total":88111129},"progress":"[=========\u003e ] 17.13MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":25250500,"total":26683298},"progress":"[===============================================\u003e ] 25.25MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":18213611,"total":88111129},"progress":"[==========\u003e ] 18.21MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":26073796,"total":26683298},"progress":"[================================================\u003e ] 26.07MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":19286763,"total":88111129},"progress":"[==========\u003e ] 19.29MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":490,"total":4478},"progress":"[=====\u003e ] 490B/4.478kB","id":"eeb8ef83b565"}
|
||||
{"status":"Downloading","progressDetail":{"current":4478,"total":4478},"progress":"[==================================================\u003e] 4.478kB/4.478kB","id":"eeb8ef83b565"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"eeb8ef83b565"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"eeb8ef83b565"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"5667fdb72017"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":20892395,"total":88111129},"progress":"[===========\u003e ] 20.89MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":294912,"total":26683298},"progress":"[\u003e ] 294.9kB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":23050987,"total":88111129},"progress":"[=============\u003e ] 23.05MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":2654208,"total":26683298},"progress":"[====\u003e ] 2.654MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":25205483,"total":88111129},"progress":"[==============\u003e ] 25.21MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":6193152,"total":26683298},"progress":"[===========\u003e ] 6.193MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":27355883,"total":88111129},"progress":"[===============\u003e ] 27.36MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":8552448,"total":26683298},"progress":"[================\u003e ] 8.552MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":197,"total":197},"progress":"[==================================================\u003e] 197B/197B","id":"357fefdf9bc9"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"357fefdf9bc9"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"357fefdf9bc9"}
|
||||
{"status":"Extracting","progressDetail":{"current":11796480,"total":26683298},"progress":"[======================\u003e ] 11.8MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":29510379,"total":88111129},"progress":"[================\u003e ] 29.51MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":277600,"total":27504647},"progress":"[\u003e ] 277.6kB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":15040512,"total":26683298},"progress":"[============================\u003e ] 15.04MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":1391300,"total":27504647},"progress":"[==\u003e ] 1.391MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":31132395,"total":88111129},"progress":"[=================\u003e ] 31.13MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":17989632,"total":26683298},"progress":"[=================================\u003e ] 17.99MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":32754411,"total":88111129},"progress":"[==================\u003e ] 32.75MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2230980,"total":27504647},"progress":"[====\u003e ] 2.231MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":22118400,"total":26683298},"progress":"[=========================================\u003e ] 22.12MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":33835755,"total":88111129},"progress":"[===================\u003e ] 33.84MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3078852,"total":27504647},"progress":"[=====\u003e ] 3.079MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":24477696,"total":26683298},"progress":"[=============================================\u003e ] 24.48MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":52419,"total":5205016},"progress":"[\u003e ] 52.42kB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Downloading","progressDetail":{"current":34917099,"total":88111129},"progress":"[===================\u003e ] 34.92MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3922628,"total":27504647},"progress":"[=======\u003e ] 3.923MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":912096,"total":5205016},"progress":"[========\u003e ] 912.1kB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Extracting","progressDetail":{"current":26247168,"total":26683298},"progress":"[=================================================\u003e ] 26.25MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":4487876,"total":27504647},"progress":"[========\u003e ] 4.488MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":35986155,"total":88111129},"progress":"[====================\u003e ] 35.99MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":26683298,"total":26683298},"progress":"[==================================================\u003e] 26.68MB/26.68MB","id":"5667fdb72017"}
|
||||
{"status":"Downloading","progressDetail":{"current":1805024,"total":5205016},"progress":"[=================\u003e ] 1.805MB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Downloading","progressDetail":{"current":5044932,"total":27504647},"progress":"[=========\u003e ] 5.045MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":36522731,"total":88111129},"progress":"[====================\u003e ] 36.52MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2550496,"total":5205016},"progress":"[========================\u003e ] 2.55MB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Downloading","progressDetail":{"current":5601988,"total":27504647},"progress":"[==========\u003e ] 5.602MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":3381984,"total":5205016},"progress":"[================================\u003e ] 3.382MB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Downloading","progressDetail":{"current":37063403,"total":88111129},"progress":"[=====================\u003e ] 37.06MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":6159044,"total":27504647},"progress":"[===========\u003e ] 6.159MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":4152032,"total":5205016},"progress":"[=======================================\u003e ] 4.152MB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Downloading","progressDetail":{"current":37604075,"total":88111129},"progress":"[=====================\u003e ] 37.6MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"5667fdb72017"}
|
||||
{"status":"Extracting","progressDetail":{"current":32768,"total":35355},"progress":"[==============================================\u003e ] 32.77kB/35.35kB","id":"d83811f270d5"}
|
||||
{"status":"Extracting","progressDetail":{"current":35355,"total":35355},"progress":"[==================================================\u003e] 35.35kB/35.35kB","id":"d83811f270d5"}
|
||||
{"status":"Downloading","progressDetail":{"current":5004000,"total":5205016},"progress":"[================================================\u003e ] 5.004MB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Downloading","progressDetail":{"current":6716100,"total":27504647},"progress":"[============\u003e ] 6.716MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"fbf4ce20f8c2"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"fbf4ce20f8c2"}
|
||||
{"status":"Downloading","progressDetail":{"current":38144747,"total":88111129},"progress":"[=====================\u003e ] 38.14MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"d83811f270d5"}
|
||||
{"status":"Extracting","progressDetail":{"current":850,"total":850},"progress":"[==================================================\u003e] 850B/850B","id":"ee671aafb583"}
|
||||
{"status":"Extracting","progressDetail":{"current":850,"total":850},"progress":"[==================================================\u003e] 850B/850B","id":"ee671aafb583"}
|
||||
{"status":"Downloading","progressDetail":{"current":7293636,"total":27504647},"progress":"[=============\u003e ] 7.294MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":39213803,"total":88111129},"progress":"[======================\u003e ] 39.21MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":8129220,"total":27504647},"progress":"[==============\u003e ] 8.129MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"ee671aafb583"}
|
||||
{"status":"Extracting","progressDetail":{"current":163,"total":163},"progress":"[==================================================\u003e] 163B/163B","id":"7fc152dfb3a6"}
|
||||
{"status":"Extracting","progressDetail":{"current":163,"total":163},"progress":"[==================================================\u003e] 163B/163B","id":"7fc152dfb3a6"}
|
||||
{"status":"Downloading","progressDetail":{"current":40295147,"total":88111129},"progress":"[======================\u003e ] 40.3MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":8964804,"total":27504647},"progress":"[================\u003e ] 8.965MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"7fc152dfb3a6"}
|
||||
{"status":"Downloading","progressDetail":{"current":9800388,"total":27504647},"progress":"[=================\u003e ] 9.8MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":41368299,"total":88111129},"progress":"[=======================\u003e ] 41.37MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":49680,"total":4964709},"progress":"[\u003e ] 49.68kB/4.965MB","id":"90aca3c647fe"}
|
||||
{"status":"Downloading","progressDetail":{"current":10635972,"total":27504647},"progress":"[===================\u003e ] 10.64MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":908013,"total":4964709},"progress":"[=========\u003e ] 908kB/4.965MB","id":"90aca3c647fe"}
|
||||
{"status":"Downloading","progressDetail":{"current":41908971,"total":88111129},"progress":"[=======================\u003e ] 41.91MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":11193028,"total":27504647},"progress":"[====================\u003e ] 11.19MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":2038509,"total":4964709},"progress":"[====================\u003e ] 2.039MB/4.965MB","id":"90aca3c647fe"}
|
||||
{"status":"Downloading","progressDetail":{"current":42449643,"total":88111129},"progress":"[========================\u003e ] 42.45MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":11750084,"total":27504647},"progress":"[=====================\u003e ] 11.75MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":3316461,"total":4964709},"progress":"[=================================\u003e ] 3.316MB/4.965MB","id":"90aca3c647fe"}
|
||||
{"status":"Downloading","progressDetail":{"current":4791021,"total":4964709},"progress":"[================================================\u003e ] 4.791MB/4.965MB","id":"90aca3c647fe"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"90aca3c647fe"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"90aca3c647fe"}
|
||||
{"status":"Downloading","progressDetail":{"current":12315332,"total":27504647},"progress":"[======================\u003e ] 12.32MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":42990315,"total":88111129},"progress":"[========================\u003e ] 42.99MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":13155012,"total":27504647},"progress":"[=======================\u003e ] 13.16MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":43530987,"total":88111129},"progress":"[========================\u003e ] 43.53MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":13990596,"total":27504647},"progress":"[=========================\u003e ] 13.99MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":44063467,"total":88111129},"progress":"[=========================\u003e ] 44.06MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":15112900,"total":27504647},"progress":"[===========================\u003e ] 15.11MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":45132523,"total":88111129},"progress":"[=========================\u003e ] 45.13MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":16235204,"total":27504647},"progress":"[=============================\u003e ] 16.24MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":52418,"total":5149051},"progress":"[\u003e ] 52.42kB/5.149MB","id":"1dd62f37c84c"}
|
||||
{"status":"Downloading","progressDetail":{"current":1195147,"total":5149051},"progress":"[===========\u003e ] 1.195MB/5.149MB","id":"1dd62f37c84c"}
|
||||
{"status":"Downloading","progressDetail":{"current":16792260,"total":27504647},"progress":"[==============================\u003e ] 16.79MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":45673195,"total":88111129},"progress":"[=========================\u003e ] 45.67MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2702475,"total":5149051},"progress":"[==========================\u003e ] 2.702MB/5.149MB","id":"1dd62f37c84c"}
|
||||
{"status":"Downloading","progressDetail":{"current":4078320,"total":5149051},"progress":"[=======================================\u003e ] 4.078MB/5.149MB","id":"1dd62f37c84c"}
|
||||
{"status":"Downloading","progressDetail":{"current":17349316,"total":27504647},"progress":"[===============================\u003e ] 17.35MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"1dd62f37c84c"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"1dd62f37c84c"}
|
||||
{"status":"Downloading","progressDetail":{"current":46213867,"total":88111129},"progress":"[==========================\u003e ] 46.21MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":17918660,"total":27504647},"progress":"[================================\u003e ] 17.92MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":19040964,"total":27504647},"progress":"[==================================\u003e ] 19.04MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":47295211,"total":88111129},"progress":"[==========================\u003e ] 47.3MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":20183748,"total":27504647},"progress":"[====================================\u003e ] 20.18MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":48368363,"total":88111129},"progress":"[===========================\u003e ] 48.37MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":21301956,"total":27504647},"progress":"[======================================\u003e ] 21.3MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":22432452,"total":27504647},"progress":"[========================================\u003e ] 22.43MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":38884,"total":3855277},"progress":"[\u003e ] 38.88kB/3.855MB","id":"3192b2fa42db"}
|
||||
{"status":"Downloading","progressDetail":{"current":49445611,"total":88111129},"progress":"[============================\u003e ] 49.45MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":977632,"total":3855277},"progress":"[============\u003e ] 977.6kB/3.855MB","id":"3192b2fa42db"}
|
||||
{"status":"Downloading","progressDetail":{"current":23268036,"total":27504647},"progress":"[==========================================\u003e ] 23.27MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":49986283,"total":88111129},"progress":"[============================\u003e ] 49.99MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1895136,"total":3855277},"progress":"[========================\u003e ] 1.895MB/3.855MB","id":"3192b2fa42db"}
|
||||
{"status":"Downloading","progressDetail":{"current":23833284,"total":27504647},"progress":"[===========================================\u003e ] 23.83MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":2939616,"total":3855277},"progress":"[======================================\u003e ] 2.94MB/3.855MB","id":"3192b2fa42db"}
|
||||
{"status":"Downloading","progressDetail":{"current":24390340,"total":27504647},"progress":"[============================================\u003e ] 24.39MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"3192b2fa42db"}
|
||||
{"status":"Downloading","progressDetail":{"current":50518763,"total":88111129},"progress":"[============================\u003e ] 50.52MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":24947396,"total":27504647},"progress":"[=============================================\u003e ] 24.95MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":51059435,"total":88111129},"progress":"[============================\u003e ] 51.06MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":25803460,"total":27504647},"progress":"[==============================================\u003e ] 25.8MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":26942148,"total":27504647},"progress":"[================================================\u003e ] 26.94MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":52140779,"total":88111129},"progress":"[=============================\u003e ] 52.14MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":27504647,"total":27504647},"progress":"[==================================================\u003e] 27.5MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"45b746196f82"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"45b746196f82"}
|
||||
{"status":"Downloading","progressDetail":{"current":53222123,"total":88111129},"progress":"[==============================\u003e ] 53.22MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":51194,"total":4983195},"progress":"[\u003e ] 51.19kB/4.983MB","id":"ae190b8f66a7"}
|
||||
{"status":"Downloading","progressDetail":{"current":54299371,"total":88111129},"progress":"[==============================\u003e ] 54.3MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1268464,"total":4983195},"progress":"[============\u003e ] 1.268MB/4.983MB","id":"ae190b8f66a7"}
|
||||
{"status":"Downloading","progressDetail":{"current":54827755,"total":88111129},"progress":"[===============================\u003e ] 54.83MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2767600,"total":4983195},"progress":"[===========================\u003e ] 2.768MB/4.983MB","id":"ae190b8f66a7"}
|
||||
{"status":"Downloading","progressDetail":{"current":4528880,"total":4983195},"progress":"[=============================================\u003e ] 4.529MB/4.983MB","id":"ae190b8f66a7"}
|
||||
{"status":"Downloading","progressDetail":{"current":55368427,"total":88111129},"progress":"[===============================\u003e ] 55.37MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"ae190b8f66a7"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"ae190b8f66a7"}
|
||||
{"status":"Downloading","progressDetail":{"current":63614,"total":6103207},"progress":"[\u003e ] 63.61kB/6.103MB","id":"97bb6e138460"}
|
||||
{"status":"Downloading","progressDetail":{"current":56449771,"total":88111129},"progress":"[================================\u003e ] 56.45MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1530606,"total":6103207},"progress":"[============\u003e ] 1.531MB/6.103MB","id":"97bb6e138460"}
|
||||
{"status":"Downloading","progressDetail":{"current":3193582,"total":6103207},"progress":"[==========================\u003e ] 3.194MB/6.103MB","id":"97bb6e138460"}
|
||||
{"status":"Downloading","progressDetail":{"current":56990443,"total":88111129},"progress":"[================================\u003e ] 56.99MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":4786926,"total":6103207},"progress":"[=======================================\u003e ] 4.787MB/6.103MB","id":"97bb6e138460"}
|
||||
{"status":"Downloading","progressDetail":{"current":57531115,"total":88111129},"progress":"[================================\u003e ] 57.53MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"97bb6e138460"}
|
||||
{"status":"Downloading","progressDetail":{"current":489,"total":787},"progress":"[===============================\u003e ] 489B/787B","id":"2edb982d5170"}
|
||||
{"status":"Downloading","progressDetail":{"current":58612459,"total":88111129},"progress":"[=================================\u003e ] 58.61MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":787,"total":787},"progress":"[==================================================\u003e] 787B/787B","id":"2edb982d5170"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"2edb982d5170"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"2edb982d5170"}
|
||||
{"status":"Downloading","progressDetail":{"current":60213995,"total":88111129},"progress":"[==================================\u003e ] 60.21MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":61827819,"total":88111129},"progress":"[===================================\u003e ] 61.83MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":63449835,"total":88111129},"progress":"[====================================\u003e ] 63.45MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":65071851,"total":88111129},"progress":"[====================================\u003e ] 65.07MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":49803,"total":4894860},"progress":"[\u003e ] 49.8kB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Downloading","progressDetail":{"current":49681,"total":4953791},"progress":"[\u003e ] 49.68kB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Downloading","progressDetail":{"current":912099,"total":4894860},"progress":"[=========\u003e ] 912.1kB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Downloading","progressDetail":{"current":66145003,"total":88111129},"progress":"[=====================================\u003e ] 66.15MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":748270,"total":4953791},"progress":"[=======\u003e ] 748.3kB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Downloading","progressDetail":{"current":1702627,"total":4894860},"progress":"[=================\u003e ] 1.703MB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Downloading","progressDetail":{"current":67205867,"total":88111129},"progress":"[======================================\u003e ] 67.21MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1678062,"total":4953791},"progress":"[================\u003e ] 1.678MB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Downloading","progressDetail":{"current":2194147,"total":4894860},"progress":"[======================\u003e ] 2.194MB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Downloading","progressDetail":{"current":67746539,"total":88111129},"progress":"[======================================\u003e ] 67.75MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2648814,"total":4953791},"progress":"[==========================\u003e ] 2.649MB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Downloading","progressDetail":{"current":2743011,"total":4894860},"progress":"[============================\u003e ] 2.743MB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Downloading","progressDetail":{"current":68287211,"total":88111129},"progress":"[======================================\u003e ] 68.29MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3697390,"total":4953791},"progress":"[=====================================\u003e ] 3.697MB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Downloading","progressDetail":{"current":3381987,"total":4894860},"progress":"[==================================\u003e ] 3.382MB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Downloading","progressDetail":{"current":4774638,"total":4953791},"progress":"[================================================\u003e ] 4.775MB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Downloading","progressDetail":{"current":68827883,"total":88111129},"progress":"[=======================================\u003e ] 68.83MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":4953791,"total":4953791},"progress":"[==================================================\u003e] 4.954MB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"0df6fd234b59"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"0df6fd234b59"}
|
||||
{"status":"Downloading","progressDetail":{"current":4004579,"total":4894860},"progress":"[========================================\u003e ] 4.005MB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Downloading","progressDetail":{"current":4893411,"total":4894860},"progress":"[=================================================\u003e ] 4.893MB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"7ddc8e6d6da9"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"7ddc8e6d6da9"}
|
||||
{"status":"Downloading","progressDetail":{"current":69909227,"total":88111129},"progress":"[=======================================\u003e ] 69.91MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":71527147,"total":88111129},"progress":"[========================================\u003e ] 71.53MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":73149163,"total":88111129},"progress":"[=========================================\u003e ] 73.15MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":74771179,"total":88111129},"progress":"[==========================================\u003e ] 74.77MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":63573,"total":6137526},"progress":"[\u003e ] 63.57kB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Downloading","progressDetail":{"current":75311851,"total":88111129},"progress":"[==========================================\u003e ] 75.31MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1317559,"total":6137526},"progress":"[==========\u003e ] 1.318MB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Downloading","progressDetail":{"current":2710199,"total":6137526},"progress":"[======================\u003e ] 2.71MB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Downloading","progressDetail":{"current":38729,"total":3854415},"progress":"[\u003e ] 38.73kB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Downloading","progressDetail":{"current":76368619,"total":88111129},"progress":"[===========================================\u003e ] 76.37MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3783351,"total":6137526},"progress":"[==============================\u003e ] 3.783MB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Downloading","progressDetail":{"current":658157,"total":3854415},"progress":"[========\u003e ] 658.2kB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Downloading","progressDetail":{"current":4520631,"total":6137526},"progress":"[====================================\u003e ] 4.521MB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Downloading","progressDetail":{"current":1350381,"total":3854415},"progress":"[=================\u003e ] 1.35MB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Downloading","progressDetail":{"current":5364407,"total":6137526},"progress":"[===========================================\u003e ] 5.364MB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Downloading","progressDetail":{"current":77445867,"total":88111129},"progress":"[===========================================\u003e ] 77.45MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2153197,"total":3854415},"progress":"[===========================\u003e ] 2.153MB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"8fc1ba8efe21"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"8fc1ba8efe21"}
|
||||
{"status":"Downloading","progressDetail":{"current":77986539,"total":88111129},"progress":"[============================================\u003e ] 77.99MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3021549,"total":3854415},"progress":"[=======================================\u003e ] 3.022MB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"1f6f45e783b5"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"1f6f45e783b5"}
|
||||
{"status":"Downloading","progressDetail":{"current":79067883,"total":88111129},"progress":"[============================================\u003e ] 79.07MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":80149227,"total":88111129},"progress":"[=============================================\u003e ] 80.15MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":81767147,"total":88111129},"progress":"[==============================================\u003e ] 81.77MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":52419,"total":5222290},"progress":"[\u003e ] 52.42kB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Downloading","progressDetail":{"current":1055455,"total":5222290},"progress":"[==========\u003e ] 1.055MB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Downloading","progressDetail":{"current":83372779,"total":88111129},"progress":"[===============================================\u003e ] 83.37MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2333407,"total":5222290},"progress":"[======================\u003e ] 2.333MB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Downloading","progressDetail":{"current":35991,"total":3564359},"progress":"[\u003e ] 35.99kB/3.564MB","id":"b8cf53bbc6ba"}
|
||||
{"status":"Downloading","progressDetail":{"current":84454123,"total":88111129},"progress":"[===============================================\u003e ] 84.45MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3300063,"total":5222290},"progress":"[===============================\u003e ] 3.3MB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Downloading","progressDetail":{"current":752366,"total":3564359},"progress":"[==========\u003e ] 752.4kB/3.564MB","id":"b8cf53bbc6ba"}
|
||||
{"status":"Downloading","progressDetail":{"current":3979999,"total":5222290},"progress":"[======================================\u003e ] 3.98MB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Downloading","progressDetail":{"current":1743598,"total":3564359},"progress":"[========================\u003e ] 1.744MB/3.564MB","id":"b8cf53bbc6ba"}
|
||||
{"status":"Downloading","progressDetail":{"current":85527275,"total":88111129},"progress":"[================================================\u003e ] 85.53MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":4537055,"total":5222290},"progress":"[===========================================\u003e ] 4.537MB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Downloading","progressDetail":{"current":2833134,"total":3564359},"progress":"[=======================================\u003e ] 2.833MB/3.564MB","id":"b8cf53bbc6ba"}
|
||||
{"status":"Downloading","progressDetail":{"current":5077727,"total":5222290},"progress":"[================================================\u003e ] 5.078MB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"b8cf53bbc6ba"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"b8cf53bbc6ba"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"43ea61082f68"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"43ea61082f68"}
|
||||
{"status":"Downloading","progressDetail":{"current":86067947,"total":88111129},"progress":"[================================================\u003e ] 86.07MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":87132907,"total":88111129},"progress":"[=================================================\u003e ] 87.13MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"4ab897fa6fbf"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":557056,"total":88111129},"progress":"[\u003e ] 557.1kB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":52418,"total":5120108},"progress":"[\u003e ] 52.42kB/5.12MB","id":"1c3245356213"}
|
||||
{"status":"Downloading","progressDetail":{"current":489,"total":790},"progress":"[==============================\u003e ] 489B/790B","id":"25efb07e4521"}
|
||||
{"status":"Extracting","progressDetail":{"current":5013504,"total":88111129},"progress":"[==\u003e ] 5.014MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":790,"total":790},"progress":"[==================================================\u003e] 790B/790B","id":"25efb07e4521"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"25efb07e4521"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"25efb07e4521"}
|
||||
{"status":"Downloading","progressDetail":{"current":1764079,"total":5120108},"progress":"[=================\u003e ] 1.764MB/5.12MB","id":"1c3245356213"}
|
||||
{"status":"Extracting","progressDetail":{"current":8355840,"total":88111129},"progress":"[====\u003e ] 8.356MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3635951,"total":5120108},"progress":"[===================================\u003e ] 3.636MB/5.12MB","id":"1c3245356213"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"1c3245356213"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"1c3245356213"}
|
||||
{"status":"Extracting","progressDetail":{"current":11141120,"total":88111129},"progress":"[======\u003e ] 11.14MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":52419,"total":5117023},"progress":"[\u003e ] 52.42kB/5.117MB","id":"61ebb123c1eb"}
|
||||
{"status":"Extracting","progressDetail":{"current":13369344,"total":88111129},"progress":"[=======\u003e ] 13.37MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1596142,"total":5117023},"progress":"[===============\u003e ] 1.596MB/5.117MB","id":"61ebb123c1eb"}
|
||||
{"status":"Extracting","progressDetail":{"current":13926400,"total":88111129},"progress":"[=======\u003e ] 13.93MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3242734,"total":5117023},"progress":"[===============================\u003e ] 3.243MB/5.117MB","id":"61ebb123c1eb"}
|
||||
{"status":"Downloading","progressDetail":{"current":55157,"total":5384215},"progress":"[\u003e ] 55.16kB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Downloading","progressDetail":{"current":4635374,"total":5117023},"progress":"[=============================================\u003e ] 4.635MB/5.117MB","id":"61ebb123c1eb"}
|
||||
{"status":"Extracting","progressDetail":{"current":15040512,"total":88111129},"progress":"[========\u003e ] 15.04MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"61ebb123c1eb"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"61ebb123c1eb"}
|
||||
{"status":"Downloading","progressDetail":{"current":989937,"total":5384215},"progress":"[=========\u003e ] 989.9kB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Extracting","progressDetail":{"current":15597568,"total":88111129},"progress":"[========\u003e ] 15.6MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2558705,"total":5384215},"progress":"[=======================\u003e ] 2.559MB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Extracting","progressDetail":{"current":18382848,"total":88111129},"progress":"[==========\u003e ] 18.38MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":4311793,"total":5384215},"progress":"[========================================\u003e ] 4.312MB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Downloading","progressDetail":{"current":53788,"total":5252487},"progress":"[\u003e ] 53.79kB/5.252MB","id":"87f7843f43cd"}
|
||||
{"status":"Extracting","progressDetail":{"current":22839296,"total":88111129},"progress":"[============\u003e ] 22.84MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":5212913,"total":5384215},"progress":"[================================================\u003e ] 5.213MB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Downloading","progressDetail":{"current":846577,"total":5252487},"progress":"[========\u003e ] 846.6kB/5.252MB","id":"87f7843f43cd"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"0964b769d2c9"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"0964b769d2c9"}
|
||||
{"status":"Extracting","progressDetail":{"current":26181632,"total":88111129},"progress":"[==============\u003e ] 26.18MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":2628337,"total":5252487},"progress":"[=========================\u003e ] 2.628MB/5.252MB","id":"87f7843f43cd"}
|
||||
{"status":"Extracting","progressDetail":{"current":30638080,"total":88111129},"progress":"[=================\u003e ] 30.64MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":4340465,"total":5252487},"progress":"[=========================================\u003e ] 4.34MB/5.252MB","id":"87f7843f43cd"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"87f7843f43cd"}
|
||||
{"status":"Extracting","progressDetail":{"current":33423360,"total":88111129},"progress":"[==================\u003e ] 33.42MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":51204,"total":5015856},"progress":"[\u003e ] 51.2kB/5.016MB","id":"a89dbf94d794"}
|
||||
{"status":"Extracting","progressDetail":{"current":36208640,"total":88111129},"progress":"[====================\u003e ] 36.21MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1624816,"total":5015856},"progress":"[================\u003e ] 1.625MB/5.016MB","id":"a89dbf94d794"}
|
||||
{"status":"Extracting","progressDetail":{"current":38436864,"total":88111129},"progress":"[=====================\u003e ] 38.44MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3373808,"total":5015856},"progress":"[=================================\u003e ] 3.374MB/5.016MB","id":"a89dbf94d794"}
|
||||
{"status":"Extracting","progressDetail":{"current":40665088,"total":88111129},"progress":"[=======================\u003e ] 40.67MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":53910,"total":5310566},"progress":"[\u003e ] 53.91kB/5.311MB","id":"f0d43ddca77f"}
|
||||
{"status":"Downloading","progressDetail":{"current":4905712,"total":5015856},"progress":"[================================================\u003e ] 4.906MB/5.016MB","id":"a89dbf94d794"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"a89dbf94d794"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"a89dbf94d794"}
|
||||
{"status":"Downloading","progressDetail":{"current":1313521,"total":5310566},"progress":"[============\u003e ] 1.314MB/5.311MB","id":"f0d43ddca77f"}
|
||||
{"status":"Extracting","progressDetail":{"current":44007424,"total":88111129},"progress":"[========================\u003e ] 44.01MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":46792704,"total":88111129},"progress":"[==========================\u003e ] 46.79MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3082993,"total":5310566},"progress":"[=============================\u003e ] 3.083MB/5.311MB","id":"f0d43ddca77f"}
|
||||
{"status":"Downloading","progressDetail":{"current":49836,"total":4915049},"progress":"[\u003e ] 49.84kB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Downloading","progressDetail":{"current":4373233,"total":5310566},"progress":"[=========================================\u003e ] 4.373MB/5.311MB","id":"f0d43ddca77f"}
|
||||
{"status":"Extracting","progressDetail":{"current":48463872,"total":88111129},"progress":"[===========================\u003e ] 48.46MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":711407,"total":4915049},"progress":"[=======\u003e ] 711.4kB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"f0d43ddca77f"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"f0d43ddca77f"}
|
||||
{"status":"Downloading","progressDetail":{"current":1710831,"total":4915049},"progress":"[=================\u003e ] 1.711MB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Extracting","progressDetail":{"current":52363264,"total":88111129},"progress":"[=============================\u003e ] 52.36MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":3504879,"total":4915049},"progress":"[===================================\u003e ] 3.505MB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Extracting","progressDetail":{"current":55705600,"total":88111129},"progress":"[===============================\u003e ] 55.71MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":4905711,"total":4915049},"progress":"[=================================================\u003e ] 4.906MB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"7c674f0cb40c"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"7c674f0cb40c"}
|
||||
{"status":"Extracting","progressDetail":{"current":58490880,"total":88111129},"progress":"[=================================\u003e ] 58.49MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":52419,"total":5119213},"progress":"[\u003e ] 52.42kB/5.119MB","id":"b48a885b52bc"}
|
||||
{"status":"Extracting","progressDetail":{"current":61276160,"total":88111129},"progress":"[==================================\u003e ] 61.28MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1333999,"total":5119213},"progress":"[=============\u003e ] 1.334MB/5.119MB","id":"b48a885b52bc"}
|
||||
{"status":"Downloading","progressDetail":{"current":2657007,"total":5119213},"progress":"[=========================\u003e ] 2.657MB/5.119MB","id":"b48a885b52bc"}
|
||||
{"status":"Extracting","progressDetail":{"current":64061440,"total":88111129},"progress":"[====================================\u003e ] 64.06MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"272cdf839cbb"}
|
||||
{"status":"Downloading","progressDetail":{"current":4344559,"total":5119213},"progress":"[==========================================\u003e ] 4.345MB/5.119MB","id":"b48a885b52bc"}
|
||||
{"status":"Extracting","progressDetail":{"current":66289664,"total":88111129},"progress":"[=====================================\u003e ] 66.29MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"b48a885b52bc"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"b48a885b52bc"}
|
||||
{"status":"Extracting","progressDetail":{"current":70746112,"total":88111129},"progress":"[========================================\u003e ] 70.75MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":73531392,"total":88111129},"progress":"[=========================================\u003e ] 73.53MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":77430784,"total":88111129},"progress":"[===========================================\u003e ] 77.43MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"50d054c97f4f"}
|
||||
{"status":"Downloading","progressDetail":{"current":488,"total":1069},"progress":"[======================\u003e ] 488B/1.069kB","id":"4c6bbd90b64d"}
|
||||
{"status":"Extracting","progressDetail":{"current":80216064,"total":88111129},"progress":"[=============================================\u003e ] 80.22MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Downloading","progressDetail":{"current":1069,"total":1069},"progress":"[==================================================\u003e] 1.069kB/1.069kB","id":"4c6bbd90b64d"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"4c6bbd90b64d"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"4c6bbd90b64d"}
|
||||
{"status":"Downloading","progressDetail":{"current":32,"total":32},"progress":"[==================================================\u003e] 32B/32B","id":"4f4fb700ef54"}
|
||||
{"status":"Verifying Checksum","progressDetail":{},"id":"4f4fb700ef54"}
|
||||
{"status":"Download complete","progressDetail":{},"id":"4f4fb700ef54"}
|
||||
{"status":"Extracting","progressDetail":{"current":81887232,"total":88111129},"progress":"[==============================================\u003e ] 81.89MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":83558400,"total":88111129},"progress":"[===============================================\u003e ] 83.56MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":85229568,"total":88111129},"progress":"[================================================\u003e ] 85.23MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":86900736,"total":88111129},"progress":"[=================================================\u003e ] 86.9MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":88014848,"total":88111129},"progress":"[=================================================\u003e ] 88.01MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":88111129,"total":88111129},"progress":"[==================================================\u003e] 88.11MB/88.11MB","id":"4ab897fa6fbf"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"4ab897fa6fbf"}
|
||||
{"status":"Extracting","progressDetail":{"current":32768,"total":1391657},"progress":"[=\u003e ] 32.77kB/1.392MB","id":"d837a2a1365e"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":1391657},"progress":"[===========\u003e ] 327.7kB/1.392MB","id":"d837a2a1365e"}
|
||||
{"status":"Extracting","progressDetail":{"current":1391657,"total":1391657},"progress":"[==================================================\u003e] 1.392MB/1.392MB","id":"d837a2a1365e"}
|
||||
{"status":"Extracting","progressDetail":{"current":1391657,"total":1391657},"progress":"[==================================================\u003e] 1.392MB/1.392MB","id":"d837a2a1365e"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"d837a2a1365e"}
|
||||
{"status":"Extracting","progressDetail":{"current":32768,"total":1328346},"progress":"[=\u003e ] 32.77kB/1.328MB","id":"988ae18fe41a"}
|
||||
{"status":"Extracting","progressDetail":{"current":753664,"total":1328346},"progress":"[============================\u003e ] 753.7kB/1.328MB","id":"988ae18fe41a"}
|
||||
{"status":"Extracting","progressDetail":{"current":1328346,"total":1328346},"progress":"[==================================================\u003e] 1.328MB/1.328MB","id":"988ae18fe41a"}
|
||||
{"status":"Extracting","progressDetail":{"current":1328346,"total":1328346},"progress":"[==================================================\u003e] 1.328MB/1.328MB","id":"988ae18fe41a"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"988ae18fe41a"}
|
||||
{"status":"Extracting","progressDetail":{"current":4478,"total":4478},"progress":"[==================================================\u003e] 4.478kB/4.478kB","id":"eeb8ef83b565"}
|
||||
{"status":"Extracting","progressDetail":{"current":4478,"total":4478},"progress":"[==================================================\u003e] 4.478kB/4.478kB","id":"eeb8ef83b565"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"eeb8ef83b565"}
|
||||
{"status":"Extracting","progressDetail":{"current":197,"total":197},"progress":"[==================================================\u003e] 197B/197B","id":"357fefdf9bc9"}
|
||||
{"status":"Extracting","progressDetail":{"current":197,"total":197},"progress":"[==================================================\u003e] 197B/197B","id":"357fefdf9bc9"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"357fefdf9bc9"}
|
||||
{"status":"Extracting","progressDetail":{"current":294912,"total":27504647},"progress":"[\u003e ] 294.9kB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":589824,"total":27504647},"progress":"[=\u003e ] 589.8kB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":5013504,"total":27504647},"progress":"[=========\u003e ] 5.014MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":9142272,"total":27504647},"progress":"[================\u003e ] 9.142MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":13565952,"total":27504647},"progress":"[========================\u003e ] 13.57MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":16515072,"total":27504647},"progress":"[==============================\u003e ] 16.52MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":18579456,"total":27504647},"progress":"[=================================\u003e ] 18.58MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":21528576,"total":27504647},"progress":"[=======================================\u003e ] 21.53MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":25657344,"total":27504647},"progress":"[==============================================\u003e ] 25.66MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":27504647,"total":27504647},"progress":"[==================================================\u003e] 27.5MB/27.5MB","id":"45b746196f82"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"45b746196f82"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5205016},"progress":"[\u003e ] 65.54kB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Extracting","progressDetail":{"current":1048576,"total":5205016},"progress":"[==========\u003e ] 1.049MB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Extracting","progressDetail":{"current":5205016,"total":5205016},"progress":"[==================================================\u003e] 5.205MB/5.205MB","id":"fbf4ce20f8c2"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"fbf4ce20f8c2"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":4964709},"progress":"[\u003e ] 65.54kB/4.965MB","id":"90aca3c647fe"}
|
||||
{"status":"Extracting","progressDetail":{"current":1245184,"total":4964709},"progress":"[============\u003e ] 1.245MB/4.965MB","id":"90aca3c647fe"}
|
||||
{"status":"Extracting","progressDetail":{"current":4964709,"total":4964709},"progress":"[==================================================\u003e] 4.965MB/4.965MB","id":"90aca3c647fe"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"90aca3c647fe"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5149051},"progress":"[\u003e ] 65.54kB/5.149MB","id":"1dd62f37c84c"}
|
||||
{"status":"Extracting","progressDetail":{"current":393216,"total":5149051},"progress":"[===\u003e ] 393.2kB/5.149MB","id":"1dd62f37c84c"}
|
||||
{"status":"Extracting","progressDetail":{"current":5149051,"total":5149051},"progress":"[==================================================\u003e] 5.149MB/5.149MB","id":"1dd62f37c84c"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"1dd62f37c84c"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":3855277},"progress":"[\u003e ] 65.54kB/3.855MB","id":"3192b2fa42db"}
|
||||
{"status":"Extracting","progressDetail":{"current":851968,"total":3855277},"progress":"[===========\u003e ] 852kB/3.855MB","id":"3192b2fa42db"}
|
||||
{"status":"Extracting","progressDetail":{"current":3855277,"total":3855277},"progress":"[==================================================\u003e] 3.855MB/3.855MB","id":"3192b2fa42db"}
|
||||
{"status":"Extracting","progressDetail":{"current":3855277,"total":3855277},"progress":"[==================================================\u003e] 3.855MB/3.855MB","id":"3192b2fa42db"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"3192b2fa42db"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":4983195},"progress":"[\u003e ] 65.54kB/4.983MB","id":"ae190b8f66a7"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":4983195},"progress":"[===\u003e ] 327.7kB/4.983MB","id":"ae190b8f66a7"}
|
||||
{"status":"Extracting","progressDetail":{"current":4980736,"total":4983195},"progress":"[=================================================\u003e ] 4.981MB/4.983MB","id":"ae190b8f66a7"}
|
||||
{"status":"Extracting","progressDetail":{"current":4983195,"total":4983195},"progress":"[==================================================\u003e] 4.983MB/4.983MB","id":"ae190b8f66a7"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"ae190b8f66a7"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":6103207},"progress":"[\u003e ] 65.54kB/6.103MB","id":"97bb6e138460"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":6103207},"progress":"[==\u003e ] 327.7kB/6.103MB","id":"97bb6e138460"}
|
||||
{"status":"Extracting","progressDetail":{"current":3670016,"total":6103207},"progress":"[==============================\u003e ] 3.67MB/6.103MB","id":"97bb6e138460"}
|
||||
{"status":"Extracting","progressDetail":{"current":6103207,"total":6103207},"progress":"[==================================================\u003e] 6.103MB/6.103MB","id":"97bb6e138460"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"97bb6e138460"}
|
||||
{"status":"Extracting","progressDetail":{"current":787,"total":787},"progress":"[==================================================\u003e] 787B/787B","id":"2edb982d5170"}
|
||||
{"status":"Extracting","progressDetail":{"current":787,"total":787},"progress":"[==================================================\u003e] 787B/787B","id":"2edb982d5170"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"2edb982d5170"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":4894860},"progress":"[\u003e ] 65.54kB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":4894860},"progress":"[===\u003e ] 327.7kB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Extracting","progressDetail":{"current":3735552,"total":4894860},"progress":"[======================================\u003e ] 3.736MB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Extracting","progressDetail":{"current":4894860,"total":4894860},"progress":"[==================================================\u003e] 4.895MB/4.895MB","id":"7ddc8e6d6da9"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"7ddc8e6d6da9"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":4953791},"progress":"[\u003e ] 65.54kB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":4953791},"progress":"[===\u003e ] 327.7kB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Extracting","progressDetail":{"current":4325376,"total":4953791},"progress":"[===========================================\u003e ] 4.325MB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Extracting","progressDetail":{"current":4953791,"total":4953791},"progress":"[==================================================\u003e] 4.954MB/4.954MB","id":"0df6fd234b59"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"0df6fd234b59"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":6137526},"progress":"[\u003e ] 65.54kB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":6137526},"progress":"[==\u003e ] 327.7kB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Extracting","progressDetail":{"current":3801088,"total":6137526},"progress":"[==============================\u003e ] 3.801MB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Extracting","progressDetail":{"current":6137526,"total":6137526},"progress":"[==================================================\u003e] 6.138MB/6.138MB","id":"8fc1ba8efe21"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"8fc1ba8efe21"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":3854415},"progress":"[\u003e ] 65.54kB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Extracting","progressDetail":{"current":851968,"total":3854415},"progress":"[===========\u003e ] 852kB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Extracting","progressDetail":{"current":3854415,"total":3854415},"progress":"[==================================================\u003e] 3.854MB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Extracting","progressDetail":{"current":3854415,"total":3854415},"progress":"[==================================================\u003e] 3.854MB/3.854MB","id":"1f6f45e783b5"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"1f6f45e783b5"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5222290},"progress":"[\u003e ] 65.54kB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Extracting","progressDetail":{"current":458752,"total":5222290},"progress":"[====\u003e ] 458.8kB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Extracting","progressDetail":{"current":4849664,"total":5222290},"progress":"[==============================================\u003e ] 4.85MB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Extracting","progressDetail":{"current":5222290,"total":5222290},"progress":"[==================================================\u003e] 5.222MB/5.222MB","id":"43ea61082f68"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"43ea61082f68"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":3564359},"progress":"[\u003e ] 65.54kB/3.564MB","id":"b8cf53bbc6ba"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":3564359},"progress":"[====\u003e ] 327.7kB/3.564MB","id":"b8cf53bbc6ba"}
|
||||
{"status":"Extracting","progressDetail":{"current":3564359,"total":3564359},"progress":"[==================================================\u003e] 3.564MB/3.564MB","id":"b8cf53bbc6ba"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"b8cf53bbc6ba"}
|
||||
{"status":"Extracting","progressDetail":{"current":790,"total":790},"progress":"[==================================================\u003e] 790B/790B","id":"25efb07e4521"}
|
||||
{"status":"Extracting","progressDetail":{"current":790,"total":790},"progress":"[==================================================\u003e] 790B/790B","id":"25efb07e4521"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"25efb07e4521"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5120108},"progress":"[\u003e ] 65.54kB/5.12MB","id":"1c3245356213"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":5120108},"progress":"[===\u003e ] 327.7kB/5.12MB","id":"1c3245356213"}
|
||||
{"status":"Extracting","progressDetail":{"current":5111808,"total":5120108},"progress":"[=================================================\u003e ] 5.112MB/5.12MB","id":"1c3245356213"}
|
||||
{"status":"Extracting","progressDetail":{"current":5120108,"total":5120108},"progress":"[==================================================\u003e] 5.12MB/5.12MB","id":"1c3245356213"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"1c3245356213"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5117023},"progress":"[\u003e ] 65.54kB/5.117MB","id":"61ebb123c1eb"}
|
||||
{"status":"Extracting","progressDetail":{"current":655360,"total":5117023},"progress":"[======\u003e ] 655.4kB/5.117MB","id":"61ebb123c1eb"}
|
||||
{"status":"Extracting","progressDetail":{"current":4259840,"total":5117023},"progress":"[=========================================\u003e ] 4.26MB/5.117MB","id":"61ebb123c1eb"}
|
||||
{"status":"Extracting","progressDetail":{"current":5117023,"total":5117023},"progress":"[==================================================\u003e] 5.117MB/5.117MB","id":"61ebb123c1eb"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"61ebb123c1eb"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5384215},"progress":"[\u003e ] 65.54kB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":5384215},"progress":"[===\u003e ] 327.7kB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Extracting","progressDetail":{"current":5177344,"total":5384215},"progress":"[================================================\u003e ] 5.177MB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Extracting","progressDetail":{"current":5384215,"total":5384215},"progress":"[==================================================\u003e] 5.384MB/5.384MB","id":"0964b769d2c9"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"0964b769d2c9"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5252487},"progress":"[\u003e ] 65.54kB/5.252MB","id":"87f7843f43cd"}
|
||||
{"status":"Extracting","progressDetail":{"current":655360,"total":5252487},"progress":"[======\u003e ] 655.4kB/5.252MB","id":"87f7843f43cd"}
|
||||
{"status":"Extracting","progressDetail":{"current":5252487,"total":5252487},"progress":"[==================================================\u003e] 5.252MB/5.252MB","id":"87f7843f43cd"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"87f7843f43cd"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5015856},"progress":"[\u003e ] 65.54kB/5.016MB","id":"a89dbf94d794"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":5015856},"progress":"[===\u003e ] 327.7kB/5.016MB","id":"a89dbf94d794"}
|
||||
{"status":"Extracting","progressDetail":{"current":3997696,"total":5015856},"progress":"[=======================================\u003e ] 3.998MB/5.016MB","id":"a89dbf94d794"}
|
||||
{"status":"Extracting","progressDetail":{"current":5015856,"total":5015856},"progress":"[==================================================\u003e] 5.016MB/5.016MB","id":"a89dbf94d794"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"a89dbf94d794"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5310566},"progress":"[\u003e ] 65.54kB/5.311MB","id":"f0d43ddca77f"}
|
||||
{"status":"Extracting","progressDetail":{"current":393216,"total":5310566},"progress":"[===\u003e ] 393.2kB/5.311MB","id":"f0d43ddca77f"}
|
||||
{"status":"Extracting","progressDetail":{"current":3407872,"total":5310566},"progress":"[================================\u003e ] 3.408MB/5.311MB","id":"f0d43ddca77f"}
|
||||
{"status":"Extracting","progressDetail":{"current":5310566,"total":5310566},"progress":"[==================================================\u003e] 5.311MB/5.311MB","id":"f0d43ddca77f"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"f0d43ddca77f"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":4915049},"progress":"[\u003e ] 65.54kB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Extracting","progressDetail":{"current":786432,"total":4915049},"progress":"[========\u003e ] 786.4kB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Extracting","progressDetail":{"current":4915049,"total":4915049},"progress":"[==================================================\u003e] 4.915MB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Extracting","progressDetail":{"current":4915049,"total":4915049},"progress":"[==================================================\u003e] 4.915MB/4.915MB","id":"7c674f0cb40c"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"7c674f0cb40c"}
|
||||
{"status":"Extracting","progressDetail":{"current":65536,"total":5119213},"progress":"[\u003e ] 65.54kB/5.119MB","id":"b48a885b52bc"}
|
||||
{"status":"Extracting","progressDetail":{"current":327680,"total":5119213},"progress":"[===\u003e ] 327.7kB/5.119MB","id":"b48a885b52bc"}
|
||||
{"status":"Extracting","progressDetail":{"current":4390912,"total":5119213},"progress":"[==========================================\u003e ] 4.391MB/5.119MB","id":"b48a885b52bc"}
|
||||
{"status":"Extracting","progressDetail":{"current":5119213,"total":5119213},"progress":"[==================================================\u003e] 5.119MB/5.119MB","id":"b48a885b52bc"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"b48a885b52bc"}
|
||||
{"status":"Extracting","progressDetail":{"current":395,"total":395},"progress":"[==================================================\u003e] 395B/395B","id":"272cdf839cbb"}
|
||||
{"status":"Extracting","progressDetail":{"current":395,"total":395},"progress":"[==================================================\u003e] 395B/395B","id":"272cdf839cbb"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"272cdf839cbb"}
|
||||
{"status":"Extracting","progressDetail":{"current":155,"total":155},"progress":"[==================================================\u003e] 155B/155B","id":"50d054c97f4f"}
|
||||
{"status":"Extracting","progressDetail":{"current":155,"total":155},"progress":"[==================================================\u003e] 155B/155B","id":"50d054c97f4f"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"50d054c97f4f"}
|
||||
{"status":"Extracting","progressDetail":{"current":1069,"total":1069},"progress":"[==================================================\u003e] 1.069kB/1.069kB","id":"4c6bbd90b64d"}
|
||||
{"status":"Extracting","progressDetail":{"current":1069,"total":1069},"progress":"[==================================================\u003e] 1.069kB/1.069kB","id":"4c6bbd90b64d"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"4c6bbd90b64d"}
|
||||
{"status":"Extracting","progressDetail":{"current":32,"total":32},"progress":"[==================================================\u003e] 32B/32B","id":"4f4fb700ef54"}
|
||||
{"status":"Extracting","progressDetail":{"current":32,"total":32},"progress":"[==================================================\u003e] 32B/32B","id":"4f4fb700ef54"}
|
||||
{"status":"Pull complete","progressDetail":{},"id":"4f4fb700ef54"}
|
||||
{"status":"Digest: sha256:4acb6bfd6c4f0cabaf7f3690e444afe51f1c7de54d51da7e63fac709c56f1c30"}
|
||||
{"status":"Status: Downloaded newer image for cloudfoundry/cnb:bionic"}
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"string": "stringvalue",
|
||||
"stringarray": [
|
||||
"a",
|
||||
"b"
|
||||
],
|
||||
"StartsWithUppercase": "value",
|
||||
"person": {
|
||||
"name": {
|
||||
"title": "dr",
|
||||
"first": "spring",
|
||||
"last": "boot"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user