Files
testcontainers/docker/libraries/container.ts
2024-07-06 21:21:10 +02:00

125 lines
3.6 KiB
TypeScript

import { CreateExecOptions, Exec } from "./exec.ts";
import { modem } from "./modem.ts";
export class Container {
/**
* Instantiate a docker container.
*
* @param id - The container ID.
* @param warnings - Warnings encountered during the container creation.
*/
constructor(
readonly id: string,
readonly warnings: string[],
) {}
/**
* Start the container.
*
* @see https://docs.docker.com/engine/api/v1.45/#tag/Container/operation/ContainerStart
*
* @param query.signal - Signal to send to the container as an integer or string (e.g. SIGINT).
* @param query.t - An integer representing the number of seconds to wait before killing the container.
*/
async start(query: SignalQuery = {}) {
await modem.post({ path: `/containers/${this.id}/start`, query });
}
/**
* Stop the container.
*
* @see https://docs.docker.com/engine/api/v1.45/#tag/Container/operation/ContainerStop
*
* @param query.signal - Signal to send to the container as an integer or string (e.g. SIGINT).
* @param query.t - An integer representing the number of seconds to wait before killing the container.
*/
async stop(query: SignalQuery = {}) {
await modem.post({ path: `/containers/${this.id}/stop`, query });
}
/**
* Remove the container.
*
* @see https://docs.docker.com/engine/api/v1.45/#tag/Container/operation/ContainerDelete
*
* @param query.v - Remove the volumes associated with the container.
* @param query.force - Kill the container if it is running.
* @param query.link - Remove the specified link and not the underlying container.
*/
async remove(query: { v?: boolean; force?: boolean; link?: boolean } = {}) {
await modem.del({ path: `/containers/${this.id}`, query });
}
/**
* Return low-level information about a container.
*
* @see https://docs.docker.com/engine/api/v1.45/#tag/Container/operation/ContainerInspect
*/
async inspect() {
return modem.get({ path: `/containers/${this.id}/json` });
}
/**
* Get the logs of the container.
*
* @see https://docs.docker.com/engine/api/v1.45/#tag/Container/operation/ContainerLogs
*
* @param handler - Function to handle each line of the logs.
*/
async logs(handler: (line: string) => true | void) {
const res = await modem.request({
method: "GET",
path: `/containers/${this.id}/logs`,
query: {
stdout: true,
follow: true,
tail: "all",
},
});
for await (const chunk of res.stream) {
if (handler(chunk) === true) {
break;
}
}
}
/**
* Run a command inside the running container.
*
* @see https://docs.docker.com/engine/api/v1.45/#tag/Exec/operation/ContainerExec
*
* @param cmd - Command to run.
* @param opts - Options for the command.
*/
async exec(cmd: string | string[], opts: Partial<CreateExecOptions> = {}) {
const { Id } = await modem.post<{ Id: string }>({
path: `/containers/${this.id}/exec`,
body: {
...opts,
Cmd: Array.isArray(cmd) ? cmd : [cmd],
AttachStdout: true,
AttachStderr: true,
},
});
return new Exec(Id).start();
}
}
/*
|--------------------------------------------------------------------------------
| Types
|--------------------------------------------------------------------------------
*/
type SignalQuery = {
/**
* Signal to send to the container as an integer or string (e.g. SIGINT).
*/
signal?: string;
/**
* An integer representing the number of seconds to wait before killing the container.
*/
t?: number;
};