lugger
Version:
Lugger is an automation framework running on customizable Typescript DSL
101 lines (88 loc) • 4.39 kB
text/typescript
// DSL SKIP
import { CallContextEvent, CCE, dedent, getRuntime, PostfixReturn, dslIfaceGuard } from "ts-dsl";
import { DockerAPIRequest, DockerAPIResponse, DockerContainer, DockerImage, DockerPullStatus, UnixSocketGet, UnixSocketPost } from "./docker.model";
// ====================================================
// Facade
// ====================================================
class dockerModel {
static ps(): PostfixReturn<DockerContainer[]>;
static ps(...args) { dslIfaceGuard('lugger:docker:docker.ps', __filename); return null; }
static images(): PostfixReturn<DockerImage[]>;
static images(...args) { dslIfaceGuard('lugger:docker:docker.images', __filename); return null; }
static pull(image: string): PostfixReturn<'downloaded' | 'cached'>;
static pull(...args) { dslIfaceGuard('lugger:docker:docker.pull', __filename); return null; }
static login(registry: string, username: string, password: string): PostfixReturn<void>;
static login(...args) { dslIfaceGuard('lugger:docker:docker.login', __filename); return null; }
}
export const docker = dockerModel as (typeof dockerModel & ((req: DockerAPIRequest) => PostfixReturn<DockerAPIResponse>));
// ====================================================
// Implemenation
// ====================================================
function dockerModel__(cce: CallContextEvent, ...args) {
return getRuntime().scopedExec(
cce, 'lugger:docker:docker', { data: { } },
async (resolve, reject, scopeContext) => {
resolve(true);
});
}
(dockerModel__ as any).ps = (cce: CallContextEvent, ...args) => {
return getRuntime().scopedExec(
cce, 'lugger:docker:docker.ps', { data: { } },
async (resolve, reject, scopeContext) => {
try { resolve(JSON.parse(await UnixSocketGet('/var/run/docker.sock', '/containers/json?all=true&size=true'))); } catch (e) { reject(e); }
});
}
(dockerModel__ as any).images = (cce: CallContextEvent, ...args) => {
// const { url, config } = getHttpRequestArgs(args);
return getRuntime().scopedExec(
cce, 'lugger:docker:docker.images', { data: { } },
async (resolve, reject, scopeContext) => {
try { resolve(JSON.parse(await UnixSocketGet('/var/run/docker.sock', '/images/json'))); } catch (e) { reject(e); }
});
}
(dockerModel__ as any).pull = (cce: CallContextEvent, ...args) => {
const image = args[0];
return getRuntime().scopedExec(
cce, 'lugger:docker:docker.pull', { data: { } },
async (resolve, reject, scopeContext) => {
try {
let registryEndpoint: string = 'docker.io';
const headers = { 'X-Stream-Match': [
`Status: Image is up to date for :: cached`,
`Status: Downloaded :: downloaded`,
`unknown: Not Found :: not_found`,
`unauthorized: :: unauthorized`,
].join(' || ') };
if (image.indexOf('.') >= 0) {
registryEndpoint = image.split('/')[0];
if (scopeContext.parent.data.dockerLogin?.[registryEndpoint]) {
headers['X-Registry-Auth'] = scopeContext.parent.data.dockerLogin[registryEndpoint];
}
}
const res = await UnixSocketPost('/var/run/docker.sock', `/images/create?fromImage=${image}`, '', headers) as DockerPullStatus;
if (!res) {
return reject(new Error(`unknown error while pulling ${image}`));
} else if (res === 'not_found') {
return reject(new Error(`image not found: ${image}`));
} else if (res === 'unauthorized') {
return reject(new Error(`unauthorized: no valid permission for ${registryEndpoint}`));
}
return resolve(res);
} catch (e) { return reject(e); }
});
}
(dockerModel__ as any).login = (cce: CallContextEvent, ...args) => {
let [ registry, username, password ] = args as [ string, string, string ];
return getRuntime().scopedExec(
cce, 'lugger:docker:docker.login', { data: { } },
async (resolve, reject, scopeContext) => {
try {
if (!scopeContext.parent.data.dockerLogin) { scopeContext.parent.data.dockerLogin = {}; }
scopeContext.parent.data.dockerLogin[registry] = Buffer.from(JSON.stringify({
serveraddress: registry, username, password, email: '',
})).toString('base64');
resolve(void 0);
} catch (e) { reject(e); }
});
}
export const docker__ = dockerModel__ as any as (typeof docker);