mirror of
https://github.com/redhat-actions/push-to-registry.git
synced 2025-02-23 10:31:22 +01:00
Use --root to when pulling from docker
This commit is contained in:
parent
6b269c55d3
commit
d6ba509bbd
4 changed files with 50 additions and 39 deletions
2
dist/index.js
vendored
2
dist/index.js
vendored
File diff suppressed because one or more lines are too long
2
dist/index.js.map
vendored
2
dist/index.js.map
vendored
File diff suppressed because one or more lines are too long
71
src/index.ts
71
src/index.ts
|
@ -2,8 +2,13 @@ import * as core from "@actions/core";
|
||||||
import * as exec from "@actions/exec";
|
import * as exec from "@actions/exec";
|
||||||
import * as io from "@actions/io";
|
import * as io from "@actions/io";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
|
import * as os from "os";
|
||||||
import * as path from "path";
|
import * as path from "path";
|
||||||
import { splitByNewline, isFullImageName, getFullImageName } from "./util";
|
import {
|
||||||
|
splitByNewline,
|
||||||
|
isFullImageName, getFullImageName,
|
||||||
|
getFullDockerImageName,
|
||||||
|
} from "./util";
|
||||||
import { Inputs, Outputs } from "./generated/inputs-outputs";
|
import { Inputs, Outputs } from "./generated/inputs-outputs";
|
||||||
|
|
||||||
interface ExecResult {
|
interface ExecResult {
|
||||||
|
@ -23,7 +28,7 @@ let podmanPath: string | undefined;
|
||||||
let isImageFromDocker = false;
|
let isImageFromDocker = false;
|
||||||
let sourceImages: string[];
|
let sourceImages: string[];
|
||||||
let destinationImages: string[];
|
let destinationImages: string[];
|
||||||
let dockerBaseUrl: string;
|
let dockerPodmanRoot: string;
|
||||||
|
|
||||||
async function getPodmanPath(): Promise<string> {
|
async function getPodmanPath(): Promise<string> {
|
||||||
if (podmanPath == null) {
|
if (podmanPath == null) {
|
||||||
|
@ -34,10 +39,6 @@ async function getPodmanPath(): Promise<string> {
|
||||||
return podmanPath;
|
return podmanPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
// base URL that gets appended if image is pulled from the Docker imaege storage
|
|
||||||
const DOCKER_IO = `docker.io`;
|
|
||||||
const DOCKER_IO_NAMESPACED = DOCKER_IO + `/library`;
|
|
||||||
|
|
||||||
async function run(): Promise<void> {
|
async function run(): Promise<void> {
|
||||||
const DEFAULT_TAG = "latest";
|
const DEFAULT_TAG = "latest";
|
||||||
const imageInput = core.getInput(Inputs.IMAGE);
|
const imageInput = core.getInput(Inputs.IMAGE);
|
||||||
|
@ -45,9 +46,6 @@ async function run(): Promise<void> {
|
||||||
// split tags
|
// split tags
|
||||||
const tagsList = tags.trim().split(/\s+/);
|
const tagsList = tags.trim().split(/\s+/);
|
||||||
|
|
||||||
// handle the case when image name is 'namespace/imagename' and image is present in docker storage
|
|
||||||
dockerBaseUrl = imageInput.indexOf("/") > -1 ? DOCKER_IO : DOCKER_IO_NAMESPACED;
|
|
||||||
|
|
||||||
// info message if user doesn't provides any tag
|
// info message if user doesn't provides any tag
|
||||||
if (tagsList.length === 0) {
|
if (tagsList.length === 0) {
|
||||||
core.info(`Input "${Inputs.TAGS}" is not provided, using default tag "${DEFAULT_TAG}"`);
|
core.info(`Input "${Inputs.TAGS}" is not provided, using default tag "${DEFAULT_TAG}"`);
|
||||||
|
@ -157,9 +155,6 @@ async function run(): Promise<void> {
|
||||||
+ `than the version in the Podman image storage. The image(s) from the Docker image storage `
|
+ `than the version in the Podman image storage. The image(s) from the Docker image storage `
|
||||||
+ `will be pushed.`
|
+ `will be pushed.`
|
||||||
);
|
);
|
||||||
if (!isFullImageNameTag) {
|
|
||||||
sourceImages = sourceImages.map((image) => `${dockerBaseUrl}/${image}`);
|
|
||||||
}
|
|
||||||
isImageFromDocker = true;
|
isImageFromDocker = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -171,9 +166,6 @@ async function run(): Promise<void> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (allTagsinDocker) {
|
else if (allTagsinDocker) {
|
||||||
if (!isFullImageNameTag) {
|
|
||||||
sourceImages = sourceImages.map((image) => `${dockerBaseUrl}/${image}`);
|
|
||||||
}
|
|
||||||
core.info(
|
core.info(
|
||||||
`"${sourceImages[0]}" was found in the Docker image storage, but not in the Podman `
|
`"${sourceImages[0]}" was found in the Docker image storage, but not in the Podman `
|
||||||
+ `image storage. The image(s) will be pulled into Podman image storage, pushed, and then `
|
+ `image storage. The image(s) will be pulled into Podman image storage, pushed, and then `
|
||||||
|
@ -188,7 +180,7 @@ async function run(): Promise<void> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let pushMsg = `⏳ Pushing "${sourceImages[0]}" to ${destinationImages.map((image) => `"${image}"`).join(", ")}`;
|
let pushMsg = `⏳ Pushing "${sourceImages[0]}" to ${destinationImages.join(", ")}`;
|
||||||
if (username) {
|
if (username) {
|
||||||
pushMsg += ` as "${username}"`;
|
pushMsg += ` as "${username}"`;
|
||||||
}
|
}
|
||||||
|
@ -216,11 +208,12 @@ async function run(): Promise<void> {
|
||||||
// push the image
|
// push the image
|
||||||
for (const destinationImage of destinationImages) {
|
for (const destinationImage of destinationImages) {
|
||||||
const args = [
|
const args = [
|
||||||
|
...(isImageFromDocker ? [ "--root", dockerPodmanRoot ] : []),
|
||||||
"push",
|
"push",
|
||||||
"--quiet",
|
"--quiet",
|
||||||
"--digestfile",
|
"--digestfile",
|
||||||
digestFile,
|
digestFile,
|
||||||
sourceImages[0],
|
isImageFromDocker ? getFullDockerImageName(sourceImages[0]) : sourceImages[0],
|
||||||
destinationImage,
|
destinationImage,
|
||||||
];
|
];
|
||||||
|
|
||||||
|
@ -260,14 +253,14 @@ async function run(): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
async function pullImageFromDocker(): Promise<ImageStorageCheckResult> {
|
async function pullImageFromDocker(): Promise<ImageStorageCheckResult> {
|
||||||
core.info(`🔍 Checking if "${sourceImages.join(",")}" present in the local Docker image storage`);
|
core.info(`🔍 Checking if "${sourceImages.join(", ")}" present in the local Docker image storage`);
|
||||||
const foundTags: string[] = [];
|
const foundTags: string[] = [];
|
||||||
const missingTags: string[] = [];
|
const missingTags: string[] = [];
|
||||||
try {
|
try {
|
||||||
for (const imageWithTag of sourceImages) {
|
for (const imageWithTag of sourceImages) {
|
||||||
const commandResult: ExecResult = await execute(
|
const commandResult: ExecResult = await execute(
|
||||||
await getPodmanPath(),
|
await getPodmanPath(),
|
||||||
[ "pull", `docker-daemon:${imageWithTag}` ],
|
[ "--root", dockerPodmanRoot, "pull", `docker-daemon:${imageWithTag}` ],
|
||||||
{ ignoreReturnCode: true, failOnStdErr: false, group: true }
|
{ ignoreReturnCode: true, failOnStdErr: false, group: true }
|
||||||
);
|
);
|
||||||
if (commandResult.exitCode === 0) {
|
if (commandResult.exitCode === 0) {
|
||||||
|
@ -323,12 +316,6 @@ async function isPodmanLocalImageLatest(): Promise<boolean> {
|
||||||
// same for all the tags present
|
// same for all the tags present
|
||||||
const imageWithTag = sourceImages[0];
|
const imageWithTag = sourceImages[0];
|
||||||
|
|
||||||
// do not check if full name is specified as image pulled from docker
|
|
||||||
// will not have a different name
|
|
||||||
if (isFullImageName(imageWithTag)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// get creation time of the image present in the Podman image storage
|
// get creation time of the image present in the Podman image storage
|
||||||
const podmanLocalImageTimeStamp = await execute(await getPodmanPath(), [
|
const podmanLocalImageTimeStamp = await execute(await getPodmanPath(), [
|
||||||
"image",
|
"image",
|
||||||
|
@ -342,9 +329,10 @@ async function isPodmanLocalImageLatest(): Promise<boolean> {
|
||||||
// appending 'docker.io/library' infront of image name as pulled image name
|
// appending 'docker.io/library' infront of image name as pulled image name
|
||||||
// from Docker image storage starts with the 'docker.io/library'
|
// from Docker image storage starts with the 'docker.io/library'
|
||||||
const pulledImageCreationTimeStamp = await execute(await getPodmanPath(), [
|
const pulledImageCreationTimeStamp = await execute(await getPodmanPath(), [
|
||||||
|
"--root", dockerPodmanRoot,
|
||||||
"image",
|
"image",
|
||||||
"inspect",
|
"inspect",
|
||||||
`${dockerBaseUrl}/${imageWithTag}`,
|
getFullDockerImageName(imageWithTag),
|
||||||
"--format",
|
"--format",
|
||||||
"{{.Created}}",
|
"{{.Created}}",
|
||||||
]);
|
]);
|
||||||
|
@ -356,11 +344,15 @@ async function isPodmanLocalImageLatest(): Promise<boolean> {
|
||||||
return podmanImageTime > dockerImageTime;
|
return podmanImageTime > dockerImageTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove the pulled image from the Podman image storage
|
async function createDockerPodmanImageStroage(): Promise<void> {
|
||||||
async function removeDockerImage(): Promise<void> {
|
core.info(`Creating temporary Podman image storage for pulling from Docker daemon`);
|
||||||
core.info(`Removing "${sourceImages[0]}" from the Podman image storage`);
|
dockerPodmanRoot = await fs.promises.mkdtemp(path.join(os.tmpdir(), "docker-podman"));
|
||||||
for (const imageWithTag of sourceImages) {
|
}
|
||||||
await execute(await getPodmanPath(), [ "rmi", imageWithTag ]);
|
|
||||||
|
async function removeDockerPodmanImageStroage(): Promise<void> {
|
||||||
|
if (dockerPodmanRoot) {
|
||||||
|
core.info(`Removing temporary Podman image storage for pulling from Docker daemon`);
|
||||||
|
await fs.promises.rmdir(dockerPodmanRoot, { recursive: true });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,12 +408,17 @@ async function execute(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
run()
|
async function main(): Promise<void> {
|
||||||
.then(async () => {
|
try {
|
||||||
if (isImageFromDocker) {
|
await createDockerPodmanImageStroage();
|
||||||
await removeDockerImage();
|
await run();
|
||||||
}
|
}
|
||||||
})
|
finally {
|
||||||
|
await removeDockerPodmanImageStroage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
main()
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
core.setFailed(err.message);
|
core.setFailed(err.message);
|
||||||
});
|
});
|
||||||
|
|
14
src/util.ts
14
src/util.ts
|
@ -17,3 +17,17 @@ export function getFullImageName(image: string, tag: string): string {
|
||||||
}
|
}
|
||||||
return `${image}:${tag}`;
|
return `${image}:${tag}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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:
|
||||||
|
return `${DOCKER_IO}/${image}`;
|
||||||
|
default:
|
||||||
|
return image;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue