unoverse 0.1.151 → 0.1.153
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/operator/lib/deploy.sh +51 -1
- package/operator/operator.sh +11 -0
- package/package.json +1 -1
package/operator/lib/deploy.sh
CHANGED
|
@@ -577,6 +577,50 @@ _ensure_ground_config() {
|
|
|
577
577
|
|
|
578
578
|
}
|
|
579
579
|
|
|
580
|
+
# A CREDENTIAL FAILURE IS A SIGN-IN PROBLEM, NOT A TERRAFORM PROBLEM.
|
|
581
|
+
#
|
|
582
|
+
# The most common way an AWS deploy fails is an expired SSO token: it happens to every
|
|
583
|
+
# operator, on a schedule, forever. Terraform reports it as a provider stack trace
|
|
584
|
+
# (InvalidGrantException, "failed to refresh cached credentials"), which reads as a
|
|
585
|
+
# broken setup and sends the operator debugging the wrong thing. Recognise the
|
|
586
|
+
# signatures and answer with the fix instead of the trace.
|
|
587
|
+
_plan_hit_credentials() {
|
|
588
|
+
local cloud="$1" log="$2"
|
|
589
|
+
if [ "$cloud" = "aws" ]; then
|
|
590
|
+
grep -qE "No valid credential sources|refresh cached SSO token|InvalidGrantException|ExpiredToken|InvalidClientTokenId|security token included in the request is (expired|invalid)" "$log"
|
|
591
|
+
else
|
|
592
|
+
grep -qE "Unable to authenticate you|invalid or missing.*token|401.*Unauthorized" "$log"
|
|
593
|
+
fi
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
_credentials_help() {
|
|
597
|
+
local cloud="$1"
|
|
598
|
+
echo ""
|
|
599
|
+
if [ "$cloud" = "aws" ]; then
|
|
600
|
+
fail "AWS did not accept your credentials, so nothing was changed."
|
|
601
|
+
echo ""
|
|
602
|
+
info "This is almost always an expired sign-in, not a broken setup:"
|
|
603
|
+
echo ""
|
|
604
|
+
echo -e " Signed in with SSO? ${BOLD}aws sso login${NC}${AWS_PROFILE:+ ${BOLD}--profile $AWS_PROFILE${NC}} ${DIM}(tokens expire on a schedule; this is the usual fix)${NC}"
|
|
605
|
+
echo -e " Profile not selected? ${BOLD}export AWS_PROFILE=<name>${NC} ${DIM}(currently: ${AWS_PROFILE:-not set})${NC}"
|
|
606
|
+
echo -e " Using access keys? ${BOLD}aws configure${NC} ${DIM}(or export AWS_ACCESS_KEY_ID / AWS_SECRET_ACCESS_KEY)${NC}"
|
|
607
|
+
echo ""
|
|
608
|
+
info "Confirm it works, then deploy again:"
|
|
609
|
+
echo -e " ${BOLD}aws sts get-caller-identity${NC}"
|
|
610
|
+
echo ""
|
|
611
|
+
echo -e " ${DIM}Setting up AWS credentials for the first time:${NC}"
|
|
612
|
+
echo -e " ${DIM}https://docs.aws.amazon.com/cli/latest/userguide/getting-started-quickstart.html${NC}"
|
|
613
|
+
else
|
|
614
|
+
fail "DigitalOcean did not accept your token, so nothing was changed."
|
|
615
|
+
echo ""
|
|
616
|
+
info "The API token is expired, revoked, or not set:"
|
|
617
|
+
echo ""
|
|
618
|
+
echo -e " Mint one (Write scope): ${BOLD}https://cloud.digitalocean.com/account/api/tokens${NC}"
|
|
619
|
+
echo -e " Then provide it: ${BOLD}export DIGITALOCEAN_TOKEN=<token>${NC} ${DIM}(or do_token in terraform.tfvars)${NC}"
|
|
620
|
+
fi
|
|
621
|
+
echo ""
|
|
622
|
+
}
|
|
623
|
+
|
|
580
624
|
_ground_apply() {
|
|
581
625
|
local cloud="$1" tmp planfile rc
|
|
582
626
|
# SEPARATE STATEMENT. On macOS bash 3.2 a single `local a="$1" b="...$a"` expands $a
|
|
@@ -595,7 +639,13 @@ _ground_apply() {
|
|
|
595
639
|
case "$rc" in
|
|
596
640
|
0) rm -rf "$tmp"; return 3 ;;
|
|
597
641
|
2) : ;;
|
|
598
|
-
*)
|
|
642
|
+
*)
|
|
643
|
+
if _plan_hit_credentials "$cloud" "$tmp/plan.log"; then
|
|
644
|
+
_credentials_help "$cloud"
|
|
645
|
+
else
|
|
646
|
+
fail "Terraform could not plan the change:"; tail -20 "$tmp/plan.log" | sed 's/^/ /'
|
|
647
|
+
fi
|
|
648
|
+
rm -rf "$tmp"; return 1 ;;
|
|
599
649
|
esac
|
|
600
650
|
|
|
601
651
|
# STOPPING IS FOR LOSING SOMETHING, NOT FOR BUILDING IT. Typing `unoverse deploy` is
|
package/operator/operator.sh
CHANGED
|
@@ -157,6 +157,17 @@ case "${1:-}" in
|
|
|
157
157
|
if [ -n "$(docker compose -f "$ROOT/docker-compose.yml" ps -q 2>/dev/null)" ]; then
|
|
158
158
|
docker compose -f "$ROOT/docker-compose.yml" --env-file "$ROOT/.env" up -d --remove-orphans >/dev/null 2>&1 \
|
|
159
159
|
&& ok "Running services moved to the new images"
|
|
160
|
+
# MIGRATIONS RUN ON UPDATE, same as deploy and start. An update is exactly when a
|
|
161
|
+
# new migration arrives (it ships inside the image just pulled), and this was the
|
|
162
|
+
# one path that skipped db-setup: a universe could run new code against a schema
|
|
163
|
+
# missing the columns that code expects, silently, until something read them.
|
|
164
|
+
# Additive-by-rule until Retire and idempotent, so re-running costs nothing.
|
|
165
|
+
# Subshell because cmd_db_setup exits rather than returns on failure.
|
|
166
|
+
if ! (cmd_db_setup) >/dev/null 2>&1; then
|
|
167
|
+
warn "Migrations did not apply. Run ${BOLD}unoverse check${NC} to see why"
|
|
168
|
+
else
|
|
169
|
+
ok "Database migrations are current"
|
|
170
|
+
fi
|
|
160
171
|
echo ""
|
|
161
172
|
echo -e " ${GREEN}unoverse where${NC} Links to your Canvas and API"
|
|
162
173
|
echo ""
|
package/package.json
CHANGED