fix(pb-init): rewrite ensure_field with pure sh/awk, fix HTTP status parsing
The previous ensure_fields helper used python3 which is not available in alpine:3.19, causing exit 127 in the cloud init container. Replaced with ensure_field (per-field, no python/jq) that uses only busybox sh, wget, sed, and awk. Also fixed the HTTP status grep pattern in create_collection and ensure_field to match only the response header line (^ HTTP/) instead of the wget error line, eliminating the spurious 'unexpected status server' warnings.
This commit is contained in:
@@ -47,7 +47,7 @@ create_collection() {
|
|||||||
--header="Content-Type: application/json" \
|
--header="Content-Type: application/json" \
|
||||||
--header="Authorization: Bearer $TOKEN" \
|
--header="Authorization: Bearer $TOKEN" \
|
||||||
--post-data="$BODY" \
|
--post-data="$BODY" \
|
||||||
"$PB_URL/api/collections" 2>&1 | grep "HTTP/" | tail -1 | awk '{print $2}')
|
"$PB_URL/api/collections" 2>&1 | grep "^ HTTP/" | awk '{print $2}')
|
||||||
case "$STATUS" in
|
case "$STATUS" in
|
||||||
200|201) log "created collection: $NAME" ;;
|
200|201) log "created collection: $NAME" ;;
|
||||||
400|422) log "collection already exists (skipped): $NAME" ;;
|
400|422) log "collection already exists (skipped): $NAME" ;;
|
||||||
@@ -55,56 +55,49 @@ create_collection() {
|
|||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
# Patch a collection by name: adds any fields listed in FIELDS_JSON that are
|
# ensure_field COLLECTION FIELD_NAME FIELD_TYPE
|
||||||
# missing from the current schema. This is idempotent and safe to re-run.
|
#
|
||||||
ensure_fields() {
|
# Checks whether FIELD_NAME exists in COLLECTION's schema. If it is missing,
|
||||||
NAME="$1"
|
# sends a PATCH with the full current fields list plus the new field appended.
|
||||||
FIELDS_JSON="$2" # JSON array of field objects to guarantee exist
|
# Uses only busybox sh + wget + sed/awk — no python/jq required.
|
||||||
|
ensure_field() {
|
||||||
|
COLL="$1"
|
||||||
|
FIELD_NAME="$2"
|
||||||
|
FIELD_TYPE="$3"
|
||||||
|
|
||||||
# Fetch current schema
|
SCHEMA=$(wget -qO- \
|
||||||
CURRENT=$(wget -qO- \
|
|
||||||
--header="Authorization: Bearer $TOKEN" \
|
--header="Authorization: Bearer $TOKEN" \
|
||||||
"$PB_URL/api/collections/$NAME" 2>/dev/null)
|
"$PB_URL/api/collections/$COLL" 2>/dev/null)
|
||||||
|
|
||||||
COLLECTION_ID=$(echo "$CURRENT" | sed 's/.*"id":"\([^"]*\)".*/\1/')
|
# Check if the field already exists (look for "name":"<FIELD_NAME>" in the fields array)
|
||||||
if [ -z "$COLLECTION_ID" ] || [ "$COLLECTION_ID" = "$CURRENT" ]; then
|
if echo "$SCHEMA" | grep -q "\"name\":\"$FIELD_NAME\""; then
|
||||||
log "WARNING: could not get id for collection $NAME — skipping ensure_fields"
|
log "field $COLL.$FIELD_NAME already exists — skipping"
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Build merged fields list via a small python snippet
|
COLLECTION_ID=$(echo "$SCHEMA" | sed 's/.*"id":"\([^"]*\)".*/\1/')
|
||||||
MERGED=$(python3 - "$CURRENT" "$FIELDS_JSON" <<'PYEOF'
|
if [ -z "$COLLECTION_ID" ] || [ "$COLLECTION_ID" = "$SCHEMA" ]; then
|
||||||
import sys, json
|
log "WARNING: could not get id for collection $COLL — skipping ensure_field"
|
||||||
current = json.loads(sys.argv[1])
|
|
||||||
desired = json.loads(sys.argv[2])
|
|
||||||
existing_names = {f["name"] for f in current.get("fields", [])}
|
|
||||||
all_fields = list(current.get("fields", []))
|
|
||||||
added = []
|
|
||||||
for f in desired:
|
|
||||||
if f["name"] not in existing_names:
|
|
||||||
all_fields.append(f)
|
|
||||||
added.append(f["name"])
|
|
||||||
print(json.dumps({"fields": all_fields, "_added": added}))
|
|
||||||
PYEOF
|
|
||||||
)
|
|
||||||
|
|
||||||
ADDED=$(echo "$MERGED" | python3 -c 'import sys,json; d=json.load(sys.stdin); print(",".join(d.get("_added",[])))' 2>/dev/null)
|
|
||||||
if [ -z "$ADDED" ]; then
|
|
||||||
log "collection $NAME schema up-to-date"
|
|
||||||
return
|
return
|
||||||
fi
|
fi
|
||||||
|
|
||||||
PATCH_BODY=$(echo "$MERGED" | python3 -c 'import sys,json; d=json.load(sys.stdin); d.pop("_added",None); print(json.dumps(d))' 2>/dev/null)
|
# Extract current fields array (everything between the outermost [ ] of "fields":[...])
|
||||||
|
# and append the new field object before the closing bracket.
|
||||||
|
CURRENT_FIELDS=$(echo "$SCHEMA" | sed 's/.*"fields":\(\[.*\]\).*/\1/')
|
||||||
|
# Strip the trailing ] and append the new field
|
||||||
|
TRIMMED=$(echo "$CURRENT_FIELDS" | sed 's/]$//')
|
||||||
|
NEW_FIELDS="${TRIMMED},{\"name\":\"${FIELD_NAME}\",\"type\":\"${FIELD_TYPE}\"}]"
|
||||||
|
PATCH_BODY="{\"fields\":${NEW_FIELDS}}"
|
||||||
|
|
||||||
STATUS=$(wget -qSO- \
|
STATUS=$(wget -qSO- \
|
||||||
--header="Content-Type: application/json" \
|
--header="Content-Type: application/json" \
|
||||||
--header="Authorization: Bearer $TOKEN" \
|
--header="Authorization: Bearer $TOKEN" \
|
||||||
--body-data="$PATCH_BODY" \
|
--body-data="$PATCH_BODY" \
|
||||||
--method=PATCH \
|
--method=PATCH \
|
||||||
"$PB_URL/api/collections/$COLLECTION_ID" 2>&1 | grep "HTTP/" | tail -1 | awk '{print $2}')
|
"$PB_URL/api/collections/$COLLECTION_ID" 2>&1 | grep "^ HTTP/" | awk '{print $2}')
|
||||||
case "$STATUS" in
|
case "$STATUS" in
|
||||||
200|201) log "patched collection $NAME — added fields: $ADDED" ;;
|
200|201) log "patched $COLL — added field: $FIELD_NAME ($FIELD_TYPE)" ;;
|
||||||
*) log "WARNING: patch returned $STATUS for collection $NAME" ;;
|
*) log "WARNING: patch returned $STATUS when adding $FIELD_NAME to $COLL" ;;
|
||||||
esac
|
esac
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,8 +184,6 @@ create_collection "app_users" '{
|
|||||||
# ─── 5. Schema migrations (idempotent field additions) ───────────────────────
|
# ─── 5. Schema migrations (idempotent field additions) ───────────────────────
|
||||||
# Ensures fields added after initial deploy are present in existing instances.
|
# Ensures fields added after initial deploy are present in existing instances.
|
||||||
|
|
||||||
ensure_fields "progress" '[
|
ensure_field "progress" "user_id" "text"
|
||||||
{"name": "user_id", "type": "text"}
|
|
||||||
]'
|
|
||||||
|
|
||||||
log "all collections ready"
|
log "all collections ready"
|
||||||
|
|||||||
Reference in New Issue
Block a user