Skip to content
This repository was archived by the owner on May 8, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions __tests__/containers.docker.integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { afterAll, afterEach, beforeAll, describe, expect, it } from 'vitest';
import { Server, ServerCredentials, credentials } from '@grpc/grpc-js';

import type { RunnerConfig } from '../src/service/config';
import { ContainerService, NonceCache } from '../src';
import { ContainerService } from '../src';
import { createRunnerGrpcServer } from '../src/service/grpc/server';
import { RunnerServiceGrpcClient } from '../src/proto/grpc.js';
import { createGrpcTestClient, type GrpcTestClient } from './helpers/grpc-test-client';
Expand All @@ -24,8 +24,6 @@ if (shouldSkip) {
console.warn(`Skipping docker-runner docker-backed integration tests: ${reason}`);
}

const RUNNER_SECRET = 'docker-runner-integration-secret';

describeOrSkip('docker-runner docker-backed container lifecycle', () => {
let grpcAddress: string;
let client: InstanceType<typeof RunnerServiceGrpcClient>;
Expand All @@ -35,24 +33,21 @@ describeOrSkip('docker-runner docker-backed container lifecycle', () => {

beforeAll(async () => {
const config: RunnerConfig = {
sharedSecret: RUNNER_SECRET,
signatureTtlMs: 60_000,
dockerSocket: hasSocket ? DEFAULT_SOCKET : '',
logLevel: 'error',
grpcHost: '127.0.0.1',
grpcPort: 0,
};
const nonceCache = new NonceCache({ ttlMs: config.signatureTtlMs });
const previousSocket = process.env.DOCKER_SOCKET;
if (config.dockerSocket) {
process.env.DOCKER_SOCKET = config.dockerSocket;
}
const containers = new ContainerService();
const server = createRunnerGrpcServer({ config, containers, nonceCache });
const server = createRunnerGrpcServer({ config, containers });
const address = await bindServer(server, config.grpcHost);
grpcAddress = address;
client = new RunnerServiceGrpcClient(address, credentials.createInsecure());
grpcTestClient = createGrpcTestClient({ client, secret: RUNNER_SECRET });
grpcTestClient = createGrpcTestClient({ client });
await grpcTestClient.ready();
shutdown = async () => {
await new Promise<void>((resolve) => {
Expand Down
38 changes: 11 additions & 27 deletions __tests__/helpers/grpc-test-client.ts
Original file line number Diff line number Diff line change
@@ -1,16 +1,8 @@
import { Metadata, type ServiceError } from '@grpc/grpc-js';
import { create } from '@bufbuild/protobuf';

import { buildAuthHeaders } from '../../src/contracts/auth';
import { containerOptsToStartWorkloadRequest } from '../../src/contracts/workload.grpc';
import {
RUNNER_SERVICE_INSPECT_WORKLOAD_PATH,
RUNNER_SERVICE_READY_PATH,
RUNNER_SERVICE_REMOVE_WORKLOAD_PATH,
RUNNER_SERVICE_START_WORKLOAD_PATH,
RUNNER_SERVICE_STOP_WORKLOAD_PATH,
type RunnerServiceGrpcClientInstance,
} from '../../src/proto/grpc.js';
import { type RunnerServiceGrpcClientInstance } from '../../src/proto/grpc.js';
import {
InspectWorkloadRequestSchema,
ReadyRequestSchema,
Expand All @@ -29,9 +21,8 @@ export type StartWorkloadInput = {
};

export type GrpcTestClient = {
metadataFor: (path: string) => Metadata;
metadataFor: () => Metadata;
unary: <Request, Response>(
path: string,
request: Request,
invoke: (
req: Request,
Expand All @@ -51,29 +42,22 @@ export type GrpcTestClient = {

export function createGrpcTestClient(options: {
client: RunnerServiceGrpcClientInstance;
secret: string;
}): GrpcTestClient {
const { client, secret } = options;
const { client } = options;

const metadataFor = (path: string): Metadata => {
const headers = buildAuthHeaders({ method: 'POST', path, body: '', secret });
const metadata = new Metadata();
for (const [key, value] of Object.entries(headers)) {
metadata.set(key, value);
}
return metadata;
const metadataFor = (): Metadata => {
return new Metadata();
};

const unary = async <Request, Response>(
path: string,
request: Request,
invoke: (
req: Request,
metadata: Metadata,
callback: (err: ServiceError | null, response?: Response) => void,
) => void,
): Promise<Response> => {
const metadata = metadataFor(path);
const metadata = metadataFor();
return new Promise<Response>((resolve, reject) => {
invoke(request, metadata, (err, response) => {
if (err) {
Expand All @@ -92,14 +76,14 @@ export function createGrpcTestClient(options: {
name: opts.name,
autoRemove: opts.autoRemove,
});
return unary(RUNNER_SERVICE_START_WORKLOAD_PATH, request, (req, metadata, callback) => {
return unary(request, (req, metadata, callback) => {
client.startWorkload(req, metadata, callback);
});
};

const stopContainer = async (containerId: string, timeoutSec = 1): Promise<void> => {
const request = create(StopWorkloadRequestSchema, { workloadId: containerId, timeoutSec });
await unary(RUNNER_SERVICE_STOP_WORKLOAD_PATH, request, (req, metadata, callback) => {
await unary(request, (req, metadata, callback) => {
client.stopWorkload(req, metadata, callback);
});
};
Expand All @@ -113,21 +97,21 @@ export function createGrpcTestClient(options: {
force: options.force ?? false,
removeVolumes: options.removeVolumes ?? false,
});
await unary(RUNNER_SERVICE_REMOVE_WORKLOAD_PATH, request, (req, metadata, callback) => {
await unary(request, (req, metadata, callback) => {
client.removeWorkload(req, metadata, callback);
});
};

const inspectContainer = async (containerId: string): Promise<InspectWorkloadResponse> => {
const request = create(InspectWorkloadRequestSchema, { workloadId: containerId });
return unary(RUNNER_SERVICE_INSPECT_WORKLOAD_PATH, request, (req, metadata, callback) => {
return unary(request, (req, metadata, callback) => {
client.inspectWorkload(req, metadata, callback);
});
};

const ready = async (): Promise<ReadyResponse> => {
const request = create(ReadyRequestSchema, {});
return unary(RUNNER_SERVICE_READY_PATH, request, (req, metadata, callback) => {
return unary(request, (req, metadata, callback) => {
client.ready(req, metadata, callback);
});
};
Expand Down
165 changes: 0 additions & 165 deletions src/contracts/auth.ts

This file was deleted.

23 changes: 0 additions & 23 deletions src/contracts/json.ts

This file was deleted.

2 changes: 0 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ export * from './lib/containerRegistry.port.ts';
export * from './lib/dockerClient.port.ts';
export * from './lib/execTimeout.ts';
export * from './lib/types.ts';
export * from './contracts/auth.ts';
export * from './contracts/json.ts';
export * from './contracts/api.ts';
export * from './contracts/workload.grpc.ts';
export { createRunnerGrpcServer } from './service/grpc/server.ts';
Expand Down
10 changes: 0 additions & 10 deletions src/service/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@ const runnerConfigSchema = z.object({
return Number.isFinite(num) ? num : 50051;
}),
grpcHost: z.string().default('0.0.0.0'),
sharedSecret: z.string().min(1, 'DOCKER_RUNNER_SHARED_SECRET is required'),
signatureTtlMs: z
.union([z.string(), z.number()])
.default('60000')
.transform((value) => {
const num = typeof value === 'number' ? value : Number(value);
return Number.isFinite(num) ? num : 60_000;
}),
dockerSocket: z.string().default('/var/run/docker.sock'),
logLevel: z.enum(['trace', 'debug', 'info', 'warn', 'error', 'fatal']).default('info'),
});
Expand All @@ -28,8 +20,6 @@ export function loadRunnerConfig(env: NodeJS.ProcessEnv = process.env): RunnerCo
const parsed = runnerConfigSchema.safeParse({
grpcPort: grpcPortEnv,
grpcHost: env.DOCKER_RUNNER_GRPC_HOST,
sharedSecret: env.DOCKER_RUNNER_SHARED_SECRET,
signatureTtlMs: env.DOCKER_RUNNER_SIGNATURE_TTL_MS,
dockerSocket: env.DOCKER_SOCKET ?? env.DOCKER_RUNNER_SOCKET,
logLevel: env.DOCKER_RUNNER_LOG_LEVEL,
});
Expand Down
Loading
Loading