BREAKING CHANGE(szci): delegate Docker operations to @git.zone/tsdocker, remove internal Docker managers and deprecated modules, simplify CLI and env var handling
This commit is contained in:
@@ -1,190 +1,78 @@
|
||||
import { logger } from '../szci.logging.ts';
|
||||
import * as plugins from './mod.plugins.ts';
|
||||
import * as paths from '../szci.paths.ts';
|
||||
import { bash } from '../szci.bash.ts';
|
||||
|
||||
// classes
|
||||
import { Szci } from '../szci.classes.szci.ts';
|
||||
import { Dockerfile } from './mod.classes.dockerfile.ts';
|
||||
import { DockerRegistry } from './mod.classes.dockerregistry.ts';
|
||||
import { RegistryStorage } from './mod.classes.registrystorage.ts';
|
||||
|
||||
export class SzciDockerManager {
|
||||
public szciRef: Szci;
|
||||
public szciRegistryStorage = new RegistryStorage();
|
||||
|
||||
constructor(szciArg: Szci) {
|
||||
this.szciRef = szciArg;
|
||||
}
|
||||
|
||||
/**
|
||||
* handle cli input
|
||||
* @param argvArg
|
||||
* Bridges SZCI_LOGIN_DOCKER* env vars to DOCKER_REGISTRY_N format for tsdocker,
|
||||
* and handles GitLab CI registry auto-login.
|
||||
*/
|
||||
private bridgeEnvVars() {
|
||||
const env = Deno.env.toObject();
|
||||
|
||||
// Bridge GitLab CI registry as DOCKER_REGISTRY_0
|
||||
if (env['GITLAB_CI']) {
|
||||
const ciJobToken = env['CI_JOB_TOKEN'];
|
||||
if (!ciJobToken) {
|
||||
logger.log('error', 'Running in GitLab CI, but no CI_JOB_TOKEN found!');
|
||||
Deno.exit(1);
|
||||
}
|
||||
Deno.env.set('DOCKER_REGISTRY_0', `registry.gitlab.com|gitlab-ci-token|${ciJobToken}`);
|
||||
}
|
||||
|
||||
// Bridge SZCI_LOGIN_DOCKER* → DOCKER_REGISTRY_N
|
||||
let registryIndex = 1;
|
||||
const sortedKeys = Object.keys(env)
|
||||
.filter((key) => key.startsWith('SZCI_LOGIN_DOCKER'))
|
||||
.sort();
|
||||
for (const key of sortedKeys) {
|
||||
Deno.env.set(`DOCKER_REGISTRY_${registryIndex}`, env[key]);
|
||||
registryIndex++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle cli input by bridging env vars and delegating to tsdocker.
|
||||
*/
|
||||
public handleCli = async (argvArg: any) => {
|
||||
if (argvArg._.length >= 2) {
|
||||
const action: string = argvArg._[1];
|
||||
switch (action) {
|
||||
case 'build':
|
||||
await this.build();
|
||||
break;
|
||||
case 'login':
|
||||
case 'prepare':
|
||||
await this.login();
|
||||
break;
|
||||
case 'test':
|
||||
await this.test();
|
||||
break;
|
||||
case 'push':
|
||||
await this.push(argvArg);
|
||||
break;
|
||||
case 'pull':
|
||||
await this.pull(argvArg);
|
||||
break;
|
||||
default:
|
||||
logger.log('error', `>>szci docker ...<< action >>${action}<< not supported`);
|
||||
}
|
||||
} else {
|
||||
if (argvArg._.length < 2) {
|
||||
logger.log(
|
||||
'info',
|
||||
`>>szci docker ...<< cli arguments invalid... Please read the documentation.`
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* builds a cwd of Dockerfiles by triggering a promisechain
|
||||
*/
|
||||
public build = async () => {
|
||||
await this.prepare();
|
||||
logger.log('info', 'now building Dockerfiles...');
|
||||
await Dockerfile.readDockerfiles(this)
|
||||
.then(Dockerfile.sortDockerfiles)
|
||||
.then(Dockerfile.mapDockerfiles)
|
||||
.then(Dockerfile.buildDockerfiles);
|
||||
};
|
||||
|
||||
/**
|
||||
* login to the DockerRegistries
|
||||
*/
|
||||
public login = async () => {
|
||||
await this.prepare();
|
||||
await this.szciRegistryStorage.loginAll();
|
||||
};
|
||||
|
||||
/**
|
||||
* logs in docker
|
||||
*/
|
||||
public prepare = async () => {
|
||||
// Always login to GitLab Registry
|
||||
if (Deno.env.get("GITLAB_CI")) {
|
||||
console.log('gitlab ci detected');
|
||||
if (!Deno.env.get("CI_JOB_TOKEN") || Deno.env.get("CI_JOB_TOKEN") === '') {
|
||||
logger.log('error', 'Running in Gitlab CI, but no registry token specified by gitlab!');
|
||||
Deno.exit(1);
|
||||
}
|
||||
this.szciRegistryStorage.addRegistry(
|
||||
new DockerRegistry({
|
||||
registryUrl: 'registry.gitlab.com',
|
||||
username: 'gitlab-ci-token',
|
||||
password: Deno.env.get("CI_JOB_TOKEN")!,
|
||||
})
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
// handle registries
|
||||
await plugins.smartobject.forEachMinimatch(
|
||||
Deno.env.toObject(),
|
||||
'SZCI_LOGIN_DOCKER*',
|
||||
async (envString: string) => {
|
||||
this.szciRegistryStorage.addRegistry(DockerRegistry.fromEnvString(envString));
|
||||
}
|
||||
);
|
||||
return;
|
||||
};
|
||||
this.bridgeEnvVars();
|
||||
|
||||
/**
|
||||
* pushes an image towards a registry
|
||||
* @param argvArg
|
||||
*/
|
||||
public push = async (argvArg: any) => {
|
||||
await this.prepare();
|
||||
let dockerRegistryUrls: string[] = [];
|
||||
const action: string = argvArg._[1];
|
||||
const extraArgs = argvArg._.slice(2).join(' ');
|
||||
|
||||
// lets parse the input of cli and npmextra
|
||||
if (argvArg._.length >= 3 && argvArg._[2] !== 'npmextra') {
|
||||
dockerRegistryUrls.push(argvArg._[2]);
|
||||
} else {
|
||||
if (this.szciRef.szciConfig.getConfig().dockerRegistries.length === 0) {
|
||||
logger.log(
|
||||
'warn',
|
||||
`There are no docker registries listed in npmextra.json! This is strange!`
|
||||
);
|
||||
}
|
||||
dockerRegistryUrls = dockerRegistryUrls.concat(
|
||||
this.szciRef.szciConfig.getConfig().dockerRegistries
|
||||
);
|
||||
}
|
||||
|
||||
// lets determine the suffix
|
||||
let suffix = null;
|
||||
if (argvArg._.length >= 4) {
|
||||
suffix = argvArg._[3];
|
||||
}
|
||||
|
||||
// lets push to the registries
|
||||
for (const dockerRegistryUrl of dockerRegistryUrls) {
|
||||
const dockerfileArray = await Dockerfile.readDockerfiles(this)
|
||||
.then(Dockerfile.sortDockerfiles)
|
||||
.then(Dockerfile.mapDockerfiles);
|
||||
const dockerRegistryToPushTo = await this.szciRegistryStorage.getRegistryByUrl(
|
||||
dockerRegistryUrl
|
||||
);
|
||||
if (!dockerRegistryToPushTo) {
|
||||
logger.log(
|
||||
'error',
|
||||
`Cannot push to registry ${dockerRegistryUrl}, because it was not found in the authenticated registry list.`
|
||||
);
|
||||
Deno.exit(1);
|
||||
}
|
||||
for (const dockerfile of dockerfileArray) {
|
||||
await dockerfile.push(dockerRegistryToPushTo, suffix);
|
||||
}
|
||||
switch (action) {
|
||||
case 'build':
|
||||
await bash(`npx @git.zone/tsdocker build ${extraArgs}`.trim());
|
||||
break;
|
||||
case 'login':
|
||||
case 'prepare':
|
||||
await bash(`npx @git.zone/tsdocker login ${extraArgs}`.trim());
|
||||
break;
|
||||
case 'test':
|
||||
await bash(`npx @git.zone/tsdocker test ${extraArgs}`.trim());
|
||||
break;
|
||||
case 'push':
|
||||
await bash(`npx @git.zone/tsdocker push ${extraArgs}`.trim());
|
||||
break;
|
||||
case 'pull':
|
||||
await bash(`npx @git.zone/tsdocker pull ${extraArgs}`.trim());
|
||||
break;
|
||||
default:
|
||||
logger.log('error', `>>szci docker ...<< action >>${action}<< not supported`);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* pulls an image
|
||||
*/
|
||||
public pull = async (argvArg: any) => {
|
||||
await this.prepare();
|
||||
const registryUrlArg = argvArg._[2];
|
||||
let suffix = null;
|
||||
if (argvArg._.length >= 4) {
|
||||
suffix = argvArg._[3];
|
||||
}
|
||||
const localDockerRegistry = await this.szciRegistryStorage.getRegistryByUrl(registryUrlArg);
|
||||
const dockerfileArray = await Dockerfile.readDockerfiles(this)
|
||||
.then(Dockerfile.sortDockerfiles)
|
||||
.then(Dockerfile.mapDockerfiles);
|
||||
for (const dockerfile of dockerfileArray) {
|
||||
await dockerfile.pull(localDockerRegistry, suffix);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* tests docker files
|
||||
*/
|
||||
public test = async () => {
|
||||
await this.prepare();
|
||||
return await Dockerfile.readDockerfiles(this).then(Dockerfile.testDockerfiles);
|
||||
};
|
||||
|
||||
/**
|
||||
* can be used to get the Dockerfiles in the directory
|
||||
*/
|
||||
getDockerfiles = async () => {
|
||||
const dockerfiles = await Dockerfile.readDockerfiles(this);
|
||||
return dockerfiles;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user