docker: parseRepoTag and pull methods
Signed-off-by: CrazyMax <1951866+crazy-max@users.noreply.github.com>
This commit is contained in:
@@ -20,7 +20,10 @@ import path from 'path';
|
||||
import * as core from '@actions/core';
|
||||
import * as io from '@actions/io';
|
||||
|
||||
import {Context} from '../context';
|
||||
import {Cache} from '../cache';
|
||||
import {Exec} from '../exec';
|
||||
import {Util} from '../util';
|
||||
|
||||
import {ConfigFile} from '../types/docker';
|
||||
|
||||
@@ -73,4 +76,78 @@ export class Docker {
|
||||
public static async printInfo(): Promise<void> {
|
||||
await Exec.exec('docker', ['info']);
|
||||
}
|
||||
|
||||
public static parseRepoTag(image: string): {repository: string; tag: string} {
|
||||
let sepPos: number;
|
||||
const digestPos = image.indexOf('@');
|
||||
const colonPos = image.lastIndexOf(':');
|
||||
if (digestPos >= 0) {
|
||||
// priority on digest
|
||||
sepPos = digestPos;
|
||||
} else if (colonPos >= 0) {
|
||||
sepPos = colonPos;
|
||||
} else {
|
||||
return {
|
||||
repository: image,
|
||||
tag: 'latest'
|
||||
};
|
||||
}
|
||||
const tag = image.slice(sepPos + 1);
|
||||
if (tag.indexOf('/') === -1) {
|
||||
return {
|
||||
repository: image.slice(0, sepPos),
|
||||
tag: tag
|
||||
};
|
||||
}
|
||||
return {
|
||||
repository: image,
|
||||
tag: 'latest'
|
||||
};
|
||||
}
|
||||
|
||||
public static async pull(image: string, cache?: boolean): Promise<void> {
|
||||
const parsedImage = Docker.parseRepoTag(image);
|
||||
const repoSanitized = parsedImage.repository.replace(/[^a-zA-Z0-9.]+/g, '--');
|
||||
const tagSanitized = parsedImage.tag.replace(/[^a-zA-Z0-9.]+/g, '--');
|
||||
|
||||
const imageCache = new Cache({
|
||||
htcName: repoSanitized,
|
||||
htcVersion: tagSanitized,
|
||||
baseCacheDir: path.join(Docker.configDir, '.cache', 'images', repoSanitized),
|
||||
cacheFile: 'image.tar'
|
||||
});
|
||||
|
||||
let cacheFoundPath: string | undefined;
|
||||
if (cache) {
|
||||
cacheFoundPath = await imageCache.find();
|
||||
if (cacheFoundPath) {
|
||||
core.info(`Image found from cache in ${cacheFoundPath}`);
|
||||
await Exec.getExecOutput(`docker`, ['load', '-i', cacheFoundPath]).catch(e => {
|
||||
core.warning(`Failed to load image from cache: ${e}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let pulled = true;
|
||||
await Exec.getExecOutput(`docker`, ['pull', image]).catch(e => {
|
||||
pulled = false;
|
||||
if (cacheFoundPath) {
|
||||
core.warning(`Failed to pull image, using one from cache: ${e}`);
|
||||
} else {
|
||||
throw new Error(e);
|
||||
}
|
||||
});
|
||||
|
||||
if (cache && pulled) {
|
||||
const imageTarPath = path.join(Context.tmpDir(), `${Util.hash(image)}.tar`);
|
||||
await Exec.getExecOutput(`docker`, ['save', '-o', imageTarPath, image])
|
||||
.then(async () => {
|
||||
const cachePath = await imageCache.save(imageTarPath);
|
||||
core.info(`Image cached to ${cachePath}`);
|
||||
})
|
||||
.catch(e => {
|
||||
core.warning(`Failed to save image: ${e}`);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user