Skip to content

Commit 8e2cadc

Browse files
Stabilize profile smoke PHP toolchain and DNS state
1 parent 0495ebd commit 8e2cadc

3 files changed

Lines changed: 193 additions & 24 deletions

File tree

infra/scripts/build-profile.sh

Lines changed: 107 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ Environment variables:
3232
Explicit OpenSSL compile flags. Appended before configure.
3333
KING_OPENSSL_LIBS
3434
Explicit OpenSSL linker flags. Appended before configure.
35+
PHP_BIN PHP binary used by matching smoke scripts. Also used to infer
36+
phpizeX.Y/php-configX.Y when PHPIZE/PHP_CONFIG are unset.
37+
PHPIZE phpize binary to use for this profile build.
38+
PHP_CONFIG php-config binary to pass to configure.
3539
EOF
3640
}
3741

@@ -142,6 +146,7 @@ BASE_CPPFLAGS="${CPPFLAGS:-}"
142146
BASE_LDFLAGS="${LDFLAGS:-}"
143147
BASE_CC="${CC:-}"
144148
BASE_CXX="${CXX:-}"
149+
PHP_BIN="${PHP_BIN:-php}"
145150

146151
profile_cc=""
147152
profile_cxx=""
@@ -150,6 +155,8 @@ profile_cppflags="${BASE_CPPFLAGS}"
150155
profile_ldflags="${BASE_LDFLAGS}"
151156
sanitizer_kind=""
152157
lsquic_runtime_prefix="${KING_LSQUIC_RUNTIME_PREFIX:-}"
158+
phpize_bin=""
159+
php_config_bin=""
153160
declare -a PHPIZE_GENERATED_RELATIVE_PATHS=()
154161
declare -a CONFIGURE_ENV=()
155162
PHPIZE_SNAPSHOT_DIR=""
@@ -162,6 +169,97 @@ trim_ascii_whitespace() {
162169
printf '%s\n' "${value}"
163170
}
164171

