Skip to content

Commit

Permalink
Support either ElasticSearch or OpenSearch in sandbox
Browse files Browse the repository at this point in the history
  • Loading branch information
lpsinger committed Nov 28, 2023
1 parent 894d36c commit ec8837d
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 43 deletions.
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

This is a [plugin](https://arc.codes/docs/en/guides/plugins/overview) for [Architect](https://arc.codes/) that provisions managed [Amazon OpenSearch](https://aws.amazon.com/opensearch-service/) for the application.

When you are using Architect's [sandbox](https://arc.codes/docs/en/reference/cli/sandbox) mode, the plugin [downloads and runs OpenSearch locally](https://opensearch.org/downloads.html#opensearch).
When you are using Architect's [sandbox](https://arc.codes/docs/en/reference/cli/sandbox) mode, the plugin [downloads and runs Elasticsearch](https://www.elastic.co/guide/en/elasticsearch/reference/current/install-elasticsearch.html#elasticsearch-install-packages) or [OpenSearch](https://opensearch.org/downloads.html#opensearch) locally.

Pair this pacakge with [@nasa-gcn/architect-functions-search](https://github.com/nasa-gcn/architect-functions-search) to connect to the service from your Node.js Lambda function code.

Expand All @@ -30,6 +30,8 @@ Pair this pacakge with [@nasa-gcn/architect-functions-search](https://github.com
# master nodes are disabled.
dedicatedMasterCount 3
dedicatedMasterType t3.small.search
# Use OpenSearch in sandbox mode; default is Elasticsearch.
sandboxEngine opensearch

4. Optionally, create a file called `sandbox-search.json` or `sandbox-search.js` in your project and populate it with sample data to be passed to [`client.bulk()`](https://github.com/opensearch-project/opensearch-js/blob/main/guides/bulk.md). Here are some examples.

Expand Down
60 changes: 60 additions & 0 deletions engines.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*!
* 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
*/

export type SandboxEngine = 'elasticsearch' | 'opensearch'

export const manifest = [
{
engine: 'elasticsearch',
type: 'Linux',
arch: 'x64',
url: 'https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.6.2-linux-x86_64.tar.gz',
},
{
engine: 'elasticsearch',
type: 'Linux',
arch: 'arm64',
url: 'https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.6.2-linux-aarch64.tar.gz',
},
{
engine: 'elasticsearch',
type: 'Darwin',
arch: 'x64',
url: 'https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.6.2-darwin-x86_64.tar.gz',
},
{
engine: 'elasticsearch',
type: 'Darwin',
arch: 'arm64',
url: 'https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.6.2-darwin-aarch64.tar.gz',
},
{
engine: 'elasticsearch',
type: 'Windows_NT',
arch: 'x64',
url: 'https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.6.2-windows-x86_64.zip',
},
{
engine: 'opensearch',
type: 'Linux',
arch: 'x64',
url: 'https://artifacts.opensearch.org/releases/bundle/opensearch/2.11.0/opensearch-2.11.0-linux-x64.tar.gz',
},
{
engine: 'opensearch',
type: 'Linux',
arch: 'arm64',
url: 'https://artifacts.opensearch.org/releases/bundle/opensearch/2.11.0/opensearch-2.11.0-linux-arm64.tar.gz',
},
{
engine: 'opensearch',
type: 'Windows_NT',
arch: 'x64',
url: 'https://artifacts.opensearch.org/releases/bundle/opensearch/2.11.0/opensearch-2.11.0-windows-x64.zip',
},
]
10 changes: 9 additions & 1 deletion index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,24 @@ export const deploy = {

let local: LocalSearch

function getEngine(name?: string) {
if (name?.toLowerCase() === 'opensearch') return 'opensearch'
else return 'elasticsearch'
}

export const sandbox = {
async start({
// @ts-expect-error: The Architect plugins API has no type definitions.
arc,
inventory: {
inv: {
// @ts-expect-error: The Architect plugins API has no type definitions.
_project: { cwd },
},
},
}) {
local = await launch({})
const engine = getEngine(getConfig(arc).sandboxEngine)
local = await launch({ engine })
await populate(cwd, { node: local.url })
},
async end() {
Expand Down
61 changes: 23 additions & 38 deletions install.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,40 +8,12 @@

import os from 'os'
import { pipeline } from 'stream/promises'
import { join } from 'path'
import { join, posix } from 'path'
import fetch from 'make-fetch-happen'
import { Extract as unzip } from 'unzip-stream'
import { x as untar } from 'tar'
import { cache, exists, mkdirP } from './paths.js'

const version = '2.11.0'

const types = new Map([
['Linux', ['linux', 'tar.gz']],
['Windows_NT', ['windows', 'zip']],
])

const archs = ['x64', 'arm64']

function getFilename() {
const os_type = os.type()
const os_arch = os.arch()

const typeInfo = types.get(os_type)

if (
!typeInfo ||
!archs.includes(os_arch) ||
(os_type === 'Windows_NT' && os_arch === 'arm64')
) {
throw new Error(
`No OpenSearch binary is available for your OS type (${os_type}) and architecture (${os_arch}). For supported operating systems, see https://opensearch.org/versions/opensearch-2-11-0.html.`
)
}

const [type, ext] = typeInfo
return { name: `opensearch-${version}-${type}-${os_arch}`, ext }
}
import { SandboxEngine, manifest } from './engines.js'

async function download(url: string) {
console.log('Downloading', url, 'to', cache)
Expand All @@ -50,26 +22,39 @@ async function download(url: string) {
return body
}

export async function install() {
const { name, ext } = getFilename()
const extractPath = join(cache, name)
const binExt = os.type() === 'Windows_NT' ? '.bat' : ''
export async function install(engine: SandboxEngine) {
const type = os.type()
const arch = os.arch()
const url = manifest.find(
(entry) =>
entry.engine === engine && entry.arch === arch && entry.type === type
)?.url
if (!url) {
throw new Error(
`No ${engine} binary is available for your OS type (${type}) and architecture (${arch}).`
)
}

const archiveFilename = posix
.basename(new URL(url).pathname)
.replace(/(.tar.gz|.zip)$/, '')
const extractPath = join(cache, archiveFilename)
const binExt = type === 'Windows_NT' ? '.bat' : ''
const binPath = join(
extractPath,
`opensearch-${version}`,
archiveFilename.split('-').slice(0, 2).join('-'),
'bin',
`opensearch${binExt}`
`${engine}${binExt}`
)

const binPathExists = await exists(binPath)

if (!binPathExists) {
const url = `https://artifacts.opensearch.org/releases/bundle/opensearch/${version}/${name}.${ext}`
const stream = await download(url)

let extract
if (url.endsWith('.tar.gz')) {
extract = untar({ cwd: extractPath })
extract = untar({ cwd: extractPath, strip: 1 })
} else if (url.endsWith('.zip')) {
extract = unzip({ path: extractPath })
} else {
Expand Down
15 changes: 12 additions & 3 deletions run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
} from './processes.js'
import { pipeline } from 'stream/promises'
import { createReadStream } from 'fs'
import type { SandboxEngine } from './engines.js'

export class LocalSearch {
private readonly child!: ChildProcess
Expand All @@ -36,11 +37,17 @@ export class LocalSearch {
return Object.assign(this, props)
}

static async launch({ port }: { port?: number }) {
static async launch({
port,
engine,
}: {
port?: number
engine: SandboxEngine
}) {
port ??= 9200
const url = `http://localhost:${port}`

const bin = await install()
const bin = await install(engine)
let child

await mkdirP(temp)
Expand All @@ -55,7 +62,9 @@ export class LocalSearch {
`-Epath.logs=${logsDir}`,
`-Ehttp.port=${port}`,
'-Ediscovery.type=single-node',
'-Eplugins.security.disabled=true',
engine === 'elasticsearch'
? '-Expack.security.enabled=false'
: '-Eplugins.security.disabled=true',
]

console.log('Spawning', bin, ...args)
Expand Down

0 comments on commit ec8837d

Please sign in to comment.