@wocker/ws
Version:
Docker workspace for web projects
247 lines (246 loc) • 8.71 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.DockerService = void 0;
const core_1 = require("@wocker/core");
const ContainerService_1 = require("./ContainerService");
const ModemService_1 = require("./ModemService");
const ImageService_1 = require("./ImageService");
let DockerService = class DockerService extends core_1.DockerService {
constructor(modemService, containerService, imageService, logService) {
super();
this.modemService = modemService;
this.containerService = containerService;
this.imageService = imageService;
this.logService = logService;
}
get docker() {
return this.modemService.docker;
}
async createVolume(name) {
return await this.docker.createVolume({
Name: name,
Driver: "local"
});
}
async hasVolume(name) {
const volume = await this.getVolume(name);
try {
await volume.inspect();
return true;
}
catch (err) {
return false;
}
}
async getVolume(name) {
return this.docker.getVolume(name);
}
async rmVolume(name) {
const volume = await this.getVolume(name);
await volume.remove();
}
async createContainer(params) {
const { name, user, entrypoint, tty, image, projectId, restart, memory, memorySwap, ulimits, extraHosts, networkMode = "bridge", links = [], env = {}, volumes = [], ports = [], cmd = [], network: networkName = "workspace", aliases } = params;
const network = this.docker.getNetwork(networkName);
try {
await network.inspect();
}
catch (err) {
if (err.statusCode === 404) {
await this.docker.createNetwork({
Name: networkName
});
}
}
await this.pullImage(image);
return this.docker.createContainer({
name,
User: user,
Image: image,
Hostname: name,
Domainname: name,
Labels: {
...projectId ? { projectId } : {}
},
AttachStdin: true,
AttachStdout: true,
AttachStderr: true,
OpenStdin: true,
StdinOnce: false,
Entrypoint: entrypoint,
Tty: true,
Cmd: cmd,
Env: Object.keys(env).map((key) => {
const value = env[key];
return `${key}=${value}`;
}),
ExposedPorts: ports.reduce((res, value) => {
const [, , containerPort, type = "tcp"] = /(\d+):(\d+)(?:\/(\w+))?/.exec(value) || [];
if (containerPort) {
res[`${containerPort}/${type}`] = {};
}
return res;
}, {}),
HostConfig: {
Memory: memory,
MemorySwap: memorySwap,
NetworkMode: networkMode,
ExtraHosts: extraHosts,
Ulimits: ulimits ? Object.keys(ulimits).reduce((res, name) => {
return [
...res,
{
Name: name,
Hard: ulimits[name].hard,
Soft: ulimits[name].soft
}
];
}, []) : [],
...restart ? {
RestartPolicy: {
Name: restart
}
} : {},
Binds: volumes,
PortBindings: ports.reduce((res, value) => {
const [, hostPort, containerPort, type = "tcp"] = /(\d+):(\d+)(?:\/(\w+))?/.exec(value) || [];
if (hostPort && containerPort) {
res[`${containerPort}/${type}`] = [
{ HostPort: hostPort }
];
}
else {
this.logService.warn(`Invalid port format for container "${name}": "${value}". Expected format: hostPort:containerPort[/protocol]`);
}
return res;
}, {})
},
NetworkingConfig: {
EndpointsConfig: networkMode === "host" ? {} : {
[networkName]: {
Links: links,
Aliases: aliases || (env.VIRTUAL_HOST ? env.VIRTUAL_HOST.split(",") : undefined)
}
}
}
});
}
async getContainer(name) {
return this.containerService.get(name);
}
async removeContainer(name) {
await this.containerService.rm(name);
}
async buildImage(params) {
await this.imageService.build(params);
}
async imageExists(tag) {
return this.imageService.exists(tag);
}
async imageRm(tag, force = false) {
await this.imageService.rm(tag, force);
}
async imageLs(options) {
const { tag, reference, labels } = options || {};
const filters = {};
if (reference) {
filters.reference = [
...filters.reference || [],
...reference
];
}
if (tag) {
filters.reference = [
...filters.reference || [],
tag
];
}
if (labels) {
filters.label = [];
for (const i in labels) {
filters.label.push(`${i}=${labels[i]}`);
}
}
return this.docker.listImages({
filters: JSON.stringify(filters)
});
}
async pullImage(tag) {
await this.imageService.pull(tag);
}
async attach(containerOrName) {
let container = typeof containerOrName === "string"
? await this.getContainer(containerOrName)
: containerOrName;
if (!container) {
return;
}
const stream = await container.attach({
stream: true,
hijack: true,
stdin: true,
stdout: true,
stderr: true,
logs: true,
detachKeys: "ctrl-d"
});
await this.attachStream(stream);
const handleResize = () => {
const [width, height] = process.stdout.getWindowSize();
container.resize({
w: width,
h: height
});
};
process.stdout.on("resize", handleResize);
handleResize();
return stream;
}
async attachStream(stream) {
return this.modemService.attachStream(stream);
}
async exec(nameOrContainer, options, _tty) {
return await this.containerService.exec(nameOrContainer, options, _tty);
}
async logs(containerOrName) {
const container = typeof containerOrName === "string"
? await this.getContainer(containerOrName)
: containerOrName;
if (!container) {
return;
}
const stream = await container.logs({
stdout: true,
stderr: true,
follow: true,
tail: 4
});
stream.on("data", (data) => {
process.stdout.write(data);
});
stream.on("error", (data) => {
process.stderr.write(data);
});
return stream;
}
async followProgress(stream) {
await this.modemService.followProgress(stream);
}
};
exports.DockerService = DockerService;
exports.DockerService = DockerService = __decorate([
(0, core_1.Injectable)("DOCKER_SERVICE"),
__metadata("design:paramtypes", [ModemService_1.ModemService,
ContainerService_1.ContainerService,
ImageService_1.ImageService,
core_1.LogService])
], DockerService);