172+
php_binary_suffix() {
173+
local binary_name=""
174+
175+
binary_name="$(basename "${PHP_BIN}")"
176+
case "${binary_name}" in
177+
php[0-9].[0-9])
178+
printf '%s\n' "${binary_name#php}"
179+
return 0
180+
;;
181+
esac
182+
183+
return 1
184+
}
185+
186+
php_runtime_api() {
187+
"${PHP_BIN}" -i 2>/dev/null | awk -F'=> ' '/^PHP API/ { print $2; exit }'
188+
}
189+
190+
phpize_api() {
191+
"${phpize_bin}" -v 2>/dev/null | awk -F': *' '/^PHP Api Version/ { print $2; exit }'
192+
}
193+
194+
resolve_php_toolchain() {
195+
local suffix=""
196+
local runtime_api=""
197+
local config_api=""
198+
local phpize_reported_api=""
199+
200+
phpize_bin="${PHPIZE:-}"
201+
php_config_bin="${PHP_CONFIG:-}"
202+
203+
if [[ -z "${phpize_bin}" || -z "${php_config_bin}" ]]; then
204+
suffix="$(php_binary_suffix || true)"
205+
if [[ -n "${suffix}" ]]; then
206+
if [[ -z "${phpize_bin}" ]] && command -v "phpize${suffix}" >/dev/null 2>&1; then
207+
phpize_bin="phpize${suffix}"
208+
fi
209+
if [[ -z "${php_config_bin}" ]] && command -v "php-config${suffix}" >/dev/null 2>&1; then
210+
php_config_bin="php-config${suffix}"
211+
fi
212+
fi
213+
fi
214+
215+
phpize_bin="${phpize_bin:-phpize}"
216+
php_config_bin="${php_config_bin:-php-config}"
217+
218+
if ! command -v "${phpize_bin}" >/dev/null 2>&1; then
219+
echo "Missing phpize binary: ${phpize_bin}" >&2
220+
exit 1
221+
fi
222+
223+
if ! command -v "${php_config_bin}" >/dev/null 2>&1; then
224+
echo "Missing php-config binary: ${php_config_bin}" >&2
225+
exit 1
226+
fi
227+
228+
if ! command -v "${PHP_BIN}" >/dev/null 2>&1; then
229+
echo "Missing PHP binary: ${PHP_BIN}" >&2
230+
exit 1
231+
fi
232+
233+
runtime_api="$(php_runtime_api)"
234+
config_api="$("${php_config_bin}" --phpapi 2>/dev/null || true)"
235+
phpize_reported_api="$(phpize_api)"
236+
237+
if [[ -z "${runtime_api}" ]]; then
238+
echo "Failed to resolve PHP runtime API from ${PHP_BIN}." >&2
239+
exit 1
240+
fi
241+
242+
if [[ -z "${config_api}" ]]; then
243+
echo "Failed to resolve PHP config API from ${php_config_bin}." >&2
244+
exit 1
245+
fi
246+
247+
if [[ -z "${phpize_reported_api}" ]]; then
248+
echo "Failed to resolve phpize API from ${phpize_bin}." >&2
249+
exit 1
250+
fi
251+
252+
if [[ "${runtime_api}" != "${config_api}" || "${runtime_api}" != "${phpize_reported_api}" ]]; then
253+
{
254+
echo "PHP toolchain API mismatch:"
255+
echo " ${PHP_BIN}: ${runtime_api}"
256+
echo " ${php_config_bin}: ${config_api}"
257+
echo " ${phpize_bin}: ${phpize_reported_api}"
258+
} >&2
259+
exit 1
260+
fi
261+
}
262+
165263
load_phpize_generated_relative_paths() {
166264
local raw_line=""
167265
local normalized_line=""
@@ -482,6 +580,11 @@ echo "Building King profile: ${PROFILE}"
482580
echo "Compiler: ${profile_cc}"
483581
echo "Jobs: ${JOBS}"
484582

583+
resolve_php_toolchain
584+
echo "PHP binary: ${PHP_BIN}"
585+
echo "phpize: ${phpize_bin}"
586+
echo "php-config: ${php_config_bin}"
587+
485588
load_phpize_generated_relative_paths
486589
snapshot_phpize_generated_files
487590
trap restore_phpize_generated_files EXIT
@@ -492,15 +595,16 @@ if [[ -f Makefile ]]; then
492595
make clean >/dev/null 2>&1 || true
493596
fi
494597

495-
phpize --clean >/dev/null 2>&1 || true
496-
phpize
598+
"${phpize_bin}" --clean >/dev/null 2>&1 || true
599+
"${phpize_bin}"
497600

498601
CONFIGURE_ENV=(
499602
CC="${profile_cc}"
500603
CXX="${profile_cxx}"
501604
CFLAGS="${profile_cflags}"
502605
CPPFLAGS="${profile_cppflags}"
503606
LDFLAGS="${profile_ldflags}"
607+
PHP_CONFIG="${php_config_bin}"
504608
)
505609

506610
if [[ "$(host_os)" == "darwin" ]]; then
@@ -519,7 +623,7 @@ if [[ -n "${lsquic_runtime_prefix}" ]]; then
519623
)
520624
fi
521625

522-
env "${CONFIGURE_ENV[@]}" ./configure --enable-king
626+
env "${CONFIGURE_ENV[@]}" ./configure --enable-king --with-php-config="${php_config_bin}"
523627
patch_generated_libtool_for_host
524628

525629
make -j"${JOBS}"

infra/scripts/runtime-install-smoke.php

Lines changed: 85 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,92 @@
33
declare(strict_types=1);
44

55
$schema = 'InstallSmoke_' . getmypid();
6-
$dnsPort = 10000 + (getmypid() % 40000);
76
$semanticDnsStatePath = getenv('KING_SEMANTIC_DNS_STATE_PATH');
87

