Skip to content

Commit

Permalink
binary download
Browse files Browse the repository at this point in the history
  • Loading branch information
alexfreska committed Jan 31, 2024
1 parent ce49c9d commit 3e76202
Show file tree
Hide file tree
Showing 15 changed files with 182 additions and 170 deletions.
5 changes: 4 additions & 1 deletion hostd/main/binary.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import * as path from 'path'
import { env } from './env'

export function getBinaryDirectoryPath(): string {
return path.join(__dirname, '../bin')
return env.isDev
? path.join(process.cwd(), 'bin')
: path.join(__dirname, '../bin')
}

export function getBinaryFilePath(): string {
Expand Down
87 changes: 32 additions & 55 deletions hostd/main/daemon.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,39 @@
import { spawn } from 'child_process'
import { state } from './state'
import { getConfig, getConfigFilePath } from './config'
import axios from 'axios'
import { getBinaryFilePath } from './binary'
import path from 'path'
import fs from 'fs'
import { getBinaryDirectoryPath, getBinaryFilePath } from './binary'

export function startDaemon(): Promise<void> {
return new Promise(async (resolve, reject) => {
export async function startDaemon(): Promise<void> {
try {
await stopDaemon()
const config = getConfig()
const binaryFilePath = getBinaryFilePath()
state.daemon = spawn(binaryFilePath, ['-env'], {
env: { ...process.env, HOSTD_CONFIG_FILE: getConfigFilePath() },
cwd: config.directory,
})

try {
const config = getConfig()
const binaryFilePath = getBinaryFilePath()
state.daemon = spawn(binaryFilePath, ['-env'], {
env: { ...process.env, HOSTD_CONFIG_FILE: getConfigFilePath() },
cwd: config.directory,
})

state.daemon.stdout?.on('data', (data) => {
console.log(`stdout: ${data}`)
// Emit events or log data as needed
})

state.daemon.stderr?.on('data', (data) => {
console.error(`stderr: ${data}`)
// Emit events or log data as needed
})
state.daemon.stdout?.on('data', (data) => {
console.log(`stdout: ${data}`)
// Emit events or log data as needed
})

state.daemon.on('close', (code) => {
console.log(`child process exited with code ${code}`)
state.daemon = null
})
state.daemon.stderr?.on('data', (data) => {
console.error(`stderr: ${data}`)
// Emit events or log data as needed
})

resolve()
} catch (err) {
state.daemon.on('close', (code) => {
console.log(`child process exited with code ${code}`)
state.daemon = null
reject(err)
}
})
})
} catch (err) {
console.log('Failed to start daemon', err)
state.daemon = null
throw err
}
}

export function stopDaemon(): Promise<void> {
Expand All @@ -60,31 +57,11 @@ export function getIsDaemonRunning(): boolean {
}

export async function getInstalledVersion(): Promise<string> {
if (!getIsDaemonRunning()) {
return ''
}
const config = getConfig()
let address = config.http.address
? 'http://' + config.http.address
: 'http://127.0.0.1:9980'

// localhost tries to uses ipv6, which the daemon does not support
address = address.replace('http://localhost:', 'http://127.0.0.1:')

const versionFilePath = path.join(getBinaryDirectoryPath(), 'version')
try {
const auth = Buffer.from(`:${config.http.password}`).toString('base64')
const response = await axios.get<{ version: string }>(
address + '/api/state/host',
{
headers: {
'Content-Type': 'application/json',
Authorization: `Basic ${auth}`,
},
}
)
return response.data.version
} catch (err) {
console.error(err)
return ''
const version = await fs.promises.readFile(versionFilePath, 'utf8')
return version
} catch (e) {
return 'error: no daemon'
}
}
2 changes: 0 additions & 2 deletions hostd/main/preload.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ contextBridge.exposeInMainWorld('electron', {
checkIsDaemonRunning: () => ipcRenderer.invoke('daemon-is-running'),
daemonStart: () => ipcRenderer.invoke('daemon-start'),
daemonStop: () => ipcRenderer.invoke('daemon-stop'),
daemonUpdate: () => ipcRenderer.invoke('daemon-update'),
openBrowser: (url: string) => ipcRenderer.invoke('open-browser', url),
getConfig: () => ipcRenderer.invoke('config-get'),
saveConfig: (config: Config) => ipcRenderer.invoke('config-save', config),
Expand All @@ -20,5 +19,4 @@ contextBridge.exposeInMainWorld('electron', {
getDefaultDataDirectory: () =>
ipcRenderer.invoke('get-default-data-directory'),
getInstalledVersion: () => ipcRenderer.invoke('get-installed-version'),
getLatestVersion: () => ipcRenderer.invoke('get-latest-version'),
})
13 changes: 7 additions & 6 deletions hostd/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,13 @@
},
"main": "dist/main/index.js",
"scripts": {
"clean": "rimraf out dist renderer/.next",
"dev": "npm run build-electron && electron .",
"build-renderer": "next build renderer",
"build-electron": "tsc -p main",
"download-daemon": "npm run build-electron && node main/download.js",
"build": "npm run build-renderer && npm run build-electron",
"clean": "rimraf bin out dist renderer/.next",
"dev": "npm run build:main && electron .",
"build": "npm run build:renderer && npm run build:main",
"build:renderer": "next build renderer",
"build:main": "tsc -p main",
"build:scripts": "tsc -p scripts",
"download:binary": "npm run build:scripts && node dist/scripts/download.js",
"type-check": "tsc -p ./renderer/tsconfig.json && tsc -p ./main/tsconfig.json",
"start": "electron-forge start",
"package": "electron-forge package",
Expand Down
17 changes: 0 additions & 17 deletions hostd/renderer/components/useIsDaemonRunning.tsx

This file was deleted.

32 changes: 25 additions & 7 deletions hostd/main/download.ts → hostd/scripts/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ import admZip from 'adm-zip'
import { promisify } from 'util'
import stream from 'stream'
import axios from 'axios'
import { system } from './system'
import { getBinaryDirectoryPath, getBinaryFilePath } from './binary'

downloadRelease()

// export async function getLatestVersion(): Promise<string> {
// async function getLatestVersion(): Promise<string> {
// try {
// const octokit = new Octokit()
// const response = await octokit.repos.getLatestRelease({
Expand All @@ -24,7 +22,7 @@ downloadRelease()
// }
// }

export async function downloadRelease(): Promise<void> {
async function downloadRelease(): Promise<void> {
try {
const octokit = new Octokit()
const releaseData = await octokit.repos.getLatestRelease({
Expand Down Expand Up @@ -76,7 +74,7 @@ async function extractBinary(): Promise<void> {
const zip = new admZip(zipFilePath)
zip.extractAllTo(extractDir, true)

const binaryName = process.platform === 'win32' ? 'hostd.exe' : 'hostd'
const binaryName = system.isWindows ? 'hostd.exe' : 'hostd'
const extractedBinaryPath = path.join(extractDir, binaryName)
const finalBinaryPath = getBinaryFilePath()

Expand All @@ -102,7 +100,7 @@ function getTempDownloadsPath(): string {
}

function getBinaryZipStagingPath(): string {
const binaryName = system.isWindows ? `hostd.exe` : `hostd`
const binaryName = process.platform === 'win32' ? `hostd.exe` : `hostd`
return path.join(getTempDownloadsPath(), binaryName + '.zip')
}

Expand Down Expand Up @@ -140,5 +138,25 @@ function releaseAsset(): string {
}
}

return `hostd_${goos}_${goarch}.zip`
return `renterd_${goos}_${goarch}.zip`
}

function getBinaryDirectoryPath(): string {
// running from dist/main/download.ts
return path.join(__dirname, '../../bin')
}

function getBinaryFilePath(): string {
const binaryName = process.platform === 'win32' ? 'hostd.exe' : 'hostd'
return path.join(getBinaryDirectoryPath(), binaryName)
}

const system: {
isDarwin: boolean
isLinux: boolean
isWindows: boolean
} = {
isDarwin: process.platform === 'darwin',
isLinux: process.platform === 'linux',
isWindows: process.platform === 'win32',
}
24 changes: 24 additions & 0 deletions hostd/scripts/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"compilerOptions": {
"allowJs": true,
"alwaysStrict": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"isolatedModules": true,
"jsx": "preserve",
"lib": ["dom", "es2017"],
"module": "commonjs",
"moduleResolution": "node",
"noEmit": false,
"noFallthroughCasesInSwitch": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"strict": true,
"target": "esnext",
"outDir": "../dist/scripts"
},
"exclude": ["node_modules"],
"include": ["**/*.ts", "**/*.tsx", "**/*.js"]
}
5 changes: 4 additions & 1 deletion renterd/main/binary.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import * as path from 'path'
import { env } from './env'

export function getBinaryDirectoryPath(): string {
return path.join(__dirname, '../bin')
return env.isDev
? path.join(process.cwd(), 'bin')
: path.join(__dirname, '../bin')
}

export function getBinaryFilePath(): string {
Expand Down
87 changes: 34 additions & 53 deletions renterd/main/daemon.ts
Original file line number Diff line number Diff line change
@@ -1,42 +1,40 @@
import { spawn } from 'child_process'
import { state } from './state'
import { getConfig, getConfigFilePath } from './config'
import { getBinaryFilePath } from './binary'
import axios from 'axios'
import { getBinaryDirectoryPath, getBinaryFilePath } from './binary'
import path from 'path'
import fs from 'fs'

export function startDaemon(): Promise<void> {
return new Promise(async (resolve, reject) => {
export async function startDaemon(): Promise<void> {
try {
await stopDaemon()
const config = getConfig()
const binaryFilePath = getBinaryFilePath()
state.daemon = spawn(binaryFilePath, [], {
env: { ...process.env, RENTERD_CONFIG_FILE: getConfigFilePath() },
cwd: config.directory,
})

try {
const config = getConfig()
const binaryFilePath = getBinaryFilePath()
state.daemon = spawn(binaryFilePath, [], {
env: { ...process.env, RENTERD_CONFIG_FILE: getConfigFilePath() },
cwd: config.directory,
})

state.daemon.stdout?.on('data', (data) => {
console.log(`stdout: ${data}`)
// Emit events or log data as needed
})

state.daemon.stderr?.on('data', (data) => {
console.error(`stderr: ${data}`)
// Emit events or log data as needed
})
state.daemon.stdout?.on('data', (data) => {
console.log(`stdout: ${data}`)
// Emit events or log data as needed
})

state.daemon.on('close', (code) => {
console.log(`child process exited with code ${code}`)
state.daemon = null
})
state.daemon.stderr?.on('data', (data) => {
console.error(`stderr: ${data}`)
// Emit events or log data as needed
})

resolve()
} catch (err) {
state.daemon.on('close', (code) => {
console.log(`child process exited with code ${code}`)
state.daemon = null
reject(err)
}
})
})
} catch (err) {
console.log('Failed to start daemon', err)
state.daemon = null
console.log('state is', state)
throw err
}
}

export function stopDaemon(): Promise<void> {
Expand All @@ -56,33 +54,16 @@ export function stopDaemon(): Promise<void> {
}

export function getIsDaemonRunning(): boolean {
console.log('daemon', state)
return !!state.daemon && !state.daemon.killed
}

export async function getInstalledVersion(): Promise<string> {
if (!getIsDaemonRunning()) {
return ''
}
const config = getConfig()
let address = config.http.address
? 'http://' + config.http.address
: 'http://127.0.0.1:9980'

// localhost tries to uses ipv6, which the daemon does not support
address = address.replace('http://localhost:', 'http://127.0.0.1:')

const versionFilePath = path.join(getBinaryDirectoryPath(), 'version')
try {
const response = await axios.get<{ version: string }>(
address + '/api/bus/state',
{
headers: {
Authorization: 'Basic ' + btoa(':' + config.http.password),
},
}
)
return response.data.version
} catch (err) {
console.error(err)
return ''
const version = await fs.promises.readFile(versionFilePath, 'utf8')
return version
} catch (e) {
return 'error: no daemon'
}
}
Loading

0 comments on commit 3e76202

Please sign in to comment.