feat: run WordPress projects on native runtime
This commit is contained in:
@@ -1,5 +1,18 @@
|
||||
import { execFile } from 'child_process'
|
||||
import { createRequire } from 'module'
|
||||
import { mkdtemp, readFile, writeFile } from 'fs/promises'
|
||||
import { tmpdir } from 'os'
|
||||
import { join } from 'path'
|
||||
import { promisify } from 'util'
|
||||
import { describe, expect, it } from 'vitest'
|
||||
import { renderMariaDbConfig, renderNginxConfig, renderPhpFpmConfig } from './nativeProject'
|
||||
import {
|
||||
renderMariaDbConfig,
|
||||
renderNginxConfig,
|
||||
renderPhpFpmConfig,
|
||||
startNativeProject,
|
||||
stopNativeProject
|
||||
} from './nativeProject'
|
||||
import { allocateNativePorts } from './portAllocator'
|
||||
|
||||
const project = {
|
||||
name: 'demo',
|
||||
@@ -7,6 +20,7 @@ const project = {
|
||||
docroot: 'public',
|
||||
ports: { http: 41001, php: 41002, database: 41003, node: 41004 }
|
||||
}
|
||||
const execFileAsync = promisify(execFile)
|
||||
|
||||
describe('native project configuration', () => {
|
||||
it('isolates PHP-FPM on its allocated loopback port', () =>
|
||||
@@ -25,3 +39,89 @@ describe('native project configuration', () => {
|
||||
expect(config).toContain('/.aurora/native/data/mariadb')
|
||||
})
|
||||
})
|
||||
|
||||
it.runIf(Boolean(process.env.AURORA_NATIVE_SMOKE_ROOT))(
|
||||
'serves PHP through the complete native stack',
|
||||
async () => {
|
||||
const root = await mkdtemp(join(tmpdir(), 'aurora-native-project-'))
|
||||
await writeFile(join(root, 'index.php'), '<?php echo "aurora-native-ok";')
|
||||
const definition = {
|
||||
name: `smoke-${Date.now()}`,
|
||||
root,
|
||||
docroot: '',
|
||||
ports: await allocateNativePorts(),
|
||||
installedRuntimeRoot: process.env.AURORA_NATIVE_SMOKE_ROOT
|
||||
}
|
||||
try {
|
||||
await startNativeProject(definition)
|
||||
const response = await fetch(`http://127.0.0.1:${definition.ports.http}`)
|
||||
expect(await response.text()).toBe('aurora-native-ok')
|
||||
} finally {
|
||||
await stopNativeProject(definition)
|
||||
}
|
||||
},
|
||||
45000
|
||||
)
|
||||
|
||||
it.runIf(Boolean(process.env.AURORA_NATIVE_WORDPRESS_SMOKE_ROOT))(
|
||||
'provisions WordPress with the bundled native runtime',
|
||||
async () => {
|
||||
const runtime = process.env.AURORA_NATIVE_WORDPRESS_SMOKE_ROOT!
|
||||
const root = await mkdtemp(join(tmpdir(), 'aurora-native-wordpress-'))
|
||||
const definition = {
|
||||
name: `wordpress-${Date.now()}`,
|
||||
root,
|
||||
docroot: '',
|
||||
ports: await allocateNativePorts(),
|
||||
installedRuntimeRoot: runtime
|
||||
}
|
||||
const wordpress = createRequire(import.meta.url)(
|
||||
'../../../packages/aurora-module-wordpress/main/index.cjs'
|
||||
) as { projectCreate: (context: Record<string, unknown>) => Promise<void> }
|
||||
try {
|
||||
await wordpress.projectCreate({
|
||||
moduleId: 'wordpress',
|
||||
directory: root,
|
||||
projectName: definition.name,
|
||||
settings: {
|
||||
title: 'Aurora native smoke',
|
||||
admin_user: 'aurora-admin',
|
||||
admin_password: 'aurora-native-test-password',
|
||||
admin_email: '[email protected]',
|
||||
locale: 'en_US',
|
||||
multisite: 'none',
|
||||
wp_debug: false
|
||||
},
|
||||
environment: { runtimeEngine: 'native' },
|
||||
urls: {
|
||||
http: `http://127.0.0.1:${definition.ports.http}`,
|
||||
https: `http://127.0.0.1:${definition.ports.http}`
|
||||
},
|
||||
native: {
|
||||
php: join(runtime, 'bin', 'php'),
|
||||
wp: join(runtime, 'bin', 'wp'),
|
||||
databasePort: definition.ports.database,
|
||||
start: () => startNativeProject(definition)
|
||||
},
|
||||
run: async (_label: string, command: string, args: string[]) => {
|
||||
await execFileAsync(command, args, {
|
||||
cwd: root,
|
||||
env: process.env,
|
||||
maxBuffer: 32 * 1024 * 1024
|
||||
})
|
||||
},
|
||||
setProjectMetadata: async () => undefined,
|
||||
saveCredentials: async () => undefined
|
||||
})
|
||||
expect(await readFile(join(root, 'wp-config.php'), 'utf8')).toContain(
|
||||
`127.0.0.1:${definition.ports.database}`
|
||||
)
|
||||
const response = await fetch(`http://127.0.0.1:${definition.ports.http}`)
|
||||
expect(response.ok).toBe(true)
|
||||
expect(await response.text()).toContain('Aurora native smoke')
|
||||
} finally {
|
||||
await stopNativeProject(definition)
|
||||
}
|
||||
},
|
||||
120000
|
||||
)
|
||||
|
||||
@@ -14,6 +14,11 @@ export interface NativeProjectDefinition {
|
||||
root: string
|
||||
docroot: string
|
||||
ports: AuroraNativePorts
|
||||
installedRuntimeRoot?: string
|
||||
}
|
||||
|
||||
function installedRoot(project: NativeProjectDefinition): string {
|
||||
return project.installedRuntimeRoot ?? runtimeRoot()
|
||||
}
|
||||
|
||||
function nativeDirectory(root: string): string {
|
||||
@@ -53,6 +58,11 @@ error_log "${quoteNginx(join(directory, 'logs', 'nginx.log'))}" info;
|
||||
events { worker_connections 256; }
|
||||
http {
|
||||
access_log "${quoteNginx(join(directory, 'logs', 'nginx-access.log'))}";
|
||||
client_body_temp_path "${quoteNginx(join(directory, 'tmp', 'nginx-client'))}";
|
||||
proxy_temp_path "${quoteNginx(join(directory, 'tmp', 'nginx-proxy'))}";
|
||||
fastcgi_temp_path "${quoteNginx(join(directory, 'tmp', 'nginx-fastcgi'))}";
|
||||
uwsgi_temp_path "${quoteNginx(join(directory, 'tmp', 'nginx-uwsgi'))}";
|
||||
scgi_temp_path "${quoteNginx(join(directory, 'tmp', 'nginx-scgi'))}";
|
||||
server {
|
||||
listen 127.0.0.1:${project.ports.http};
|
||||
server_name localhost;
|
||||
@@ -65,9 +75,17 @@ http {
|
||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
|
||||
fastcgi_param REQUEST_METHOD $request_method;
|
||||
fastcgi_param REQUEST_URI $request_uri;
|
||||
fastcgi_param QUERY_STRING $query_string;
|
||||
fastcgi_param CONTENT_TYPE $content_type;
|
||||
fastcgi_param CONTENT_LENGTH $content_length;
|
||||
fastcgi_param DOCUMENT_ROOT $document_root;
|
||||
fastcgi_param SERVER_PROTOCOL $server_protocol;
|
||||
fastcgi_param SERVER_NAME $server_name;
|
||||
fastcgi_param SERVER_PORT $server_port;
|
||||
fastcgi_param HTTP_HOST $http_host;
|
||||
fastcgi_param REMOTE_ADDR $remote_addr;
|
||||
fastcgi_param REMOTE_PORT $remote_port;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -94,18 +112,32 @@ skip-name-resolve
|
||||
|
||||
export async function provisionNativeProject(project: NativeProjectDefinition): Promise<void> {
|
||||
const directory = nativeDirectory(project.root)
|
||||
for (const child of ['config', 'data/mariadb', 'logs', 'pids', 'tmp'])
|
||||
for (const child of [
|
||||
'config',
|
||||
'data/mariadb',
|
||||
'logs',
|
||||
'pids',
|
||||
'tmp',
|
||||
'tmp/nginx-client',
|
||||
'tmp/nginx-proxy',
|
||||
'tmp/nginx-fastcgi',
|
||||
'tmp/nginx-uwsgi',
|
||||
'tmp/nginx-scgi'
|
||||
])
|
||||
await mkdir(join(directory, child), { recursive: true })
|
||||
await Promise.all([
|
||||
writeFile(join(directory, 'config', 'php-fpm.conf'), renderPhpFpmConfig(project)),
|
||||
writeFile(join(directory, 'config', 'nginx.conf'), renderNginxConfig(project)),
|
||||
writeFile(join(directory, 'config', 'mariadb.cnf'), renderMariaDbConfig(project))
|
||||
writeFile(
|
||||
join(directory, 'config', 'mariadb.cnf'),
|
||||
renderMariaDbConfig(project, installedRoot(project))
|
||||
)
|
||||
])
|
||||
try {
|
||||
await access(join(directory, 'data', 'mariadb', 'mysql'))
|
||||
} catch {
|
||||
await execFileAsync(
|
||||
join(runtimeRoot(), 'bin', 'mariadb-install-db'),
|
||||
join(installedRoot(project), 'bin', 'mariadb-install-db'),
|
||||
[
|
||||
'--no-defaults',
|
||||
`--datadir=${join(directory, 'data', 'mariadb')}`,
|
||||
@@ -129,19 +161,19 @@ export function nativeServiceSpecs(project: NativeProjectDefinition): NativeServ
|
||||
return [
|
||||
{
|
||||
...common('database'),
|
||||
command: join(runtimeRoot(), 'bin', 'mariadbd'),
|
||||
command: join(installedRoot(project), 'bin', 'mariadbd'),
|
||||
args: [`--defaults-file=${join(directory, 'config', 'mariadb.cnf')}`],
|
||||
ready: { port: project.ports.database, timeoutMs: 30000 }
|
||||
},
|
||||
{
|
||||
...common('php'),
|
||||
command: join(runtimeRoot(), 'bin', 'php-fpm'),
|
||||
command: join(installedRoot(project), 'bin', 'php-fpm'),
|
||||
args: ['--nodaemonize', '--fpm-config', join(directory, 'config', 'php-fpm.conf')],
|
||||
ready: { port: project.ports.php }
|
||||
},
|
||||
{
|
||||
...common('web'),
|
||||
command: join(runtimeRoot(), 'bin', 'nginx'),
|
||||
command: join(installedRoot(project), 'bin', 'nginx'),
|
||||
args: ['-c', join(directory, 'config', 'nginx.conf'), '-p', `${directory}/`],
|
||||
ready: { port: project.ports.http }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user