8+
function install_smoke_allocate_udp_port(): int
9+
{
10+
$errno = 0;
11+
$errstr = '';
12+
$probe = @stream_socket_server(
13+
'udp://127.0.0.1:0',
14+
$errno,
15+
$errstr,
16+
STREAM_SERVER_BIND
17+
);
18+
if ($probe === false) {
19+
throw new RuntimeException("Failed to allocate UDP smoke port: {$errstr} ({$errno})");
20+
}
21+
22+
$name = stream_socket_get_name($probe, false);
23+
fclose($probe);
24+
if (!is_string($name) || $name === '') {
25+
throw new RuntimeException('Failed to read allocated UDP smoke port.');
26+
}
27+
28+
$separator = strrpos($name, ':');
29+
if ($separator === false) {
30+
throw new RuntimeException("Unexpected UDP socket name: {$name}");
31+
}
32+
33+
$port = (int) substr($name, $separator + 1);
34+
if ($port < 1 || $port > 65535) {
35+
throw new RuntimeException("Invalid allocated UDP smoke port: {$name}");
36+
}
37+
38+
return $port;
39+
}
40+
41+
function install_smoke_default_semantic_dns_state_path(): string
42+
{
43+
return sys_get_temp_dir()
44+
. '/king_install_smoke_semantic_dns_' . getmypid()
45+
. '/semantic_dns_state.bin';
46+
}
47+
48+
function install_smoke_semantic_dns_config(int $dnsPort, ?string $statePath): array
49+
{
50+
return [
51+
'enabled' => true,
52+
'bind_address' => '127.0.0.1',
53+
'dns_port' => $dnsPort,
54+
'default_record_ttl_sec' => 120,
55+
'service_discovery_max_ips_per_response' => 5,
56+
'semantic_mode_enable' => true,
57+
'state_path' => is_string($statePath) && $statePath !== ''
58+
? $statePath
59+
: install_smoke_default_semantic_dns_state_path(),
60+
'mothernode_uri' => 'mother://install-smoke',
61+
'routing_policies' => ['mode' => 'local'],
62+
];
63+
}
64+
65+
function install_smoke_start_semantic_dns(?string $statePath): int
66+
{
67+
$lastError = null;
68+
for ($attempt = 0; $attempt < 8; $attempt++) {
69+
$dnsPort = install_smoke_allocate_udp_port();
70+
if (!king_semantic_dns_init(install_smoke_semantic_dns_config($dnsPort, $statePath))) {
71+
fwrite(STDERR, "Semantic-DNS init smoke failed.\n");
72+
exit(1);
73+
}
74+
75+
try {
76+
if (king_semantic_dns_start_server()) {
77+
return $dnsPort;
78+
}
79+
$lastError = 'king_semantic_dns_start_server returned false';
80+
} catch (Throwable $error) {
81+
$lastError = $error->getMessage();
82+
if (!str_contains($lastError, 'could not bind the UDP DNS listener')) {
83+
throw $error;
84+
}
85+
}
86+
}
87+
88+
fwrite(STDERR, "Semantic-DNS start smoke failed after retries: {$lastError}\n");
89+
exit(1);
90+
}
91+
992
if (!function_exists('king_connect')) {
1093
fwrite(STDERR, "King extension functions are unavailable.\n");
1194
exit(1);
@@ -65,26 +148,7 @@
65148
@rmdir($root);
66149
}
67150

68-
if (!king_semantic_dns_init([
69-
'enabled' => true,
70-
'bind_address' => '127.0.0.1',
71-
'dns_port' => $dnsPort,
72-
'default_record_ttl_sec' => 120,
73-
'service_discovery_max_ips_per_response' => 5,
74-
'semantic_mode_enable' => true,
75-
'state_path' => is_string($semanticDnsStatePath) && $semanticDnsStatePath !== ''
76-
? $semanticDnsStatePath
77-
: sys_get_temp_dir() . '/king_install_smoke_' . getmypid() . '/semantic_dns_state.bin',
78-
'mothernode_uri' => 'mother://install-smoke',
79-
'routing_policies' => ['mode' => 'local'],
80-
])) {
81-
fwrite(STDERR, "Semantic-DNS init smoke failed.\n");
82-
exit(1);
83-
}
84-
if (!king_semantic_dns_start_server()) {
85-
fwrite(STDERR, "Semantic-DNS start smoke failed.\n");
86-
exit(1);
87-
}
151+
install_smoke_start_semantic_dns(is_string($semanticDnsStatePath) ? $semanticDnsStatePath : null);
88152
if (!king_semantic_dns_register_service([
89153
'service_id' => 'install-smoke',
90154
'service_name' => 'install-smoke',

infra/scripts/smoke-profile.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ case "${PROFILE}" in
128128
esac
129129

130130
"${PHP_BIN}" \
131+
-n \
131132
-d "extension=${EXT_SO}" \
132133
-d "king.security_allow_config_override=1" \
133134
"${SCRIPT_DIR}/runtime-install-smoke.php"

0 commit comments

Comments
 (0)