diff --git a/k8s/awoooi-prod/06-deployment-api.yaml b/k8s/awoooi-prod/06-deployment-api.yaml index f1b6d4b9f..a2c4ce0f2 100644 --- a/k8s/awoooi-prod/06-deployment-api.yaml +++ b/k8s/awoooi-prod/06-deployment-api.yaml @@ -157,12 +157,12 @@ spec: - name: AWOOOI_BUILD_COMMIT_SHA # 2026-06-29 Codex: CD rewrites this to the deployed image tag so # production deploy readback does not rely on a stale static snapshot. - value: "af6e5848a8ba7c7e7e0a4f901e82cf30c151e31e" + value: "df6af166c9d1e3c0bd9b5da97a3465cddf3a86ed" - name: AWOOOI_DESIRED_API_IMAGE_TAG # 2026-06-30 Codex: CD rewrites this alongside AWOOOI_BUILD_COMMIT_SHA. # Production readback compares runtime image truth against this # GitOps desired tag instead of doing a slow Gitea raw fetch. - value: "af6e5848a8ba7c7e7e0a4f901e82cf30c151e31e" + value: "df6af166c9d1e3c0bd9b5da97a3465cddf3a86ed" - name: DATABASE_POOL_SIZE # 2026-07-01 Codex: production role `awoooi` currently has a low # connection limit. Keep API pool conservative until DB role diff --git a/k8s/awoooi-prod/08-deployment-ansible-executor-broker.yaml b/k8s/awoooi-prod/08-deployment-ansible-executor-broker.yaml index fab6ebc8b..165f4c454 100644 --- a/k8s/awoooi-prod/08-deployment-ansible-executor-broker.yaml +++ b/k8s/awoooi-prod/08-deployment-ansible-executor-broker.yaml @@ -66,7 +66,7 @@ spec: - name: DATABASE_NULL_POOL value: "true" - name: AWOOOI_BUILD_COMMIT_SHA - value: "af6e5848a8ba7c7e7e0a4f901e82cf30c151e31e" + value: "df6af166c9d1e3c0bd9b5da97a3465cddf3a86ed" - name: ENABLE_AWOOOP_ANSIBLE_CANDIDATE_BACKFILL_WORKER value: "false" - name: ENABLE_AWOOOP_ANSIBLE_CHECK_MODE_WORKER diff --git a/k8s/awoooi-prod/08-deployment-worker.yaml b/k8s/awoooi-prod/08-deployment-worker.yaml index 7e5dcda54..103d78ac6 100644 --- a/k8s/awoooi-prod/08-deployment-worker.yaml +++ b/k8s/awoooi-prod/08-deployment-worker.yaml @@ -178,7 +178,7 @@ spec: - name: DATABASE_BOOTSTRAP_DDL_ENABLED value: "false" - name: AWOOOI_BUILD_COMMIT_SHA - value: "af6e5848a8ba7c7e7e0a4f901e82cf30c151e31e" + value: "df6af166c9d1e3c0bd9b5da97a3465cddf3a86ed" - name: ENABLE_AWOOOP_ANSIBLE_CANDIDATE_BACKFILL_WORKER value: "true" - name: ENABLE_SECURITY_CONTROL_PLANE_MAINTENANCE_WORKER diff --git a/k8s/awoooi-prod/kustomization.yaml b/k8s/awoooi-prod/kustomization.yaml index 7dcc49193..fb91eab17 100644 --- a/k8s/awoooi-prod/kustomization.yaml +++ b/k8s/awoooi-prod/kustomization.yaml @@ -40,9 +40,9 @@ resources: # ⚠️ 重要: name 必須與 deployment YAML 中的 image 完全匹配 (含 tag) # newName + newTag 由 CI 透過 kustomize edit set image 注入 images: -- digest: sha256:6eddeb8742de3489e8e4767ed1e28f452ac3c3a42add33c405222e3c908137ac +- digest: sha256:708690b31eb51d0303d17ef667207be601b86d283785abdbeb031fca1b440784 name: 192.168.0.110:5000/library/api:IMAGE_TAG_PLACEHOLDER newName: 192.168.0.110:5000/awoooi/api -- digest: sha256:68851092697630242e70722b2dc96293254b9441e35b8f21b6fd910bf448894d +- digest: sha256:e3d664f234fca6975606e2de751ab09691743ada28b95c689139882d0cd34c77 name: 192.168.0.110:5000/library/web:IMAGE_TAG_PLACEHOLDER newName: 192.168.0.110:5000/awoooi/web diff --git a/ops/signoz/p0-obs-002-post-closure-regression.yaml b/ops/signoz/p0-obs-002-post-closure-regression.yaml index 0800683ed..3e1510057 100644 --- a/ops/signoz/p0-obs-002-post-closure-regression.yaml +++ b/ops/signoz/p0-obs-002-post-closure-regression.yaml @@ -778,9 +778,9 @@ pending_verifiers: independent_export_verifier_sha256: cbab56dd3919866a96550c1dce46ec67783cd6f00473e4491861e17d1430048c isolated_restore_driver_sha256: 38ce70b3f891a3ce8edfaeb880ccf69d0bb6817c3f801a0aefa0f06341901997 contract_tests_sha256: 474d9dfcfe170c62425356ea9f06ed0dc1629b39215ee80f395f721c7d43a923 - controlled_deployer_sha256: b3edcb3629aa3069fcecde5812cc4f21e83e324eec89b3c75f61cc73444adb97 - deployer_tests_sha256: cae135b2075d845f13d762c751d9e6de88bf806b37dcd5bd8837487211a20880 - test_terminal: 19_passed + controlled_deployer_sha256: ca64829e8cd850d83b016a6207bf463da586a68a4c78571e7a8734c93deb4766 + deployer_tests_sha256: 2092164f254b7c8b9064f2ffb1859e6dd4213b627992373719b3d9bc8a6ae200 + test_terminal: 20_passed portable_assets: - dashboards - alert_rules diff --git a/scripts/ops/deploy-signoz-metadata-toolchain.sh b/scripts/ops/deploy-signoz-metadata-toolchain.sh index d9981c188..ac447471e 100755 --- a/scripts/ops/deploy-signoz-metadata-toolchain.sh +++ b/scripts/ops/deploy-signoz-metadata-toolchain.sh @@ -395,7 +395,14 @@ mkdir -m 0700 "${RECEIPT_DIR}" "${CANDIDATE_DIR}" : > "${RECEIPT_LOG}" chmod 0600 "${RECEIPT_LOG}" -exec 8>>/tmp/awoooi-signoz-backup-operation.lock +OPERATION_LOCK=/tmp/awoooi-signoz-backup-operation.lock +[ -f "${OPERATION_LOCK}" ] && [ ! -L "${OPERATION_LOCK}" ] +# The shared lock is intentionally owned by the unprivileged backup account. +# Open the existing inode read-only so Linux fs.protected_regular=2 cannot +# reject a root O_CREAT/O_APPEND open in sticky /tmp. flock(2) still provides +# the same exclusive inter-process lock without changing file contents, +# ownership, or mode. Missing/unsafe lock state fails closed. +exec 8<"${OPERATION_LOCK}" flock -n 8 active_operations="$( (pgrep -af '(^|/|[[:space:]])(backup-signoz|clickhouse-native-backup|clickhouse-native-restore-drill|run-signoz-backup-canary)[.]sh([[:space:]]|$)' || true) \ diff --git a/scripts/ops/tests/test_signoz_metadata_toolchain_deploy.py b/scripts/ops/tests/test_signoz_metadata_toolchain_deploy.py index b2d1d130e..256f2feec 100644 --- a/scripts/ops/tests/test_signoz_metadata_toolchain_deploy.py +++ b/scripts/ops/tests/test_signoz_metadata_toolchain_deploy.py @@ -165,6 +165,15 @@ def test_deployer_has_no_active_pointer_or_destructive_fallback() -> None: assert "ln -s" not in source +def test_shared_operation_lock_is_existing_read_only_and_fail_closed() -> None: + source = DEPLOYER.read_text(encoding="utf-8") + assert "OPERATION_LOCK=/tmp/awoooi-signoz-backup-operation.lock" in source + assert '[ -f "${OPERATION_LOCK}" ] && [ ! -L "${OPERATION_LOCK}" ]' in source + assert 'exec 8<"${OPERATION_LOCK}"' in source + assert "flock -n 8" in source + assert "exec 8>>/tmp/awoooi-signoz-backup-operation.lock" not in source + + def test_exact_five_file_supply_chain_and_modes_are_fixed() -> None: source = DEPLOYER.read_text(encoding="utf-8") for path in ( diff --git a/scripts/reboot-recovery/signoz-canonical-route-preflight.py b/scripts/reboot-recovery/signoz-canonical-route-preflight.py index fed7e045b..d22a1e528 100644 --- a/scripts/reboot-recovery/signoz-canonical-route-preflight.py +++ b/scripts/reboot-recovery/signoz-canonical-route-preflight.py @@ -865,7 +865,7 @@ def evaluate(root: Path, contract_path: Path) -> dict[str, Any]: == len(METADATA_EXPORT_SOURCE_PATHS) and set(declared_metadata_export_hashes) == set(METADATA_EXPORT_SOURCE_PATHS) and declared_metadata_export_hashes == actual_metadata_export_hashes - and metadata_export_source_contract.get("test_terminal") == "19_passed" + and metadata_export_source_contract.get("test_terminal") == "20_passed" ) offsite_backup = pending_verifiers.get("signoz_backup_offsite_dr", {}) failed_artifacts = pending_verifiers.get( diff --git a/scripts/reboot-recovery/tests/test_signoz_canonical_route_migration.py b/scripts/reboot-recovery/tests/test_signoz_canonical_route_migration.py index ba17d042e..8015ff7d8 100644 --- a/scripts/reboot-recovery/tests/test_signoz_canonical_route_migration.py +++ b/scripts/reboot-recovery/tests/test_signoz_canonical_route_migration.py @@ -877,7 +877,7 @@ def test_post_release_verifier_and_native_backup_close_with_remaining_gaps() -> field: hashlib.sha256((ROOT / relative).read_bytes()).hexdigest() for field, relative in metadata_paths.items() } - assert source_contract["test_terminal"] == "19_passed" + assert source_contract["test_terminal"] == "20_passed" assert source_contract["raw_sqlite_read"] is False assert source_contract["raw_volume_read"] is False assert source_contract["secret_value_persistence"] is False