feat: add bundled Windows native runtime
This commit is contained in:
+3
-1
@@ -14,6 +14,7 @@ import { registerRemoteIpc } from './ipc/remote'
|
||||
import { registerRuntimeIpc } from './ipc/runtime'
|
||||
import { killAllRunningCommands, powerOffAllProjects } from './commandRunner'
|
||||
import { startAutomaticUpdates } from './updater'
|
||||
import { ensureBundledNativeRuntime } from './nativeRuntime'
|
||||
|
||||
function createWindow(): void {
|
||||
// Create the browser window.
|
||||
@@ -51,7 +52,7 @@ function createWindow(): void {
|
||||
// This method will be called when Electron has finished
|
||||
// initialization and is ready to create browser windows.
|
||||
// Some APIs can only be used after this event occurs.
|
||||
app.whenReady().then(() => {
|
||||
app.whenReady().then(async () => {
|
||||
// Set app user model id for windows
|
||||
electronApp.setAppUserModelId('com.aurora-dockside.app')
|
||||
|
||||
@@ -73,6 +74,7 @@ app.whenReady().then(() => {
|
||||
registerRemoteIpc()
|
||||
registerRuntimeIpc()
|
||||
|
||||
await ensureBundledNativeRuntime()
|
||||
createWindow()
|
||||
startAutomaticUpdates()
|
||||
|
||||
|
||||
@@ -61,7 +61,16 @@ async function runDatabasePipe(
|
||||
docroot: config.docroot,
|
||||
ports: config.nativePorts
|
||||
})
|
||||
command = join(runtimeRoot(), 'bin', mode === 'dump' ? 'mariadb-dump' : 'mariadb')
|
||||
command =
|
||||
process.platform === 'win32'
|
||||
? join(
|
||||
runtimeRoot(),
|
||||
'bin',
|
||||
'mariadb',
|
||||
'bin',
|
||||
mode === 'dump' ? 'mariadb-dump.exe' : 'mariadb.exe'
|
||||
)
|
||||
: join(runtimeRoot(), 'bin', mode === 'dump' ? 'mariadb-dump' : 'mariadb')
|
||||
args = [
|
||||
'--host=127.0.0.1',
|
||||
`--port=${config.nativePorts.database}`,
|
||||
|
||||
@@ -118,6 +118,7 @@ export function registerProjectsIpc(): void {
|
||||
const php = nativeServiceSpecs(native)
|
||||
.find((spec) => spec.id.endsWith(':php'))
|
||||
?.command.replace(/php-fpm$/, 'php')
|
||||
.replace(/php-cgi\.exe$/i, 'php.exe')
|
||||
if (!php) throw new Error('Native PHP executable not found.')
|
||||
return runCommandStreamed(id, php, ['-i'], e.sender, { cwd: native.root })
|
||||
}
|
||||
|
||||
@@ -109,8 +109,18 @@ export async function runModuleLifecycleHook(
|
||||
urls: urls ? Object.freeze(urls) : undefined,
|
||||
native: nativeDefinition
|
||||
? Object.freeze({
|
||||
php: join(runtimeRoot(), 'bin', 'php'),
|
||||
wp: join(runtimeRoot(), 'bin', 'wp'),
|
||||
php:
|
||||
process.platform === 'win32'
|
||||
? join(runtimeRoot(), 'bin', 'php', 'php.exe')
|
||||
: join(runtimeRoot(), 'bin', 'php'),
|
||||
wp:
|
||||
process.platform === 'win32'
|
||||
? join(runtimeRoot(), 'bin', 'php', 'php.exe')
|
||||
: join(runtimeRoot(), 'bin', 'wp'),
|
||||
wpPrefixArgs:
|
||||
process.platform === 'win32'
|
||||
? ['-d', 'memory_limit=512M', join(runtimeRoot(), 'tools', 'wp-cli.phar')]
|
||||
: [],
|
||||
databaseHost: '127.0.0.1',
|
||||
databasePort: nativeDefinition.ports.database,
|
||||
start: () => startNativeProject(nativeDefinition)
|
||||
|
||||
@@ -21,6 +21,14 @@ function installedRoot(project: NativeProjectDefinition): string {
|
||||
return project.installedRuntimeRoot ?? runtimeRoot()
|
||||
}
|
||||
|
||||
function runtimeExecutable(project: NativeProjectDefinition, name: string): string {
|
||||
if (process.platform !== 'win32') return join(installedRoot(project), 'bin', name)
|
||||
if (name === 'php' || name === 'php-cgi')
|
||||
return join(installedRoot(project), 'bin', 'php', `${name}.exe`)
|
||||
if (name === 'nginx') return join(installedRoot(project), 'bin', 'nginx', 'nginx.exe')
|
||||
return join(installedRoot(project), 'bin', 'mariadb', 'bin', `${name}.exe`)
|
||||
}
|
||||
|
||||
function nativeDirectory(root: string): string {
|
||||
return join(root, '.aurora', 'native')
|
||||
}
|
||||
@@ -109,7 +117,10 @@ http {
|
||||
}
|
||||
|
||||
export function renderNativeAdminerBootstrap(project: NativeProjectDefinition): string {
|
||||
const adminer = join(installedRoot(project), 'root', 'usr', 'share', 'aurora', 'adminer.php')
|
||||
const adminer =
|
||||
process.platform === 'win32'
|
||||
? join(installedRoot(project), 'tools', 'adminer.php')
|
||||
: join(installedRoot(project), 'root', 'usr', 'share', 'aurora', 'adminer.php')
|
||||
return `<?php
|
||||
// Generated by Aurora Core. This endpoint binds only to the project's loopback server.
|
||||
?>
|
||||
@@ -137,8 +148,12 @@ export function renderMariaDbConfig(
|
||||
installedRuntimeRoot = runtimeRoot()
|
||||
): string {
|
||||
const directory = nativeDirectory(project.root)
|
||||
const basedir =
|
||||
process.platform === 'win32'
|
||||
? join(installedRuntimeRoot, 'bin', 'mariadb')
|
||||
: join(installedRuntimeRoot, 'root', 'usr')
|
||||
return `[mariadbd]
|
||||
basedir=${join(installedRuntimeRoot, 'root', 'usr')}
|
||||
basedir=${basedir}
|
||||
datadir=${join(directory, 'data', 'mariadb')}
|
||||
tmpdir=${join(directory, 'tmp')}
|
||||
bind-address=127.0.0.1
|
||||
@@ -172,20 +187,30 @@ export async function provisionNativeProject(project: NativeProjectDefinition):
|
||||
writeFile(
|
||||
join(directory, 'config', 'mariadb.cnf'),
|
||||
renderMariaDbConfig(project, installedRoot(project))
|
||||
)
|
||||
),
|
||||
...(process.platform === 'win32'
|
||||
? [
|
||||
writeFile(
|
||||
join(directory, 'config', 'php.ini'),
|
||||
`extension_dir="${join(installedRoot(project), 'bin', 'php', 'ext')}"\nextension=mysqli\nextension=pdo_mysql\nextension=mbstring\nextension=curl\nextension=openssl\nextension=zip\ndisplay_errors=On\nlog_errors=On\nerror_log="${join(directory, 'logs', 'php.log')}"\n`
|
||||
)
|
||||
]
|
||||
: [])
|
||||
])
|
||||
try {
|
||||
await access(join(directory, 'data', 'mariadb', 'mysql'))
|
||||
} catch {
|
||||
await execFileAsync(
|
||||
join(installedRoot(project), 'bin', 'mariadb-install-db'),
|
||||
[
|
||||
'--no-defaults',
|
||||
`--datadir=${join(directory, 'data', 'mariadb')}`,
|
||||
`--tmpdir=${join(directory, 'tmp')}`,
|
||||
'--auth-root-authentication-method=normal',
|
||||
'--skip-test-db'
|
||||
],
|
||||
runtimeExecutable(project, 'mariadb-install-db'),
|
||||
process.platform === 'win32'
|
||||
? [`--datadir=${join(directory, 'data', 'mariadb')}`, '--password=']
|
||||
: [
|
||||
'--no-defaults',
|
||||
`--datadir=${join(directory, 'data', 'mariadb')}`,
|
||||
`--tmpdir=${join(directory, 'tmp')}`,
|
||||
'--auth-root-authentication-method=normal',
|
||||
'--skip-test-db'
|
||||
],
|
||||
{ cwd: project.root, maxBuffer: 16 * 1024 * 1024 }
|
||||
)
|
||||
}
|
||||
@@ -202,19 +227,32 @@ export function nativeServiceSpecs(project: NativeProjectDefinition): NativeServ
|
||||
return [
|
||||
{
|
||||
...common('database'),
|
||||
command: join(installedRoot(project), 'bin', 'mariadbd'),
|
||||
args: [`--defaults-file=${join(directory, 'config', 'mariadb.cnf')}`],
|
||||
command: runtimeExecutable(project, 'mariadbd'),
|
||||
args: [
|
||||
`--defaults-file=${join(directory, 'config', 'mariadb.cnf')}`,
|
||||
...(process.platform === 'win32' ? ['--console'] : [])
|
||||
],
|
||||
ready: { port: project.ports.database, timeoutMs: 30000 }
|
||||
},
|
||||
{
|
||||
...common('php'),
|
||||
command: join(installedRoot(project), 'bin', 'php-fpm'),
|
||||
args: ['--nodaemonize', '--fpm-config', join(directory, 'config', 'php-fpm.conf')],
|
||||
command: runtimeExecutable(project, process.platform === 'win32' ? 'php-cgi' : 'php-fpm'),
|
||||
args:
|
||||
process.platform === 'win32'
|
||||
? ['-b', `127.0.0.1:${project.ports.php}`]
|
||||
: ['--nodaemonize', '--fpm-config', join(directory, 'config', 'php-fpm.conf')],
|
||||
env:
|
||||
process.platform === 'win32'
|
||||
? {
|
||||
PHPRC: join(directory, 'config', 'php.ini'),
|
||||
PHP_FCGI_MAX_REQUESTS: '0'
|
||||
}
|
||||
: undefined,
|
||||
ready: { port: project.ports.php }
|
||||
},
|
||||
{
|
||||
...common('web'),
|
||||
command: join(installedRoot(project), 'bin', 'nginx'),
|
||||
command: runtimeExecutable(project, 'nginx'),
|
||||
args: ['-c', join(directory, 'config', 'nginx.conf'), '-p', `${directory}/`],
|
||||
ready: { port: project.ports.http }
|
||||
}
|
||||
|
||||
@@ -136,7 +136,13 @@ export async function installNativeRuntimeArchive(source: string): Promise<Auror
|
||||
validateArchiveEntries(stdout)
|
||||
await execFileAsync(
|
||||
'tar',
|
||||
['-xzf', source, '--no-same-owner', '--no-same-permissions', '-C', staging],
|
||||
[
|
||||
'-xzf',
|
||||
source,
|
||||
...(process.platform === 'win32' ? [] : ['--no-same-owner', '--no-same-permissions']),
|
||||
'-C',
|
||||
staging
|
||||
],
|
||||
{ maxBuffer: 16 * 1024 * 1024 }
|
||||
)
|
||||
await rejectLinks(staging)
|
||||
@@ -188,6 +194,16 @@ export async function installBundledNativeRuntime(): Promise<AuroraRuntimeStatus
|
||||
return installNativeRuntimeArchive(join(directory, basename(archive)))
|
||||
}
|
||||
|
||||
export async function ensureBundledNativeRuntime(): Promise<void> {
|
||||
if ((await nativeStatus()).available) return
|
||||
try {
|
||||
await installBundledNativeRuntime()
|
||||
} catch (error) {
|
||||
// Development builds and platforms without a packaged target keep the manual installer available.
|
||||
console.warn('Aurora Native bundled runtime was not installed:', error)
|
||||
}
|
||||
}
|
||||
|
||||
async function nativeStatus(): Promise<AuroraRuntimeStatus['native']> {
|
||||
if (!supportedPlatforms.has(process.platform) || !supportedArchitectures.has(process.arch))
|
||||
return {
|
||||
|
||||
Reference in New Issue
Block a user