-
Notifications
You must be signed in to change notification settings - Fork 0
infra: prod 박스 관측 배선 스크립트 추가 #3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,90 @@ | ||
| #!/usr/bin/env bash | ||
| # | ||
| # extractor prod 박스 관측(Alloy) 배선 - 이 스크립트가 값의 SSOT다. | ||
| # | ||
| # TeamPiKi/infra 의 공통 Alloy 블록(blocks/alloy/config.alloy + provision-alloy.sh)을 | ||
| # fetch 하고, Grafana Cloud 자격을 SSM Parameter Store 에서 읽어 env 로 얹은 뒤 | ||
| # extractor 의 값(environment=prod, box=piki-extractor)으로 공통 블록을 호출한다. | ||
| # | ||
| # 실행 위치: extractor 박스 안 (SSM run-command 또는 세션 접속 후 직접 실행). | ||
| # 이 박스에는 aws cli 가 없어 SSM 조회는 dockerized aws cli 로 한다 | ||
| # (인스턴스 IAM 롤 + IMDSv2 hop limit 2 라 컨테이너 안에서도 자격 획득 가능). | ||
| # | ||
| # 전제: TeamPiKi/infra 의 공통 Alloy 블록 PR 이 머지돼 있어야 한다. 머지 전에는 | ||
| # --ref 로 그 PR 의 브랜치명을 지정해 선검증할 수 있다. | ||
| # | ||
| # 사용 예: | ||
| # provision-observability.sh # main(머지된 공통 블록) 사용 | ||
| # provision-observability.sh --ref feat/alloy-common-block # 머지 전 브랜치로 선검증 | ||
| # | ||
| # 인자: | ||
| # --ref (선택) TeamPiKi/infra git ref. 기본 main | ||
| # | ||
| # 종료 코드: 성공 0, fetch/SSM 조회/공통 블록 실행 실패 1, 인자 오류 2 | ||
|
|
||
| set -euo pipefail | ||
|
|
||
| REF="main" | ||
|
|
||
| while [ $# -gt 0 ]; do | ||
| case "$1" in | ||
| --ref) REF="${2:-}"; shift 2;; | ||
| *) echo "unknown arg: $1" >&2; exit 2;; | ||
| esac | ||
| done | ||
|
|
||
| [ -n "$REF" ] || { echo "--ref 값이 비었다" >&2; exit 2; } | ||
|
|
||
| WORK_DIR="/tmp/piki-obs" | ||
| mkdir -p "$WORK_DIR" | ||
|
|
||
| INFRA_RAW_BASE="https://raw.githubusercontent.com/TeamPiKi/infra/$REF/blocks/alloy" | ||
|
|
||
| # --- 1. 공통 Alloy 블록 fetch (repo public, 인증 불필요) --- | ||
| curl -fsSL "$INFRA_RAW_BASE/config.alloy" -o "$WORK_DIR/config.alloy" \ | ||
| || { echo "config.alloy fetch 실패 (ref=$REF)" >&2; exit 1; } | ||
| curl -fsSL "$INFRA_RAW_BASE/provision-alloy.sh" -o "$WORK_DIR/provision-alloy.sh" \ | ||
| || { echo "provision-alloy.sh fetch 실패 (ref=$REF)" >&2; exit 1; } | ||
|
Comment on lines
+44
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '\n== infra/scripts/provision-observability.sh ==\n'
wc -l infra/scripts/provision-observability.sh
sed -n '1,140p' infra/scripts/provision-observability.sh
printf '\n== Search for REF defaults and integrity checks ==\n'
rg -n --no-heading -S 'REF=|--ref|checksum|sha256|signature|gpg|cosign|main' infra/scriptsRepository: TeamPiKi/extractor Length of output: 4591 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '\n== infra/scripts/run-extractor.sh ==\n'
wc -l infra/scripts/run-extractor.sh
sed -n '1,220p' infra/scripts/run-extractor.shRepository: TeamPiKi/extractor Length of output: 3331 Pin the fetched observability scripts instead of defaulting to
🤖 Prompt for AI Agents |
||
|
|
||
| # --- 2. Grafana Cloud 자격을 SSM Parameter Store 에서 조회 --- | ||
| # 박스엔 aws cli 가 없어 dockerized aws cli 로 조회한다. | ||
| get_ssm_param() { | ||
| local param_name="$1" | ||
| docker run --rm --network host \ | ||
| -e AWS_DEFAULT_REGION=ap-northeast-2 \ | ||
| amazon/aws-cli ssm get-parameter \ | ||
| --name "$param_name" \ | ||
| --with-decryption \ | ||
| --query 'Parameter.Value' \ | ||
| --output text | ||
| } | ||
|
|
||
| # metrics/logs/token 5종은 필수 - 없으면 관측이 성립하지 않으므로 즉시 실패. | ||
| GRAFANA_METRICS_URL=$(get_ssm_param /piki-extractor/grafana-metrics-url) \ | ||
| || { echo "필수 SSM 파라미터 조회 실패: /piki-extractor/grafana-metrics-url" >&2; exit 1; } | ||
| GRAFANA_METRICS_USER=$(get_ssm_param /piki-extractor/grafana-metrics-user) \ | ||
| || { echo "필수 SSM 파라미터 조회 실패: /piki-extractor/grafana-metrics-user" >&2; exit 1; } | ||
| GRAFANA_LOGS_URL=$(get_ssm_param /piki-extractor/grafana-logs-url) \ | ||
| || { echo "필수 SSM 파라미터 조회 실패: /piki-extractor/grafana-logs-url" >&2; exit 1; } | ||
| GRAFANA_LOGS_USER=$(get_ssm_param /piki-extractor/grafana-logs-user) \ | ||
| || { echo "필수 SSM 파라미터 조회 실패: /piki-extractor/grafana-logs-user" >&2; exit 1; } | ||
| GRAFANA_CLOUD_TOKEN=$(get_ssm_param /piki-extractor/grafana-cloud-token) \ | ||
| || { echo "필수 SSM 파라미터 조회 실패: /piki-extractor/grafana-cloud-token" >&2; exit 1; } | ||
|
|
||
| # traces 2종은 선택 - 없으면 빈 값으로 둔다. 공통 config.alloy 가 더미 endpoint 로 | ||
| # fallback 해 trace export 만 비활성화되고(metrics/logs 는 정상 동작), 스크립트는 실패하지 않는다. | ||
| GRAFANA_TRACES_URL=$(get_ssm_param /piki-extractor/grafana-traces-url) || GRAFANA_TRACES_URL="" | ||
| GRAFANA_TRACES_USER=$(get_ssm_param /piki-extractor/grafana-traces-user) || GRAFANA_TRACES_USER="" | ||
|
|
||
| export GRAFANA_METRICS_URL GRAFANA_METRICS_USER | ||
| export GRAFANA_LOGS_URL GRAFANA_LOGS_USER | ||
| export GRAFANA_TRACES_URL GRAFANA_TRACES_USER | ||
| export GRAFANA_CLOUD_TOKEN | ||
|
|
||
| # --- 3. 공통 블록 호출 - 이 박스는 prod 전용이라 environment=prod 고정 --- | ||
| # (dev extractor 는 core dev 박스에 동거하며 그쪽 배선은 core 소관, 여기서 다루지 않는다) | ||
| bash "$WORK_DIR/provision-alloy.sh" \ | ||
| --config "$WORK_DIR/config.alloy" \ | ||
| --name piki-alloy \ | ||
| --environment prod \ | ||
| --box piki-extractor | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,91 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| #!/usr/bin/env bash | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # extractor 앱 컨테이너 (재)기동 - 이 스크립트가 컨테이너 기동의 신설 SSOT다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 지금까지 앱 컨테이너(piki-extractor)는 임시(수동 SSM)로 기동돼 run 파라미터가 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # repo 어디에도 없었다. 라벨·env 는 이 스크립트 한 곳에만 박는다 - 이 스크립트 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 밖에서 env 를 더하지 않는다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 실행 위치: extractor 박스 안 (SSM run-command 또는 세션 접속 후 직접 실행). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 박스엔 aws cli 가 없어 SSM 조회는 dockerized aws cli 로 한다 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # (인스턴스 IAM 롤 + IMDSv2 hop limit 2 라 컨테이너 안에서도 자격 획득 가능). | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 사용 예: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # run-extractor.sh --image piki-extractor:latest | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 인자: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # --image (필수) 기동할 이미지:태그. default 없음 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 종료 코드: 성공(헬스체크 통과) 0, SSM 조회/헬스체크 실패 1, 인자 오류 2 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| set -euo pipefail | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| IMAGE="" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| while [ $# -gt 0 ]; do | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| case "$1" in | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --image) IMAGE="${2:-}"; shift 2;; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| *) echo "unknown arg: $1" >&2; exit 2;; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| esac | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| done | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+25
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
If 🐛 Proposed fix case "$1" in
- --image) IMAGE="${2:-}"; shift 2;;
+ --image)
+ [ $# -ge 2 ] || { echo "--image requires a value" >&2; exit 2; }
+ IMAGE="$2"; shift 2;;
*) echo "unknown arg: $1" >&2; exit 2;;📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [ -n "$IMAGE" ] || { echo "--image is required" >&2; exit 2; } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # --- 1. GEMINI_API_KEY 를 SSM Parameter Store 에서 조회 --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| GEMINI_API_KEY=$( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| docker run --rm --network host \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -e AWS_DEFAULT_REGION=ap-northeast-2 \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| amazon/aws-cli ssm get-parameter \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --name /piki-extractor/gemini-api-key \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --with-decryption \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --query 'Parameter.Value' \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --output text | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) || { echo "필수 SSM 파라미터 조회 실패: /piki-extractor/gemini-api-key" >&2; exit 1; } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # --- 2. 기존 컨테이너 제거 후 재기동 (없으면 무시) --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| docker rm -f piki-extractor >/dev/null 2>&1 || true | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| docker run -d --name piki-extractor --restart unless-stopped \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -p 8090:8090 \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --add-host=host.docker.internal:host-gateway \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --label piki.observe=true \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --label piki.service=piki-extractor \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --label piki.metrics.port=8090 \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --label piki.metrics.path=/actuator/prometheus \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -e AWS_REGION=ap-northeast-2 \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -e GEMINI_API_KEY="$GEMINI_API_KEY" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -e TRACING_OTLP_ENABLED=true \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -e OTLP_ENDPOINT=http://host.docker.internal:4318/v1/traces \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| -e LOGGING_STRUCTURED_FORMAT_CONSOLE=ecs \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "$IMAGE" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+48
to
+60
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win Secret leaked via process command line.
🛡️ Proposed fix using an env-file with restricted permissions+ENV_FILE=$(mktemp)
+chmod 600 "$ENV_FILE"
+trap 'rm -f "$ENV_FILE"' EXIT
+cat > "$ENV_FILE" <<EOF
+AWS_REGION=ap-northeast-2
+GEMINI_API_KEY=$GEMINI_API_KEY
+TRACING_OTLP_ENABLED=true
+OTLP_ENDPOINT=http://host.docker.internal:4318/v1/traces
+LOGGING_STRUCTURED_FORMAT_CONSOLE=ecs
+EOF
+
docker run -d --name piki-extractor --restart unless-stopped \
-p 8090:8090 \
--add-host=host.docker.internal:host-gateway \
--label piki.observe=true \
--label piki.service=piki-extractor \
--label piki.metrics.port=8090 \
--label piki.metrics.path=/actuator/prometheus \
- -e AWS_REGION=ap-northeast-2 \
- -e GEMINI_API_KEY="$GEMINI_API_KEY" \
- -e TRACING_OTLP_ENABLED=true \
- -e OTLP_ENDPOINT=http://host.docker.internal:4318/v1/traces \
- -e LOGGING_STRUCTURED_FORMAT_CONSOLE=ecs \
+ --env-file "$ENV_FILE" \
"$IMAGE"📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 라벨 4종(piki.observe/piki.service/piki.metrics.port/piki.metrics.path)은 공통 Alloy 의 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # label opt-in 계약(TeamPiKi/infra contracts/observability.md) - 이 라벨이 있어야 박스 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # Alloy 가 이 컨테이너를 스크레이프 대상으로 인식한다. piki.metrics.port 는 컨테이너 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 내부 포트가 아니라 "호스트 127.0.0.1 에서 닿는 포트" 다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # -p 8090:8090 전체 바인드: 이 박스는 SG 로 인바운드가 앱 SG 에서만 허용되니(SG 격리) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 외부 노출이 없다. core 앱은 이 박스의 private IP 로 이 포트를 호출한다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # --add-host=host.docker.internal:host-gateway + OTLP_ENDPOINT=...host.docker.internal:4318: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 트레이스는 앱이 박스 로컬 Alloy(4318, OTLP HTTP)로 능동적으로 push 하는 유일한 신호다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 이 컨테이너는 bridge 네트워크라 host-gateway 를 거쳐야 호스트의 Alloy 에 닿는다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # LOGGING_STRUCTURED_FORMAT_CONSOLE=ecs: 공통 Loki 파이프라인이 ECS JSON 포맷을 전제로 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # level 라벨링·trace 상관을 한다(Spring Boot 구조화 로깅, relaxed binding 으로 이 env 하나면 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 활성화된다). 형식이 다르면 그쪽 파이프라인이 파싱하지 못한다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 이 스크립트를 박스에 첫 적용할 때는 기존 임시 기동 컨테이너를 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # `docker inspect piki-extractor` 로 대조해, 누락된 env 가 있으면 여기(이 스크립트)에 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # 흡수시킨다 - 이 스크립트 밖에서 별도로 env 를 더하지 않는다. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # --- 3. 헬스 대기 - 공통 healthcheck 블록을 dogfooding --- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| HEALTHCHECK_SH="/tmp/piki-run-extractor-healthcheck.sh" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| curl -fsSL https://raw.githubusercontent.com/TeamPiKi/infra/main/blocks/healthcheck.sh -o "$HEALTHCHECK_SH" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| || { echo "healthcheck.sh fetch 실패" >&2; exit 1; } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+82
to
+85
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🔒 Security & Privacy | 🟠 Major | 🏗️ Heavy lift 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '\n== run-extractor excerpt ==\n'
sed -n '60,120p' infra/scripts/run-extractor.sh
printf '\n== provision-observability excerpt ==\n'
sed -n '1,220p' infra/scripts/provision-observability.sh
printf '\n== search for healthcheck.sh and ref override ==\n'
rg -n "healthcheck\.sh|--ref|raw\.githubusercontent|bash .*healthcheck|HEALTHCHECK_SH" infra/scriptsRepository: TeamPiKi/extractor Length of output: 6109 Pin the fetched healthcheck script instead of pulling 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bash "$HEALTHCHECK_SH" \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --url http://localhost:8090/actuator/health \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --interval 5 \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --attempts 24 \ | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| --expect-body '"status":"UP"' | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Same missing-value edge case as
run-extractor.sh's--imageparsing.If
--refis passed with no following value,shift 2on a single remaining positional param fails underset -e, crashing before the[ -n "$REF" ]check at line 36 can produce the intended "인자 오류" message.🤖 Prompt for AI Agents