Skip to content

Commit

Permalink
add forked docker process (#39)
Browse files Browse the repository at this point in the history
Resolves #40.
  • Loading branch information
Courey authored Jun 24, 2024
1 parent 66a2073 commit 32de9b7
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 27 deletions.
1 change: 1 addition & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { pathToFileURL } from 'url'
import { launch } from './run.js'
import { populate } from './data.js'
import { search as getSearchClient } from '@nasa-gcn/architect-functions-search'
import './launchSearch'
import {
cloudformationResources as serverlessCloudformationResources,
services as serverlessServices,
Expand Down
53 changes: 53 additions & 0 deletions launchSearch.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*!
* Copyright © 2023 United States Government as represented by the
* Administrator of the National Aeronautics and Space Administration.
* All Rights Reserved.
*
* SPDX-License-Identifier: Apache-2.0
*/

import Dockerode from 'dockerode'

const [, , command, jsonifiedArgs] = process.argv

if (command === 'launch-docker-subprocess') {
const dockerContainer = await launchDockerSearch()

const signals = ['message', 'SIGTERM', 'SIGINT']
signals.forEach((signal) => {
process.on(signal, async () => {
await dockerContainer.kill()
})
})

await dockerContainer.wait()
}

async function launchDockerSearch() {
const { dataDir, logsDir, engine, port, options } = JSON.parse(jsonifiedArgs)
const Image =
engine === 'elasticsearch'
? 'elastic/elasticsearch:8.6.2'
: 'opensearchproject/opensearch:2.11.0'
console.log('Launching Docker container', Image)
const docker = new Dockerode()

const container = await docker.createContainer({
Env: [...options, 'path.data=/var/lib/search', 'path.logs=/var/log/search'],
HostConfig: {
AutoRemove: true,
Mounts: [
{ Source: dataDir, Target: '/var/lib/search', Type: 'bind' },
{ Source: logsDir, Target: '/var/log/search', Type: 'bind' },
],
PortBindings: {
[`${port}/tcp`]: [{ HostIP: '127.0.0.1', HostPort: `${port}` }],
},
},
Image,
})
const stream = await container.attach({ stream: true, stderr: true })
stream.pipe(process.stderr)
await container.start()
return container
}
50 changes: 24 additions & 26 deletions run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ import { mkdirP, temp } from './paths.js'
import rimraf from 'rimraf'
import { spawn, untilTerminated } from './processes.js'
import type { SandboxEngine } from './engines.js'
import Dockerode from 'dockerode'
import { UnexpectedResolveError, neverResolve } from './promises.js'
import { fork } from 'child_process'
import { fileURLToPath } from 'url'

type SearchEngineLauncherFunction<T = object> = (
props: T & {
Expand Down Expand Up @@ -63,37 +64,34 @@ const launchDocker: SearchEngineLauncherFunction = async ({
port,
options,
}) => {
const Image =
engine === 'elasticsearch'
? 'elastic/elasticsearch:8.6.2'
: 'opensearchproject/opensearch:2.11.0'
console.log('Launching Docker container', Image)
const docker = new Dockerode()
const container = await docker.createContainer({
Env: [...options, 'path.data=/var/lib/search', 'path.logs=/var/log/search'],
HostConfig: {
AutoRemove: true,
Mounts: [
{ Source: dataDir, Target: '/var/lib/search', Type: 'bind' },
{ Source: logsDir, Target: '/var/log/search', Type: 'bind' },
],
PortBindings: {
[`${port}/tcp`]: [{ HostIP: '127.0.0.1', HostPort: `${port}` }],
},
},
Image,
})
const stream = await container.attach({ stream: true, stderr: true })
stream.pipe(process.stderr)
await container.start()
const argv = {
dataDir,
logsDir,
engine,
port,
options,
}
// FIXME: fork accepts either a string or URL as the first argument. @types/node has defined the modulePath type as string only.
// new URL(import.meta.url) may be used in place of __filename once this has been updated.
// see: https://github.com/DefinitelyTyped/DefinitelyTyped/discussions/69812
const __filename = fileURLToPath(import.meta.url)
const subprocess = fork(__filename, [
'launch-docker-subprocess',
JSON.stringify(argv),
])

return {
async kill() {
console.log('Killing Docker container')
await container.kill()
subprocess.send({ action: 'kill' })
},
async waitUntilStopped() {
await container.wait()
return new Promise((resolve) => {
subprocess.on('exit', () => {
console.log('Docker container exited')
resolve()
})
})
},
}
}
Expand Down
4 changes: 3 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
{
"extends": "@tsconfig/node14/tsconfig.json",
"compilerOptions": {
"resolveJsonModule": true
"resolveJsonModule": true,
"module": "esnext",
"target": "es2022"
}
}

0 comments on commit 32de9b7

Please sign in to comment.