Skip to content

Commit

Permalink
allow specifying images with localhost/
Browse files Browse the repository at this point in the history
  • Loading branch information
benniekiss committed Aug 15, 2024
1 parent 5ed88d2 commit 5011d97
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 17 deletions.
6 changes: 3 additions & 3 deletions dist/index.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/index.js.map

Large diffs are not rendered by default.

18 changes: 12 additions & 6 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import * as os from "os";
import * as path from "path";
import {
isStorageDriverOverlay, findFuseOverlayfsPath,
splitByNewline,
isFullImageName, getFullImageName,
splitByNewline, getFullImageName, isFullImageName,
getImageName, isRegistryLocalhost,
getFullDockerImageName,
} from "./util";
import { Inputs, Outputs } from "./generated/inputs-outputs";
Expand Down Expand Up @@ -86,12 +86,17 @@ async function run(): Promise<void> {
if (!registry) {
throw new Error(`Input "${Inputs.REGISTRY}" must be provided when using non full name tags`);
}
// special handling if image starts with localhost/
// this will target `localhost/image:tag` as the source, but push `registry/image:tag`
const isImageLocalhost = isRegistryLocalhost(normalizedImage);
const destinationImageName = isImageLocalhost ? getImageName(normalizedImage) : normalizedImage;

const registryWithoutTrailingSlash = registry.replace(/\/$/, "");
const registryPath = `${registryWithoutTrailingSlash}/${normalizedImage}`;
core.info(`Combining image name "${normalizedImage}" and registry "${registry}" `
const registryPath = `${registryWithoutTrailingSlash}/${destinationImageName}`;

core.info(`Combining image name "${destinationImageName}" and registry "${registry}" `
+ `to form registry path "${registryPath}"`);
if (normalizedImage.indexOf("/") > -1 && registry.indexOf("/") > -1) {
if (destinationImageName.indexOf("/") > -1 && registry.indexOf("/") > -1) {
core.warning(`"${registryPath}" does not seem to be a valid registry path. `
+ `The registry path should not contain more than 2 slashes. `
+ `Refer to the Inputs section of the readme for naming image and registry.`);
Expand Down Expand Up @@ -296,9 +301,10 @@ async function pullImageFromDocker(): Promise<ImageStorageCheckResult> {
const missingTags: string[] = [];
try {
for (const imageWithTag of sourceImages) {
const dockerImageName = getFullDockerImageName(imageWithTag);
const commandResult: ExecResult = await execute(
await getPodmanPath(),
[ ...dockerPodmanOpts, "pull", `docker-daemon:${imageWithTag}` ],
[ ...dockerPodmanOpts, "pull", `docker-daemon:${dockerImageName}` ],
{ ignoreReturnCode: true, failOnStdErr: false, group: true }
);
if (commandResult.exitCode === 0) {
Expand Down
70 changes: 63 additions & 7 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,73 @@ export function getFullImageName(image: string, tag: string): string {
return `${image}:${tag}`;
}

export function isNamespace(image: string): boolean {
return image.indexOf("/") > 0;
}

export function isRegistryDomain(image: string): boolean {
// naively checks if the registry is a domain
if (isNamespace(image)) {
const registry = image.split("/")[0];
return registry.indexOf(".") > 0 && !registry.endsWith(".");
}
return false;
}

export function isRegistryLocalhost(image: string): boolean {
if (isNamespace(image)) {
const registry = image.split("/")[0];
return registry === "localhost";
}
return false;
}

export function isNameFullyQualified(image: string): boolean {
if (isFullImageName(image)) {
return isRegistryDomain(image);
}
return false;
}

export function getImageName(image: string): string {
const imageParts = image.split("/");

switch (true) {
case (imageParts.length <= 2):
if (isRegistryLocalhost(image) || isRegistryDomain(image)) {
return imageParts.slice(1).join("/");
}
return image;
case (isRegistryLocalhost(image)):
return imageParts.slice(1).join("/");
case (isRegistryDomain(image)):
return imageParts.slice(2).join("/");
default:
return image;
}
}

const DOCKER_IO = `docker.io`;
const DOCKER_IO_NAMESPACED = DOCKER_IO + `/library`;

export function getFullDockerImageName(image: string): string {
switch (image.split("/").length) {
case 1:
return `${DOCKER_IO_NAMESPACED}/${image}`;
case 2:
if (image.includes("amazonaws.com")) return image;
return `${DOCKER_IO}/${image}`;
// docker does not store images with localhost/
// so we get the base image name if it is prepended with localhost/
const sanitizedImageName = isRegistryLocalhost(image) ? getImageName(image) : image;
const imagePartsLength = sanitizedImageName.split("/").length;

switch (true) {
case (isNameFullyQualified(sanitizedImageName)):
// if the docker image is in the form of `registry/image:tag`,
// then it is pulled to podman as the same name
return sanitizedImageName;
case (imagePartsLength === 1):
// if image is in the form of `image:tag`,
// podman pulls it as `docker.io/library/image:tag`
return `${DOCKER_IO_NAMESPACED}/${sanitizedImageName}`;
default:
return image;
// otherwise, if the image is in the form of `namespace/image:tag`,
// podman pulls it as `docker.io/namespace/image:tag`
return `${DOCKER_IO}/${sanitizedImageName}`;
}
}

0 comments on commit 5011d97

Please sign in to comment.