@fairmint/canton-node-sdk 0.0.225 → 0.0.226
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/scripts/localnet-cloud.sh +357 -70
package/package.json
CHANGED
|
@@ -10,6 +10,11 @@ DOCKERD_LOG_FILE="/tmp/localnet-dockerd.log"
|
|
|
10
10
|
HOSTS_ENTRY="127.0.0.1 scan.localhost sv.localhost wallet.localhost"
|
|
11
11
|
CURL_CONNECT_TIMEOUT=2
|
|
12
12
|
CURL_MAX_TIME=5
|
|
13
|
+
LOCALNET_SPLICE_VERSION="${CANTON_LOCALNET_SPLICE_VERSION:-}"
|
|
14
|
+
LOCALNET_SCRIBE_VERSION="${CANTON_LOCALNET_SCRIBE_VERSION:-}"
|
|
15
|
+
LOCALNET_PROTOCOL_VERSION="${CANTON_LOCALNET_PROTOCOL_VERSION:-}"
|
|
16
|
+
VALIDATOR_READY_ATTEMPTS="${CANTON_LOCALNET_VALIDATOR_READY_ATTEMPTS:-90}"
|
|
17
|
+
SCAN_READY_ATTEMPTS="${CANTON_LOCALNET_SCAN_READY_ATTEMPTS:-90}"
|
|
13
18
|
|
|
14
19
|
log() {
|
|
15
20
|
printf '[localnet] %s\n' "$*"
|
|
@@ -34,6 +39,21 @@ require_command() {
|
|
|
34
39
|
fi
|
|
35
40
|
}
|
|
36
41
|
|
|
42
|
+
require_positive_integer() {
|
|
43
|
+
local name="$1"
|
|
44
|
+
local value="$2"
|
|
45
|
+
|
|
46
|
+
if [[ ! "${value}" =~ ^[1-9][0-9]*$ ]]; then
|
|
47
|
+
log "${name} must be a positive integer; received '${value}'."
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
validate_configuration() {
|
|
53
|
+
require_positive_integer "CANTON_LOCALNET_VALIDATOR_READY_ATTEMPTS" "${VALIDATOR_READY_ATTEMPTS}"
|
|
54
|
+
require_positive_integer "CANTON_LOCALNET_SCAN_READY_ATTEMPTS" "${SCAN_READY_ATTEMPTS}"
|
|
55
|
+
}
|
|
56
|
+
|
|
37
57
|
ensure_sudo() {
|
|
38
58
|
if ! sudo_noninteractive_available; then
|
|
39
59
|
log "Passwordless sudo is required in this cloud environment."
|
|
@@ -147,6 +167,7 @@ run_quickstart_command() {
|
|
|
147
167
|
local command="$1"
|
|
148
168
|
local docker_shim_dir=""
|
|
149
169
|
local quickstart_image_tag=""
|
|
170
|
+
local quickstart_path="${HOME}/.dpm/bin:${HOME}/.daml/bin:${PATH}"
|
|
150
171
|
local status=0
|
|
151
172
|
|
|
152
173
|
quickstart_image_tag="$(resolve_quickstart_image_tag)"
|
|
@@ -161,28 +182,20 @@ EOF
|
|
|
161
182
|
log "Using sudo docker shim for quickstart command."
|
|
162
183
|
fi
|
|
163
184
|
|
|
164
|
-
set +e
|
|
165
185
|
if [[ -n "${docker_shim_dir}" ]]; then
|
|
166
|
-
|
|
167
|
-
cd "${QUICKSTART_DIR}"
|
|
168
|
-
MODULES_DIR="${QUICKSTART_DIR}/docker/modules" \
|
|
169
|
-
LOCALNET_DIR="${QUICKSTART_DIR}/docker/modules/localnet" \
|
|
170
|
-
IMAGE_TAG="${quickstart_image_tag}" \
|
|
171
|
-
PATH="${docker_shim_dir}:${HOME}/.daml/bin:${PATH}" \
|
|
172
|
-
bash -lc "${command}"
|
|
173
|
-
)
|
|
174
|
-
status=$?
|
|
175
|
-
else
|
|
176
|
-
(
|
|
177
|
-
cd "${QUICKSTART_DIR}"
|
|
178
|
-
MODULES_DIR="${QUICKSTART_DIR}/docker/modules" \
|
|
179
|
-
LOCALNET_DIR="${QUICKSTART_DIR}/docker/modules/localnet" \
|
|
180
|
-
IMAGE_TAG="${quickstart_image_tag}" \
|
|
181
|
-
PATH="${HOME}/.daml/bin:${PATH}" \
|
|
182
|
-
bash -lc "${command}"
|
|
183
|
-
)
|
|
184
|
-
status=$?
|
|
186
|
+
quickstart_path="${docker_shim_dir}:${quickstart_path}"
|
|
185
187
|
fi
|
|
188
|
+
|
|
189
|
+
set +e
|
|
190
|
+
(
|
|
191
|
+
cd "${QUICKSTART_DIR}"
|
|
192
|
+
MODULES_DIR="${QUICKSTART_DIR}/docker/modules" \
|
|
193
|
+
LOCALNET_DIR="${QUICKSTART_DIR}/docker/modules/localnet" \
|
|
194
|
+
IMAGE_TAG="${quickstart_image_tag}" \
|
|
195
|
+
PATH="${quickstart_path}" \
|
|
196
|
+
bash -lc "${command}"
|
|
197
|
+
)
|
|
198
|
+
status=$?
|
|
186
199
|
set -e
|
|
187
200
|
|
|
188
201
|
if [[ -n "${docker_shim_dir}" ]]; then
|
|
@@ -308,25 +321,276 @@ ensure_hosts_entries() {
|
|
|
308
321
|
fi
|
|
309
322
|
}
|
|
310
323
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
324
|
+
set_quickstart_env_value() {
|
|
325
|
+
local file="$1"
|
|
326
|
+
local key="$2"
|
|
327
|
+
local value="$3"
|
|
328
|
+
|
|
329
|
+
if [[ ! -f "${file}" ]]; then
|
|
330
|
+
return
|
|
331
|
+
fi
|
|
332
|
+
|
|
333
|
+
if grep -Eq "^${key}=" "${file}"; then
|
|
334
|
+
KEY="${key}" VALUE="${value}" perl -0pi -e '
|
|
335
|
+
my $key = $ENV{"KEY"};
|
|
336
|
+
my $value = $ENV{"VALUE"};
|
|
337
|
+
s/^\Q$key\E=.*/$key=$value/m;
|
|
338
|
+
' "${file}"
|
|
339
|
+
else
|
|
340
|
+
printf '\n%s=%s\n' "${key}" "${value}" >>"${file}"
|
|
341
|
+
fi
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
patch_quickstart_canton_healthcheck() {
|
|
345
|
+
local healthcheck="${QUICKSTART_DIR}/docker/modules/localnet/docker/canton/health-check.sh"
|
|
346
|
+
|
|
347
|
+
if [[ ! -f "${healthcheck}" ]]; then
|
|
348
|
+
log "Canton quickstart healthcheck not found: ${healthcheck}"
|
|
349
|
+
exit 1
|
|
350
|
+
fi
|
|
351
|
+
|
|
352
|
+
cat >"${healthcheck}" <<'EOF'
|
|
353
|
+
#!/bin/bash
|
|
354
|
+
set -eou pipefail
|
|
355
|
+
|
|
356
|
+
http_check() {
|
|
357
|
+
local port="$1"
|
|
358
|
+
local path="$2"
|
|
359
|
+
local status=""
|
|
360
|
+
|
|
361
|
+
echo "Checking http://localhost:${port}${path}"
|
|
362
|
+
exec 3<>"/dev/tcp/127.0.0.1/${port}"
|
|
363
|
+
printf 'GET %s HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n' "${path}" >&3
|
|
364
|
+
IFS=$'\r' read -r status <&3 || true
|
|
365
|
+
exec 3<&-
|
|
366
|
+
exec 3>&-
|
|
367
|
+
|
|
368
|
+
case "${status}" in
|
|
369
|
+
HTTP/*\ 2*) ;;
|
|
370
|
+
*)
|
|
371
|
+
echo "Unexpected status from ${port}${path}: ${status}"
|
|
372
|
+
return 1
|
|
373
|
+
;;
|
|
374
|
+
esac
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
if [ "${APP_USER_PROFILE:-off}" = "on" ]; then
|
|
378
|
+
http_check "2${CANTON_HTTP_HEALTHCHECK_PORT_SUFFIX}" "/health"
|
|
379
|
+
fi
|
|
380
|
+
if [ "${APP_PROVIDER_PROFILE:-off}" = "on" ]; then
|
|
381
|
+
http_check "3${CANTON_HTTP_HEALTHCHECK_PORT_SUFFIX}" "/health"
|
|
382
|
+
fi
|
|
383
|
+
if [ "${SV_PROFILE:-off}" = "on" ]; then
|
|
384
|
+
http_check "4${CANTON_HTTP_HEALTHCHECK_PORT_SUFFIX}" "/health"
|
|
385
|
+
fi
|
|
386
|
+
EOF
|
|
387
|
+
chmod +x "${healthcheck}"
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
patch_quickstart_splice_healthcheck() {
|
|
391
|
+
local healthcheck="${QUICKSTART_DIR}/docker/modules/localnet/docker/splice/health-check.sh"
|
|
392
|
+
|
|
393
|
+
if [[ ! -f "${healthcheck}" ]]; then
|
|
394
|
+
log "Splice quickstart healthcheck not found: ${healthcheck}"
|
|
395
|
+
exit 1
|
|
396
|
+
fi
|
|
397
|
+
|
|
398
|
+
cat >"${healthcheck}" <<'EOF'
|
|
399
|
+
#!/bin/bash
|
|
400
|
+
set -eou pipefail
|
|
401
|
+
|
|
402
|
+
http_check() {
|
|
403
|
+
local port="$1"
|
|
404
|
+
local path="$2"
|
|
405
|
+
local status=""
|
|
406
|
+
|
|
407
|
+
echo "Checking http://localhost:${port}${path}"
|
|
408
|
+
exec 3<>"/dev/tcp/127.0.0.1/${port}"
|
|
409
|
+
printf 'GET %s HTTP/1.1\r\nHost: localhost\r\nConnection: close\r\n\r\n' "${path}" >&3
|
|
410
|
+
IFS=$'\r' read -r status <&3 || true
|
|
411
|
+
exec 3<&-
|
|
412
|
+
exec 3>&-
|
|
413
|
+
|
|
414
|
+
case "${status}" in
|
|
415
|
+
HTTP/*\ 2*) ;;
|
|
416
|
+
*)
|
|
417
|
+
echo "Unexpected status from ${port}${path}: ${status}"
|
|
418
|
+
return 1
|
|
419
|
+
;;
|
|
420
|
+
esac
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
if [ "${APP_USER_PROFILE:-off}" = "on" ]; then
|
|
424
|
+
http_check "2${VALIDATOR_ADMIN_API_PORT_SUFFIX}" "/api/validator/readyz"
|
|
425
|
+
fi
|
|
426
|
+
if [ "${APP_PROVIDER_PROFILE:-off}" = "on" ]; then
|
|
427
|
+
http_check "3${VALIDATOR_ADMIN_API_PORT_SUFFIX}" "/api/validator/readyz"
|
|
428
|
+
fi
|
|
429
|
+
if [ "${SV_PROFILE:-off}" = "on" ]; then
|
|
430
|
+
http_check "4${VALIDATOR_ADMIN_API_PORT_SUFFIX}" "/api/validator/readyz"
|
|
431
|
+
http_check "5012" "/api/scan/readyz"
|
|
432
|
+
http_check "5014" "/api/sv/readyz"
|
|
433
|
+
fi
|
|
434
|
+
EOF
|
|
435
|
+
chmod +x "${healthcheck}"
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
configure_quickstart_localnet() {
|
|
439
|
+
local env_file=""
|
|
440
|
+
local canton_conf="${QUICKSTART_DIR}/docker/modules/localnet/conf/canton/app.conf"
|
|
441
|
+
|
|
442
|
+
for env_file in "${QUICKSTART_DIR}/.env" "${QUICKSTART_DIR}/.env.local"; do
|
|
443
|
+
if [[ -n "${LOCALNET_SPLICE_VERSION}" ]]; then
|
|
444
|
+
set_quickstart_env_value "${env_file}" "SPLICE_VERSION" "${LOCALNET_SPLICE_VERSION}"
|
|
445
|
+
fi
|
|
446
|
+
if [[ -n "${LOCALNET_SCRIBE_VERSION}" ]]; then
|
|
447
|
+
set_quickstart_env_value "${env_file}" "SCRIBE_VERSION" "${LOCALNET_SCRIBE_VERSION}"
|
|
448
|
+
fi
|
|
449
|
+
if [[ -n "${CANTON_LOCALNET_DAML_RUNTIME_VERSION:-}" ]]; then
|
|
450
|
+
set_quickstart_env_value "${env_file}" "DAML_RUNTIME_VERSION" "${CANTON_LOCALNET_DAML_RUNTIME_VERSION}"
|
|
451
|
+
fi
|
|
452
|
+
done
|
|
453
|
+
|
|
454
|
+
if [[ ! -f "${canton_conf}" ]]; then
|
|
455
|
+
log "Canton quickstart config not found: ${canton_conf}"
|
|
456
|
+
exit 1
|
|
457
|
+
fi
|
|
458
|
+
|
|
459
|
+
if [[ -n "${LOCALNET_PROTOCOL_VERSION}" ]]; then
|
|
460
|
+
PROTOCOL_VERSION="${LOCALNET_PROTOCOL_VERSION}" perl -0pi -e '
|
|
461
|
+
my $protocol_version = $ENV{"PROTOCOL_VERSION"};
|
|
462
|
+
s/initial-protocol-version = \d+/initial-protocol-version = $protocol_version/g;
|
|
463
|
+
s/(non-standard-config = yes\n)(?![[:space:]]*alpha-version-support = yes)/$1 alpha-version-support = yes\n/;
|
|
464
|
+
s/(initial-protocol-version = \d+\n)(?![[:space:]]*alpha-version-support = yes)/$1 alpha-version-support = yes\n/;
|
|
465
|
+
' "${canton_conf}"
|
|
466
|
+
fi
|
|
467
|
+
|
|
468
|
+
patch_quickstart_canton_healthcheck
|
|
469
|
+
patch_quickstart_splice_healthcheck
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
requested_auth_mode() {
|
|
473
|
+
printf '%s' "${CANTON_LOCALNET_AUTH_MODE:-oauth2}"
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
quickstart_env_value() {
|
|
477
|
+
local key="$1"
|
|
478
|
+
local parsed_value=""
|
|
479
|
+
|
|
480
|
+
if [[ -f "${QUICKSTART_DIR}/.env.local" ]]; then
|
|
481
|
+
parsed_value="$(awk -F= -v key="${key}" '
|
|
482
|
+
$0 ~ /^[[:space:]]*#/ { next }
|
|
483
|
+
$1 == key {
|
|
484
|
+
value = substr($0, index($0, "=") + 1)
|
|
485
|
+
gsub(/^[[:space:]]+|[[:space:]]+$/, "", value)
|
|
486
|
+
gsub(/^"|"$/, "", value)
|
|
487
|
+
gsub(/^'\''|'\''$/, "", value)
|
|
488
|
+
parsed = value
|
|
489
|
+
}
|
|
490
|
+
END {
|
|
491
|
+
if (parsed != "") {
|
|
492
|
+
print parsed
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
' "${QUICKSTART_DIR}/.env.local")"
|
|
496
|
+
fi
|
|
497
|
+
|
|
498
|
+
printf '%s' "${parsed_value}"
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
configured_auth_mode() {
|
|
502
|
+
quickstart_env_value "AUTH_MODE"
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
quickstart_profile_config_complete() {
|
|
506
|
+
local key=""
|
|
507
|
+
|
|
508
|
+
for key in OBSERVABILITY_ENABLED AUTH_MODE PARTY_HINT TEST_MODE; do
|
|
509
|
+
if [[ -z "$(quickstart_env_value "${key}")" ]]; then
|
|
510
|
+
return 1
|
|
511
|
+
fi
|
|
512
|
+
done
|
|
513
|
+
|
|
514
|
+
return 0
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
verify_configured_auth_mode() {
|
|
518
|
+
local expected_auth_mode="$1"
|
|
519
|
+
local actual_auth_mode=""
|
|
520
|
+
|
|
521
|
+
actual_auth_mode="$(configured_auth_mode)"
|
|
522
|
+
if [[ "${actual_auth_mode}" != "${expected_auth_mode}" ]]; then
|
|
523
|
+
log "cn-quickstart setup did not configure AUTH_MODE=${expected_auth_mode}; found '${actual_auth_mode:-unset}'."
|
|
524
|
+
exit 1
|
|
525
|
+
fi
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
current_auth_mode() {
|
|
529
|
+
local configured=""
|
|
530
|
+
|
|
531
|
+
configured="$(configured_auth_mode)"
|
|
532
|
+
if [[ -n "${configured}" ]]; then
|
|
533
|
+
printf '%s' "${configured}"
|
|
534
|
+
return
|
|
535
|
+
fi
|
|
536
|
+
|
|
537
|
+
requested_auth_mode
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
run_quickstart_setup() {
|
|
541
|
+
local auth_mode=""
|
|
542
|
+
|
|
543
|
+
auth_mode="$(requested_auth_mode)"
|
|
544
|
+
case "${auth_mode}" in
|
|
545
|
+
shared-secret)
|
|
546
|
+
log "Running cn-quickstart setup (shared-secret mode)..."
|
|
547
|
+
(
|
|
548
|
+
cd "${QUICKSTART_DIR}"
|
|
549
|
+
printf 'Y\nn\n\n' | make setup || true
|
|
550
|
+
)
|
|
551
|
+
verify_configured_auth_mode "shared-secret"
|
|
552
|
+
;;
|
|
553
|
+
oauth2)
|
|
316
554
|
log "Running cn-quickstart setup (OAuth2 enabled)..."
|
|
317
555
|
(
|
|
318
556
|
cd "${QUICKSTART_DIR}"
|
|
319
557
|
# Match CI behavior first, then fall back to prompt-based answers for newer setup flows.
|
|
320
558
|
echo "2" | make setup || true
|
|
321
|
-
if
|
|
559
|
+
if [[ "$(configured_auth_mode)" != "oauth2" ]]; then
|
|
322
560
|
printf 'y\ny\n\nn\n' | make setup
|
|
323
561
|
fi
|
|
324
562
|
)
|
|
325
|
-
|
|
563
|
+
verify_configured_auth_mode "oauth2"
|
|
564
|
+
;;
|
|
565
|
+
*)
|
|
566
|
+
log "Unsupported CANTON_LOCALNET_AUTH_MODE: ${auth_mode}"
|
|
567
|
+
exit 1
|
|
568
|
+
;;
|
|
569
|
+
esac
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
quickstart_setup() {
|
|
573
|
+
if [[ ! -f "${QUICKSTART_DIR}/.env.local" ]]; then
|
|
574
|
+
run_quickstart_setup
|
|
575
|
+
elif ! quickstart_profile_config_complete; then
|
|
576
|
+
log "Regenerating incomplete cn-quickstart config."
|
|
577
|
+
rm -f "${QUICKSTART_DIR}/.env.local"
|
|
578
|
+
run_quickstart_setup
|
|
579
|
+
elif [[ -n "${CANTON_LOCALNET_AUTH_MODE:-}" && "$(configured_auth_mode)" != "${CANTON_LOCALNET_AUTH_MODE}" ]]; then
|
|
580
|
+
log "Regenerating cn-quickstart config for CANTON_LOCALNET_AUTH_MODE=${CANTON_LOCALNET_AUTH_MODE}."
|
|
581
|
+
rm -f "${QUICKSTART_DIR}/.env.local"
|
|
582
|
+
run_quickstart_setup
|
|
326
583
|
else
|
|
327
584
|
log "Reusing existing ${QUICKSTART_DIR}/.env.local."
|
|
328
585
|
fi
|
|
329
586
|
|
|
587
|
+
if [[ ! -f "${QUICKSTART_DIR}/.env.local" ]]; then
|
|
588
|
+
log "cn-quickstart setup failed: ${QUICKSTART_DIR}/.env.local was not created."
|
|
589
|
+
exit 1
|
|
590
|
+
fi
|
|
591
|
+
|
|
592
|
+
configure_quickstart_localnet
|
|
593
|
+
|
|
330
594
|
if quickstart_infra_only_enabled; then
|
|
331
595
|
log "Skipping Daml SDK install for infrastructure-only localnet."
|
|
332
596
|
return
|
|
@@ -343,37 +607,6 @@ quickstart_setup() {
|
|
|
343
607
|
fi
|
|
344
608
|
}
|
|
345
609
|
|
|
346
|
-
default_party_hint() {
|
|
347
|
-
local clean_user=""
|
|
348
|
-
local raw_user="${USER:-runner}"
|
|
349
|
-
|
|
350
|
-
clean_user="$(printf '%s' "${raw_user}" | tr -cd '[:alpha:]')"
|
|
351
|
-
if [[ -z "${clean_user}" ]]; then
|
|
352
|
-
clean_user="runner"
|
|
353
|
-
fi
|
|
354
|
-
|
|
355
|
-
printf 'quickstart-%s-1' "${clean_user,,}"
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
write_quickstart_env_local() {
|
|
359
|
-
local auth_mode="${CANTON_LOCALNET_AUTH_MODE:-oauth2}"
|
|
360
|
-
local observability_enabled="${CANTON_LOCALNET_OBSERVABILITY_ENABLED:-false}"
|
|
361
|
-
local party_hint="${CANTON_LOCALNET_PARTY_HINT:-}"
|
|
362
|
-
local test_mode="${CANTON_LOCALNET_TEST_MODE:-off}"
|
|
363
|
-
|
|
364
|
-
if [[ -z "${party_hint}" ]]; then
|
|
365
|
-
party_hint="$(default_party_hint)"
|
|
366
|
-
fi
|
|
367
|
-
|
|
368
|
-
log "Writing non-interactive cn-quickstart localnet config."
|
|
369
|
-
cat >"${QUICKSTART_DIR}/.env.local" <<EOF
|
|
370
|
-
OBSERVABILITY_ENABLED=${observability_enabled}
|
|
371
|
-
AUTH_MODE=${auth_mode}
|
|
372
|
-
PARTY_HINT=${party_hint}
|
|
373
|
-
TEST_MODE=${test_mode}
|
|
374
|
-
EOF
|
|
375
|
-
}
|
|
376
|
-
|
|
377
610
|
quickstart_fast_start_enabled() {
|
|
378
611
|
is_truthy "${CANTON_LOCALNET_FAST_START:-true}"
|
|
379
612
|
}
|
|
@@ -448,20 +681,37 @@ stop_infra_only_localnet() {
|
|
|
448
681
|
}
|
|
449
682
|
|
|
450
683
|
wait_for_services() {
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
684
|
+
local auth_mode=""
|
|
685
|
+
local code=""
|
|
686
|
+
local ledger_code=""
|
|
687
|
+
|
|
688
|
+
auth_mode="$(current_auth_mode)"
|
|
689
|
+
|
|
690
|
+
if [[ "${auth_mode}" == "oauth2" ]]; then
|
|
691
|
+
log "Waiting for Keycloak..."
|
|
692
|
+
for _ in $(seq 1 30); do
|
|
693
|
+
if curl --connect-timeout "${CURL_CONNECT_TIMEOUT}" --max-time "${CURL_MAX_TIME}" -fsS http://localhost:8082/realms/AppProvider >/dev/null 2>&1; then
|
|
694
|
+
break
|
|
695
|
+
fi
|
|
696
|
+
sleep 2
|
|
697
|
+
done
|
|
698
|
+
if ! curl --connect-timeout "${CURL_CONNECT_TIMEOUT}" --max-time "${CURL_MAX_TIME}" -fsS http://localhost:8082/realms/AppProvider >/dev/null 2>&1; then
|
|
699
|
+
log "Keycloak did not become ready."
|
|
700
|
+
exit 1
|
|
455
701
|
fi
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
702
|
+
else
|
|
703
|
+
log "Checking for Keycloak (optional in ${auth_mode} mode)..."
|
|
704
|
+
for _ in $(seq 1 5); do
|
|
705
|
+
if curl --connect-timeout "${CURL_CONNECT_TIMEOUT}" --max-time "${CURL_MAX_TIME}" -fsS http://localhost:8082/realms/AppProvider >/dev/null 2>&1; then
|
|
706
|
+
log "Keycloak is ready."
|
|
707
|
+
break
|
|
708
|
+
fi
|
|
709
|
+
sleep 2
|
|
710
|
+
done
|
|
461
711
|
fi
|
|
462
712
|
|
|
463
713
|
log "Waiting for Validator API..."
|
|
464
|
-
for _ in $(seq 1
|
|
714
|
+
for _ in $(seq 1 "${VALIDATOR_READY_ATTEMPTS}"); do
|
|
465
715
|
code="$(curl --connect-timeout "${CURL_CONNECT_TIMEOUT}" --max-time "${CURL_MAX_TIME}" -sS -o /dev/null -w '%{http_code}' http://localhost:3903/api/validator/v0/wallet/user-status || true)"
|
|
466
716
|
if [[ "${code}" == "200" || "${code}" == "401" ]]; then
|
|
467
717
|
break
|
|
@@ -475,7 +725,7 @@ wait_for_services() {
|
|
|
475
725
|
fi
|
|
476
726
|
|
|
477
727
|
log "Waiting for Scan API..."
|
|
478
|
-
for _ in $(seq 1
|
|
728
|
+
for _ in $(seq 1 "${SCAN_READY_ATTEMPTS}"); do
|
|
479
729
|
if curl --connect-timeout "${CURL_CONNECT_TIMEOUT}" --max-time "${CURL_MAX_TIME}" -fsS http://scan.localhost:4000/api/scan/v0/dso-party-id >/dev/null 2>&1; then
|
|
480
730
|
break
|
|
481
731
|
fi
|
|
@@ -486,6 +736,20 @@ wait_for_services() {
|
|
|
486
736
|
exit 1
|
|
487
737
|
fi
|
|
488
738
|
|
|
739
|
+
log "Waiting for Ledger JSON API..."
|
|
740
|
+
for _ in $(seq 1 60); do
|
|
741
|
+
ledger_code="$(curl --connect-timeout "${CURL_CONNECT_TIMEOUT}" --max-time "${CURL_MAX_TIME}" -sS -o /dev/null -w '%{http_code}' http://localhost:3975/v2/version || true)"
|
|
742
|
+
if [[ "${ledger_code}" == "200" || "${ledger_code}" == "401" ]]; then
|
|
743
|
+
break
|
|
744
|
+
fi
|
|
745
|
+
sleep 2
|
|
746
|
+
done
|
|
747
|
+
ledger_code="$(curl --connect-timeout "${CURL_CONNECT_TIMEOUT}" --max-time "${CURL_MAX_TIME}" -sS -o /dev/null -w '%{http_code}' http://localhost:3975/v2/version || true)"
|
|
748
|
+
if [[ "${ledger_code}" != "200" && "${ledger_code}" != "401" ]]; then
|
|
749
|
+
log "Ledger JSON API did not become ready (HTTP ${ledger_code})."
|
|
750
|
+
exit 1
|
|
751
|
+
fi
|
|
752
|
+
|
|
489
753
|
log "All localnet services are ready."
|
|
490
754
|
}
|
|
491
755
|
|
|
@@ -592,6 +856,7 @@ status_localnet() {
|
|
|
592
856
|
keycloak_ok="no"
|
|
593
857
|
validator_ok="no"
|
|
594
858
|
scan_ok="no"
|
|
859
|
+
ledger_ok="no"
|
|
595
860
|
if curl --connect-timeout "${CURL_CONNECT_TIMEOUT}" --max-time "${CURL_MAX_TIME}" -fsS http://localhost:8082/realms/AppProvider >/dev/null 2>&1; then
|
|
596
861
|
keycloak_ok="yes"
|
|
597
862
|
fi
|
|
@@ -602,10 +867,15 @@ status_localnet() {
|
|
|
602
867
|
if curl --connect-timeout "${CURL_CONNECT_TIMEOUT}" --max-time "${CURL_MAX_TIME}" -fsS http://scan.localhost:4000/api/scan/v0/dso-party-id >/dev/null 2>&1; then
|
|
603
868
|
scan_ok="yes"
|
|
604
869
|
fi
|
|
870
|
+
ledger_code="$(curl --connect-timeout "${CURL_CONNECT_TIMEOUT}" --max-time "${CURL_MAX_TIME}" -sS -o /dev/null -w '%{http_code}' http://localhost:3975/v2/version || true)"
|
|
871
|
+
if [[ "${ledger_code}" == "200" || "${ledger_code}" == "401" ]]; then
|
|
872
|
+
ledger_ok="yes"
|
|
873
|
+
fi
|
|
605
874
|
|
|
606
875
|
printf 'Keycloak ready: %s\n' "${keycloak_ok}"
|
|
607
876
|
printf 'Validator ready: %s (HTTP %s)\n' "${validator_ok}" "${validator_code:-n/a}"
|
|
608
877
|
printf 'Scan ready: %s\n' "${scan_ok}"
|
|
878
|
+
printf 'Ledger JSON API ready: %s (HTTP %s)\n' "${ledger_ok}" "${ledger_code:-n/a}"
|
|
609
879
|
}
|
|
610
880
|
|
|
611
881
|
show_localnet_logs() {
|
|
@@ -642,13 +912,20 @@ show_localnet_logs() {
|
|
|
642
912
|
}
|
|
643
913
|
|
|
644
914
|
run_smoke() {
|
|
915
|
+
local auth_mode=""
|
|
645
916
|
local validator_code=""
|
|
917
|
+
local ledger_code=""
|
|
646
918
|
|
|
647
919
|
log "Running localnet smoke checks..."
|
|
920
|
+
auth_mode="$(current_auth_mode)"
|
|
648
921
|
|
|
649
|
-
if
|
|
922
|
+
if curl --connect-timeout "${CURL_CONNECT_TIMEOUT}" --max-time "${CURL_MAX_TIME}" -fsS http://localhost:8082/realms/AppProvider >/dev/null 2>&1; then
|
|
923
|
+
log "Keycloak is reachable."
|
|
924
|
+
elif [[ "${auth_mode}" == "oauth2" ]]; then
|
|
650
925
|
log "Keycloak is not reachable."
|
|
651
926
|
exit 1
|
|
927
|
+
else
|
|
928
|
+
log "Keycloak not detected (expected in ${auth_mode} mode)."
|
|
652
929
|
fi
|
|
653
930
|
|
|
654
931
|
validator_code="$(curl --connect-timeout "${CURL_CONNECT_TIMEOUT}" --max-time "${CURL_MAX_TIME}" -sS -o /dev/null -w '%{http_code}' http://localhost:3903/api/validator/v0/wallet/user-status || true)"
|
|
@@ -662,6 +939,12 @@ run_smoke() {
|
|
|
662
939
|
exit 1
|
|
663
940
|
fi
|
|
664
941
|
|
|
942
|
+
ledger_code="$(curl --connect-timeout "${CURL_CONNECT_TIMEOUT}" --max-time "${CURL_MAX_TIME}" -sS -o /dev/null -w '%{http_code}' http://localhost:3975/v2/version || true)"
|
|
943
|
+
if [[ "${ledger_code}" != "200" && "${ledger_code}" != "401" ]]; then
|
|
944
|
+
log "Ledger JSON API is not reachable (HTTP ${ledger_code})."
|
|
945
|
+
exit 1
|
|
946
|
+
fi
|
|
947
|
+
|
|
665
948
|
log "Smoke checks passed."
|
|
666
949
|
}
|
|
667
950
|
|
|
@@ -751,6 +1034,7 @@ Environment:
|
|
|
751
1034
|
CANTON_LOCALNET_FAST_START=true|false Enable fast startup path (default: true)
|
|
752
1035
|
CANTON_LOCALNET_FORCE_FULL_START=true|false Force full startup with rebuild
|
|
753
1036
|
CANTON_LOCALNET_INFRA_ONLY=true|false Start only LocalNet + Keycloak infrastructure
|
|
1037
|
+
CANTON_LOCALNET_AUTH_MODE=oauth2|shared-secret
|
|
754
1038
|
CANTON_LOCALNET_QUICKSTART_DIR=<path> Use an existing cn-quickstart/quickstart directory
|
|
755
1039
|
USAGE
|
|
756
1040
|
}
|
|
@@ -763,6 +1047,7 @@ main() {
|
|
|
763
1047
|
|
|
764
1048
|
case "$1" in
|
|
765
1049
|
setup)
|
|
1050
|
+
validate_configuration
|
|
766
1051
|
ensure_docker_packages
|
|
767
1052
|
start_docker_daemon
|
|
768
1053
|
ensure_submodules
|
|
@@ -770,6 +1055,7 @@ main() {
|
|
|
770
1055
|
quickstart_setup
|
|
771
1056
|
;;
|
|
772
1057
|
start)
|
|
1058
|
+
validate_configuration
|
|
773
1059
|
require_command curl
|
|
774
1060
|
ensure_docker_packages
|
|
775
1061
|
start_docker_daemon
|
|
@@ -796,6 +1082,7 @@ main() {
|
|
|
796
1082
|
run_integration_tests
|
|
797
1083
|
;;
|
|
798
1084
|
verify)
|
|
1085
|
+
validate_configuration
|
|
799
1086
|
require_command curl
|
|
800
1087
|
ensure_docker_packages
|
|
801
1088
|
start_docker_daemon
|