Skip to content

Commit

Permalink
Merge pull request #7 from lightningrodlabs/v0-2-0
Browse files Browse the repository at this point in the history
V0 2 0
  • Loading branch information
Connoropolous committed Sep 27, 2022
2 parents d5cb7fa + d8197ad commit a0a36ee
Show file tree
Hide file tree
Showing 8 changed files with 24 additions and 181 deletions.
8 changes: 3 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,10 @@
# electron-holochain

> Holochain Revision: [v0.0.156 August 23, 2022](https://github.com/holochain/holochain/blob/main/CHANGELOG.md#20220823103320)
>
> Lair Keystore Revision: [v0.2.0 June 20, 2022](https://github.com/holochain/lair/releases/tag/lair_keystore-v0.2.0)
> Holochain Revision: [v0.0.162 September 14, 2022](https://github.com/holochain/holochain/blob/main/CHANGELOG.md#20220914013149)
>
> Expects an HAPP built with HDK [v0.0.147](https://docs.rs/hdk/0.0.147/hdk/index.html) and HDI [v0.0.19](https://docs.rs/hdi/0.0.19/hdi/index.html)
> Expects an HAPP built with HDK [v0.0.152](https://docs.rs/hdk/0.0.152/hdk/index.html) and HDI [v0.1.2](https://docs.rs/hdi/0.1.2/hdi/index.html)
manage holochain processes during an electron application runtime, using [holochain-runner binaries](https://github.com/lightningrodlabs/holochain-runner).
manage holochain processes during an electron application runtime, using [holochain-runner binary](https://github.com/lightningrodlabs/holochain-runner).

```typescript
// function initAgent(
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@lightningrodlabs/electron-holochain",
"version": "0.1.0",
"description": "manage holochain processes during an electron application runtime",
"version": "0.2.0",
"description": "manage holochain as a sub-process within an electron application runtime",
"main": "dist/src/index.js",
"scripts": {
"build": "tsc",
Expand Down
8 changes: 0 additions & 8 deletions src/binaries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import * as path from 'path'

const windowsExtension = process.platform === 'win32' ? '.exe' : ''
const holochainRunnerBinName = `holochain-runner${windowsExtension}`
const lairKeystoreBinName = `lair-keystore${windowsExtension}`

const binariesDirectory = path.join(
__dirname,
Expand All @@ -15,15 +14,8 @@ const defaultHolochainRunnerBinaryPath = path.join(
holochainRunnerBinName
)

const defaultLairKeystoreBinaryPath = path.join(
binariesDirectory,
lairKeystoreBinName
)

export {
holochainRunnerBinName,
lairKeystoreBinName,
binariesDirectory,
defaultHolochainRunnerBinaryPath,
defaultLairKeystoreBinaryPath,
}
11 changes: 1 addition & 10 deletions src/downloadBinaries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import * as tar from 'tar'
import {
binariesDirectory,
defaultHolochainRunnerBinaryPath,
defaultLairKeystoreBinaryPath,
} from './binaries.js'

async function download(url: string, dest: string) {
Expand Down Expand Up @@ -41,13 +40,6 @@ async function downloadBinaries(tag: string) {
darwin: 'holochain-runner-x86_64-apple-darwin.tar.gz',
linux: 'holochain-runner-x86_64-unknown-linux-gnu.tar.gz'
}
const lairKeystoreFilenames = {
win32: 'lair-keystore-x86_64-pc-windows-msvc.exe',
darwin: 'lair-keystore-x86_64-apple-darwin',
linux: 'lair-keystore-x86_64-unknown-linux-gnu'
}
const lairKeystoreUrl = `https://github.com/lightningrodlabs/holochain-runner/releases/download/${tag}/${lairKeystoreFilenames[process.platform]}`
await download(lairKeystoreUrl, defaultLairKeystoreBinaryPath)
const holochainRunnerCompressedUrl = `https://github.com/lightningrodlabs/holochain-runner/releases/download/${tag}/${holochainRunnerFilenames[process.platform]}`
const compressedTempFilename = path.join(
binariesDirectory,
Expand All @@ -57,15 +49,14 @@ async function downloadBinaries(tag: string) {
await tar.x({ file: compressedTempFilename, cwd: binariesDirectory })
fs.rmSync(compressedTempFilename)
// defaultHolochainRunnerBinaryPath
await chmod(defaultLairKeystoreBinaryPath, 511)
await chmod(defaultHolochainRunnerBinaryPath, 511)
}

;(async () => {
try {
// current holochain-runner release version
// version-bump
const holochainRunnerTag = 'v0.1.0'
const holochainRunnerTag = 'v0.2.0'
await downloadBinaries(holochainRunnerTag)
} catch (e) {
console.log(e)
Expand Down
95 changes: 4 additions & 91 deletions src/holochain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
} from './options.js'
import {
defaultHolochainRunnerBinaryPath,
defaultLairKeystoreBinaryPath,
} from './binaries.js'


Expand All @@ -24,13 +23,10 @@ type ERROR_EVENT = 'error'
const ERROR_EVENT = 'error'
type HOLOCHAIN_RUNNER_QUIT = 'holochain_runner_quit'
const HOLOCHAIN_RUNNER_QUIT = 'holochain_runner_quit'
type LAIR_KEYSTORE_QUIT = 'lair_keystore_quit'
const LAIR_KEYSTORE_QUIT = 'lair_keystore_quit'
export {
STATUS_EVENT,
APP_PORT_EVENT,
ERROR_EVENT,
LAIR_KEYSTORE_QUIT,
HOLOCHAIN_RUNNER_QUIT,
}

Expand All @@ -40,7 +36,6 @@ export declare interface StatusUpdates {
| STATUS_EVENT
| APP_PORT_EVENT
| ERROR_EVENT
| LAIR_KEYSTORE_QUIT
| HOLOCHAIN_RUNNER_QUIT,
listener: (status: StateSignal | string | Error) => void
): this
Expand All @@ -59,9 +54,6 @@ export class StatusUpdates extends EventEmitter {
emitHolochainRunnerQuit(): void {
this.emit(HOLOCHAIN_RUNNER_QUIT)
}
emitLairKeystoreQuit(): void {
this.emit(LAIR_KEYSTORE_QUIT)
}
}

export enum StateSignal {
Expand Down Expand Up @@ -112,99 +104,21 @@ export async function runHolochain(
options: ElectronHolochainOptions,
pathOptions?: PathOptions
): Promise<{
lairHandle: childProcess.ChildProcessWithoutNullStreams
holochainRunnerHandle: childProcess.ChildProcessWithoutNullStreams
}> {
const lairKeystoreBinaryPath = pathOptions
? pathOptions.lairKeystoreBinaryPath
: defaultLairKeystoreBinaryPath
const holochainRunnerBinaryPath = pathOptions
? pathOptions.holochainRunnerBinaryPath
: defaultHolochainRunnerBinaryPath

if (!checkLairInitialized(options.keystorePath)) {
if (options.keystorePath && !checkLairInitialized(options.keystorePath)) {
fs.mkdirSync(options.keystorePath, {
recursive: true
})
// similar occurs in Holochain Launcher
// https://github.com/holochain/launcher/blob/743420b717249e7c8807e04522a21288127d8d1e/crates/lair_keystore_manager/src/versions/init.rs#L13-L21
// first we have to initialize lair-keystore
// IF not already initialized
// p for "piped", relates to piping in the passphrase
const lairInitHandle = childProcess.spawn(lairKeystoreBinaryPath, ['init', '-p'], {
cwd: options.keystorePath,
})
lairInitHandle.on('error', (e) => {
console.error('there was an error during lair-keystore init -p', e)
})
await new Promise<void>((resolve, reject) => {
lairInitHandle.stdout.on('data', (chunk) => {
if (chunk.toString().includes('lair-keystore init connection_url')) {
resolve()
}
})
lairInitHandle.stderr.on('data', (chunk) => {
console.error('error during lair-keystore init', chunk.toString())
reject(new Error(chunk.toString()))
})
console.log('writing passphrase to `lair-keystore init -p`')
lairInitHandle.stdin.write(options.passphrase)
lairInitHandle.stdin.end()
})
}

// p for "piped", relates to piping in the passphrase
const lairHandle = childProcess.spawn(lairKeystoreBinaryPath, [
'server',
'-p',
], {
cwd: options.keystorePath
})
// write the passphrase in
lairHandle.stdin.write(options.passphrase)
lairHandle.stdin.end()

await new Promise<void>((resolve, reject) => {
lairHandle.stdout.on('data', (chunk) => {
if (chunk.toString().includes('lair-keystore running')) {
resolve()
}
})

lairHandle.stdout.on('error', (error) => {
if (lairHandle.killed) return;
console.error('lair-keystore stdout err > ' + error)
statusEmitter.emitError(error)
})
lairHandle.stderr.on('data', (error) => {
if (lairHandle.killed) return;
console.error('lair-keystore stderr err' + error.toString())
statusEmitter.emitError(error)
reject(new Error(error.toString()))
})
lairHandle.on('error', (error) => {
if (lairHandle.killed) return;
console.error('lair-keystore err > ' + error.toString())
statusEmitter.emitError(error)
})
lairHandle.on('close', (code) => {
if (lairHandle.killed) return;
console.log('lair-keystore closed with code: ', code)
statusEmitter.emitLairKeystoreQuit()
})
})

// translate from ElectronHolochainOptions to HolochainRunnerOptions
const { keystorePath, ...restOfOptions } = options
// get the keystoreUrl for passing to holochain-runner
const keystoreUrl = childProcess.spawnSync(lairKeystoreBinaryPath, ['url'], {
cwd: options.keystorePath
}).stdout.toString()
const holochainRunnerOptions = {
...restOfOptions,
keystoreUrl
}
const optionsArray = constructOptions(holochainRunnerOptions)
const optionsArray = constructOptions(options)
// spawn holochain-runner and pass it a version
// of the given options that it can digest
const holochainRunnerHandle = childProcess.spawn(
holochainRunnerBinaryPath,
optionsArray
Expand Down Expand Up @@ -249,7 +163,6 @@ export async function runHolochain(
})

return {
lairHandle,
holochainRunnerHandle,
}
}
Expand Down
50 changes: 3 additions & 47 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,10 @@ import {
STATUS_EVENT,
APP_PORT_EVENT,
ERROR_EVENT,
LAIR_KEYSTORE_QUIT,
HOLOCHAIN_RUNNER_QUIT,
} from './holochain'
import {
defaultHolochainRunnerBinaryPath,
defaultLairKeystoreBinaryPath,
} from './binaries'
import * as childProcess from 'child_process'
import * as fs from 'fs'
Expand All @@ -26,7 +24,6 @@ export {
PathOptions,
APP_PORT_EVENT,
ERROR_EVENT,
LAIR_KEYSTORE_QUIT,
HOLOCHAIN_RUNNER_QUIT,
}

Expand All @@ -44,27 +41,25 @@ export default async function initAgent(
// execute this in a callback
// so that we can continue and return
// the statusEmitter to the caller
let lairHandle: childProcess.ChildProcessWithoutNullStreams
let holochainRunnerHandle: childProcess.ChildProcessWithoutNullStreams
;(async () => {
let handles = await runHolochain(
statusEmitter,
opts,
binaryPaths
)
lairHandle = handles.lairHandle
holochainRunnerHandle = handles.holochainRunnerHandle

app.on('will-quit', async () => {
// SIGTERM signal is the default, and that's good
await killHolochain(lairHandle, holochainRunnerHandle)
await killHolochain(holochainRunnerHandle)
})
})()
return {
statusEmitter,
shutdown: async () => {
// SIGTERM signal is the default, and that's good
await killHolochain(lairHandle, holochainRunnerHandle)
await killHolochain(holochainRunnerHandle)
},
}
}
Expand All @@ -80,7 +75,6 @@ function sleep(ms) {
* Kill handles and their children
*/
async function killHolochain(
lairHandle: childProcess.ChildProcessWithoutNullStreams,
holochainRunnerHandle: childProcess.ChildProcessWithoutNullStreams
) {
// Kill holochain and its children
Expand All @@ -98,25 +92,10 @@ async function killHolochain(
})
holochainRunnerHandle.kill()
}
// Kill lair-keystore and its children
let canWaitForKeystore = false
if (lairHandle && lairHandle.pid) {
canWaitForKeystore = true
console.debug('Killing lair-keystore sub processes...')
kill(lairHandle.pid, function (err) {
canWaitForKeystore = false
if (!err) {
console.debug('killed all lair-keystore sub processes')
} else {
console.error(err)
}
})
lairHandle.kill()
}
// Wait for the kill commands to complete and exit anyway after a timeout
console.debug('waiting...')
const start_time = Date.now()
while (canWaitForHolochain || canWaitForKeystore) {
while (canWaitForHolochain) {
await sleep(10)
if (Date.now() - start_time > 5 * 1000) {
console.error('Killing sub-processes TIMED-OUT. Aborted.')
Expand Down Expand Up @@ -154,26 +133,3 @@ export function getRunnerVersion(runnerBinaryPath?: string): string {

return holochainHandle.stdout.toString()
}

/**
*
*/
export function getLairVersion(lairBinaryPath?: string): string {
const binaryPath: string = lairBinaryPath
? lairBinaryPath
: defaultLairKeystoreBinaryPath

if (!fs.existsSync(binaryPath)) {
console.error('lair-keystore binary not found at path: ' + binaryPath)
return 'lair-keystore missing'
}

const handle = childProcess.spawnSync(binaryPath, ['--version'])

if (handle.error) {
console.error('Calling lair-keystore failed: ' + handle.error.message)
return 'lair-keystore broken'
}

return handle.stdout.toString()
}
Loading

0 comments on commit a0a36ee

Please sign in to comment.