Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to start containers with raw image IDs #663

Merged
merged 2 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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", () => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similarly to should keep other tags (not latest) on image IDs, do we need a fromString test where the input has a non-latest tag (aa285b773a2c042056883845aea893a743d358a5d40f61734fa228fde93dae6f:1)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's probably a good idea. I've added a commit with a test (and also added the docker error message to the text explaining that it won't accept the reference).

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