Add feature to push multiple tags of the image

Signed-off-by: divyansh42 <diagrawa@redhat.com>
This commit is contained in:
divyansh42 2021-01-25 15:52:13 +05:30
parent 23eb62f550
commit 73da53f4a0
6 changed files with 96 additions and 55 deletions

View file

@ -15,6 +15,7 @@ let podmanPath: string | undefined;
// boolean value to check if pushed image is from Docker image storage
let isImageFromDocker = false;
let imageToPush: string;
let tagsList: string[];
async function getPodmanPath(): Promise<string> {
if (podmanPath == null) {
@ -29,24 +30,28 @@ const dockerBaseUrl = "docker.io/library";
async function run(): Promise<void> {
const imageInput = core.getInput("image", { required: true });
const tag = core.getInput("tag") || "latest";
const tags = core.getInput("tags");
// split tags
tagsList = tags.split(" ");
const registry = core.getInput("registry", { required: true });
const username = core.getInput("username", { required: true });
const password = core.getInput("password", { required: true });
const tlsVerify = core.getInput("tls-verify");
const digestFileInput = core.getInput("digestfile");
imageToPush = `${imageInput}:${tag}`;
imageToPush = `${imageInput}`;
const registryPathList: string[] = [];
// check if image exist in Podman image storage
// check if image with all the required tags exist in Podman image storage
const isPresentInPodman: boolean = await checkImageInPodman();
// check if image exist in Docker image storage and if exist pull the image to Podman
// check if image with all the required tags exist in Docker image storage
// and if exist pull the image with all the tags to Podman
const isPresentInDocker: boolean = await pullImageFromDocker();
// failing if image is not found in Docker as well as Podman
// failing if image with any of the tag is not found in Docker as well as Podman
if (!isPresentInDocker && !isPresentInPodman) {
throw new Error(`${imageToPush} not found in Podman local storage, or Docker local storage.`);
throw new Error(`All the tags of ${imageToPush} not found in Podman local storage, or Docker local storage.`);
}
if (isPresentInPodman && isPresentInDocker) {
@ -60,59 +65,64 @@ async function run(): Promise<void> {
}
else {
core.warning(`The version of ${imageToPush} in the Podman image storage is more recent `
+ `than the version in the Docker image storage. The image from the Podman image `
+ `than the version in the Docker image storage. Tag(s) of the image from the Podman image `
+ `storage will be pushed.`);
}
}
else if (isPresentInDocker) {
imageToPush = `${dockerBaseUrl}/${imageToPush}`;
core.info(`${imageToPush} was found in the Docker image storage, but not in the Podman `
+ `image storage. The image will be pulled into Podman image storage, pushed, and then `
+ `image storage. Tag(s) of the image will be pulled into Podman image storage, pushed, and then `
+ `removed from the Podman image storage.`);
isImageFromDocker = true;
}
let pushMsg = `Pushing ${imageToPush} to ${registry}`;
let pushMsg = `Pushing ${imageToPush} with tags ${tagsList.toString()} to ${registry}`;
if (username) {
pushMsg += ` as ${username}`;
}
core.info(pushMsg);
const registryWithoutTrailingSlash = registry.replace(/\/$/, "");
const registryPath = `${registryWithoutTrailingSlash}/${imageInput}:${tag}`;
const creds = `${username}:${password}`;
let digestFile = digestFileInput;
const imageNameWithTag = `${imageToPush}:${tagsList[0]}`;
if (!digestFile) {
digestFile = `${imageToPush.replace(
digestFile = `${imageNameWithTag.replace(
/[/\\/?%*:|"<>]/g,
"-",
)}_digest.txt`;
}
// push the image
const args = [
"push",
"--quiet",
"--digestfile",
digestFile,
"--creds",
creds,
imageToPush,
registryPath,
];
for (const tag of tagsList) {
const imageWithTag = `${imageToPush}:${tag}`;
const registryPath = `${registryWithoutTrailingSlash}/${imageInput}:${tag}`;
// check if tls-verify is not set to null
if (tlsVerify) {
args.push(`--tls-verify=${tlsVerify}`);
const args = [
"push",
"--quiet",
"--digestfile",
digestFile,
"--creds",
creds,
imageWithTag,
registryPath,
];
// check if tls-verify is not set to null
if (tlsVerify) {
args.push(`--tls-verify=${tlsVerify}`);
}
await execute(await getPodmanPath(), args);
core.info(`Successfully pushed ${imageWithTag} to ${registryPath}.`);
registryPathList.push(registryPath);
}
await execute(await getPodmanPath(), args);
core.info(`Successfully pushed ${imageToPush} to ${registryPath}.`);
core.setOutput("registry-path", registryPath);
try {
const digest = (await fs.promises.readFile(digestFile)).toString();
core.info(digest);
@ -121,41 +131,57 @@ async function run(): Promise<void> {
catch (err) {
core.warning(`Failed to read digest file "${digestFile}": ${err}`);
}
core.setOutput("registry-paths", registryPathList.toString());
}
async function pullImageFromDocker(): Promise<boolean> {
let imageWithTag;
try {
await execute(await getPodmanPath(), [ "pull", `docker-daemon:${imageToPush}` ]);
core.info(`${imageToPush} found in Docker image storage`);
return true;
for (const tag of tagsList) {
imageWithTag = `${imageToPush}:${tag}`;
await execute(await getPodmanPath(), [ "pull", `docker-daemon:${imageWithTag}` ]);
core.info(`${imageWithTag} found in Docker image storage`);
}
}
catch (err) {
core.info(`${imageToPush} not found in Docker image storage`);
core.info(`${imageWithTag} not found in Docker image storage`);
return false;
}
return true;
}
async function checkImageInPodman(): Promise<boolean> {
// check if images exist in Podman's storage
core.info(`Checking if ${imageToPush} is in Podman image storage`);
core.info(`Checking if ${imageToPush} with tag(s) ${tagsList.toString()} is present in Podman image storage`);
let imageWithTag;
try {
await execute(await getPodmanPath(), [ "image", "exists", imageToPush ]);
core.info(`${imageToPush} found in Podman image storage`);
return true;
for (const tag of tagsList) {
imageWithTag = `${imageToPush}:${tag}`;
await execute(await getPodmanPath(), [ "image", "exists", imageWithTag ]);
core.info(`${imageWithTag} found in Podman image storage`);
}
}
catch (err) {
core.info(`${imageToPush} not found in Podman image storage`);
core.info(`${imageWithTag} not found in Podman image storage`);
core.debug(err);
return false;
}
return true;
}
async function isPodmanLocalImageLatest(): Promise<boolean> {
// checking for only one tag as creation time will be
// same for all the tags present
const imageWithTag = `${imageToPush}:${tagsList[0]}`;
// get creation time of the image present in the Podman image storage
const podmanLocalImageTimeStamp = await execute(await getPodmanPath(), [
"image",
"inspect",
imageToPush,
imageWithTag,
"--format",
"{{.Created}}",
]);
@ -166,7 +192,7 @@ async function isPodmanLocalImageLatest(): Promise<boolean> {
const pulledImageCreationTimeStamp = await execute(await getPodmanPath(), [
"image",
"inspect",
`${dockerBaseUrl}/${imageToPush}`,
`${dockerBaseUrl}/${imageWithTag}`,
"--format",
"{{.Created}}",
]);
@ -181,8 +207,11 @@ async function isPodmanLocalImageLatest(): Promise<boolean> {
// remove the pulled image from the Podman image storage
async function removeDockerImage(): Promise<void> {
if (imageToPush) {
core.info(`Removing ${imageToPush} from the Podman image storage`);
await execute(await getPodmanPath(), [ "rmi", imageToPush ]);
for (const tag of tagsList) {
const imageWithTag = `${imageToPush}:${tag}`;
await execute(await getPodmanPath(), [ "rmi", imageWithTag ]);
core.info(`Removing ${imageWithTag} from the Podman image storage`);
}
}
}