Skip to content

Commit

Permalink
Allow to start containers with raw image IDs (#663)
Browse files Browse the repository at this point in the history
  • Loading branch information
gzm0 authored Nov 23, 2023
1 parent c1953f5 commit 40cd6f6
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 0 deletions.
44 changes: 44 additions & 0 deletions packages/testcontainers/src/container-runtime/image-name.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,29 @@ describe("ContainerImage", () => {
const imageName = new ImageName("registry", "image", "sha256:1234abcd1234abcd1234abcd1234abcd");
expect(imageName.string).toBe("registry/image@sha256:1234abcd1234abcd1234abcd1234abcd");
});

it("should not append the `latest` tag to image IDs", () => {
const imageName = new ImageName(
undefined,
"aa285b773a2c042056883845aea893a743d358a5d40f61734fa228fde93dae6f",
"latest"
);
expect(imageName.string).toBe("aa285b773a2c042056883845aea893a743d358a5d40f61734fa228fde93dae6f");
});

it("should keep other tags (not `latest`) on image IDs", () => {
// Note that the resulting image ID will not be accepted by Docker:
//
// > "invalid repository name [...], cannot specify 64-byte hexadecimal strings"
//
// However, not treating tags other than `latests` specially is probably less surprising.
const imageName = new ImageName(
undefined,
"aa285b773a2c042056883845aea893a743d358a5d40f61734fa228fde93dae6f",
"1"
);
expect(imageName.string).toBe("aa285b773a2c042056883845aea893a743d358a5d40f61734fa228fde93dae6f:1");
});
});

describe("fromString", () => {
Expand Down Expand Up @@ -96,5 +119,26 @@ describe("ContainerImage", () => {
expect(imageName.image).toBe("image");
expect(imageName.tag).toBe("sha256:1234abcd1234abcd1234abcd1234abcd");
});

it("should work with image being an image ID", () => {
const imageName = ImageName.fromString("aa285b773a2c042056883845aea893a743d358a5d40f61734fa228fde93dae6f");

expect(imageName.registry).toBe(undefined);
expect(imageName.image).toBe("aa285b773a2c042056883845aea893a743d358a5d40f61734fa228fde93dae6f");
expect(imageName.tag).toBe("latest");
});

it("should work with image being an image ID and an explicit tag", () => {
// Note: Such an ID will not be accepted by docker:
//
// > "invalid repository name [...], cannot specify 64-byte hexadecimal strings"
//
// However, parsing it this way is probably least surprising.
const imageName = ImageName.fromString("aa285b773a2c042056883845aea893a743d358a5d40f61734fa228fde93dae6f:1");

expect(imageName.registry).toBe(undefined);
expect(imageName.image).toBe("aa285b773a2c042056883845aea893a743d358a5d40f61734fa228fde93dae6f");
expect(imageName.tag).toBe("1");
});
});
});
10 changes: 10 additions & 0 deletions packages/testcontainers/src/container-runtime/image-name.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
export class ImageName {
public readonly string: string;

private static readonly hexRE = /^[0-9a-f]{64}$/i;

constructor(
public readonly registry: string | undefined,
public readonly image: string,
Expand All @@ -12,6 +14,14 @@ export class ImageName {
} else {
this.string = `${this.registry}/${this.image}:${this.tag}`;
}
} else if (this.tag === "latest" && ImageName.hexRE.test(this.image)) {
// 64 byte hex string. This refers to an image sha256 directly.
// Do not put the tag as the docker does not accept it.
// It will fail with:
//
// invalid repository name (<image>), cannot specify 64-byte hexadecimal strings.
//
this.string = this.image;
} else if (this.tag.startsWith("sha256:")) {
this.string = `${this.image}@${this.tag}`;
} else {
Expand Down

0 comments on commit 40cd6f6

Please sign in to comment.