-
-
Notifications
You must be signed in to change notification settings - Fork 7
Expand file tree
/
Copy pathupdate.sh
More file actions
executable file
·178 lines (154 loc) · 7.84 KB
/
Copy pathupdate.sh
File metadata and controls
executable file
·178 lines (154 loc) · 7.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
source "$SCRIPT_DIR/utils/utils.sh" "$@"
# Nothing terminates TLS in the cluster in this mode, so any Certificate left
# over from a previous https install keeps retrying HTTP-01 against a server
# that no longer answers the challenge -- silently accumulating failed orders
# against Let's Encrypt's rate limit. watch_ssl_status is skipped below, so
# there is nothing to report it either.
if [ "$REVERSE_PROXY" = true ]; then
for CERT in 5stack-ssl 5stack-mediamtx-ssl; do
kubectl --kubeconfig=$KUBECONFIG delete certificate "$CERT" -n 5stack 2>/dev/null
done
fi
if [ "$REVERSE_PROXY" != true ]; then
step "Installing cert-manager"
apply_overlay overlays/cert-manager-crds || die "failed to install cert-manager"
for CRD in certificates.cert-manager.io issuers.cert-manager.io clusterissuers.cert-manager.io; do
if ! output_redirect kubectl --kubeconfig=$KUBECONFIG wait --for=condition=Established "crd/$CRD" --timeout=120s; then
die "cert-manager CRD $CRD never became established"
fi
done
ok "cert-manager CRDs ready"
# The CRDs are Established within a second of the apply, long before any
# cert-manager pod is running -- which is exactly why this wait exists. The
# overlay below carries the Certificate and the Issuer, and cert-manager's
# admission webhook rejects both outright while it is still starting.
step "Waiting for cert-manager"
wait_for_cert_manager || die "cert-manager did not become ready; re-run ./update.sh once it settles"
ok "cert-manager is ready"
fi
step "Building overlay manifests"
HTTP_REPLACEMENTS="$PANEL_DIR/overlays/http/http-replacements.yaml"
HTTPS_REPLACEMENTS="$PANEL_DIR/overlays/http/https-replacements.yaml"
# Whether an operator has asked for a TURN relay at all. Read straight from
# coturn's own env file rather than the environment: this is the same file the
# generated ConfigMap is built from, so the two can never disagree.
TURN_DOMAIN="$(grep -s '^TURN_DOMAIN=' "$PANEL_DIR/overlays/coturn/coturn.env" | tail -1 | cut -d= -f2- | tr -d '\r')"
TURN_DOMAIN="${TURN_DOMAIN%\"}"
TURN_DOMAIN="${TURN_DOMAIN#\"}"
OVERLAY_BASES=("vault" "local-secrets")
for BASE in "${OVERLAY_BASES[@]}"; do
for PROTOCOL in "http" "https"; do
OVERLAY="overlays/${BASE}-${PROTOCOL}"
mkdir -p "$OVERLAY"
# MediaMTX is a WebRTC relay, not an encoder, and it now also carries
# player cameras — which have nothing to do with GPU game streaming.
# Only the nvidia device plugin stays GPU-gated.
STREAMING_RESOURCES="$(if [[ "$PROTOCOL" == "https" ]]; then echo "- ../mediamtx-https"; else echo "- ../mediamtx"; fi)"
# The TURN relay is opt-in and most installs never need one: WebRTC
# connects directly for the large majority of players, and STUN covers
# most of the rest. Deployed only once TURN_DOMAIN is set, so nobody
# ends up running a relay -- on hostNetwork, holding port 3478 -- that
# they never asked for. It has no http/https split: it speaks TURN, not
# HTTP, and the media it relays is already DTLS-encrypted end to end.
if [ -n "$TURN_DOMAIN" ]; then
STREAMING_RESOURCES="$STREAMING_RESOURCES
- ../coturn"
fi
if [ "$GPU_VENDOR" = "nvidia" ]; then
STREAMING_RESOURCES="- ../nvidia
$STREAMING_RESOURCES"
fi
cat > "$OVERLAY/kustomization.yaml" <<EOF
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../$BASE
- ../config
$STREAMING_RESOURCES
$(if [[ "$PROTOCOL" == "https" ]]; then echo "- ../cert-manager"; fi)
EOF
if [ "$PROTOCOL" = "https" ]; then
cp overlays/http/ingress-patch.yaml "$OVERLAY/ingress-patch.yaml"
cat "$HTTPS_REPLACEMENTS" >> "$OVERLAY/kustomization.yaml"
else
cat "$HTTP_REPLACEMENTS" >> "$OVERLAY/kustomization.yaml"
fi
done
done
ok "overlays generated"
step "Applying kustomize overlay"
if [ "$VAULT_MANAGER" = true ]; then
OVERLAY_BASE="vault"
else
OVERLAY_BASE="local-secrets"
fi
if [ "$REVERSE_PROXY" = true ]; then
OVERLAY="overlays/${OVERLAY_BASE}-http"
else
OVERLAY="overlays/${OVERLAY_BASE}-https"
fi
# RustFS replaces MinIO on the *same* volume -- it reads a MinIO data directory
# in place, buckets, objects and IAM users included. That only holds while one
# of them is running: minio-pvc is ReadWriteOnce, but both pods land on the same
# node, and Kubernetes happily lets two pods on one node mount the same RWO
# claim. Two object stores writing one directory corrupts it, so the old
# StatefulSet has to be gone before the apply below creates the new one.
if kubectl --kubeconfig=$KUBECONFIG get statefulset minio -n 5stack >/dev/null 2>&1; then
step "Migrating MinIO to RustFS"
kubectl --kubeconfig=$KUBECONFIG delete statefulset minio -n 5stack >/dev/null 2>&1
kubectl --kubeconfig=$KUBECONFIG wait --for=delete pod -l app=minio -n 5stack --timeout=120s >/dev/null 2>&1
# Asserted against the live state rather than the wait's exit code: `wait`
# also fails when the selector matches nothing, which is the case where
# there is nothing left to wait for.
if [ -n "$(kubectl --kubeconfig=$KUBECONFIG get pods -l app=minio -n 5stack -o name 2>/dev/null)" ]; then
die "minio is still running; refusing to start rustfs on the same volume"
fi
ok "minio stopped; its volume is now served by rustfs"
fi
apply_overlay "$OVERLAY" || die "failed to apply $OVERLAY"
ok "overlay applied"
# Strictly after the apply: it is the apply that removes the cert-manager.io/issuer
# annotation from the ingresses, and until that lands ingress-shim recreates an
# Ingress-owned Certificate as fast as we can let go of one.
if [ "$REVERSE_PROXY" != true ]; then
disown_shim_owned_certificates
fi
if [ "$VAULT_MANAGER" = true ]; then
step "Syncing Vault secrets"
if ! resync_vault_secrets; then
exit 1
fi
fi
step "Recycling stateful workloads"
kubectl --kubeconfig=$KUBECONFIG delete deployment rustfs -n 5stack 2>/dev/null
kubectl --kubeconfig=$KUBECONFIG delete deployment timescaledb -n 5stack 2>/dev/null
kubectl --kubeconfig=$KUBECONFIG delete deployment typesense -n 5stack 2>/dev/null
kubectl --kubeconfig=$KUBECONFIG delete deployment redis -n 5stack 2>/dev/null
GIT_SHA=$(git rev-parse HEAD)
kubectl --kubeconfig=$KUBECONFIG label node $(kubectl --kubeconfig=$KUBECONFIG get nodes --selector='node-role.kubernetes.io/control-plane' -o jsonpath='{.items[0].metadata.name}') 5stack-panel-version=$GIT_SHA --overwrite
# Must track the mediamtx overlay above: the deployment's node affinity is
# requiredDuringScheduling, so without this label the pod never schedules.
kubectl --kubeconfig=$KUBECONFIG label node $(kubectl --kubeconfig=$KUBECONFIG get nodes --selector='node-role.kubernetes.io/control-plane' -o jsonpath='{.items[0].metadata.name}') 5stack-mediamtx=true --overwrite
if [ -n "$TURN_DOMAIN" ]; then
kubectl --kubeconfig=$KUBECONFIG label node $(kubectl --kubeconfig=$KUBECONFIG get nodes --selector='node-role.kubernetes.io/control-plane' -o jsonpath='{.items[0].metadata.name}') 5stack-coturn=true --overwrite
fi
SSL_OK=true
if [ "$REVERSE_PROXY" != true ]; then
watch_ssl_status || SSL_OK=false
fi
if [ "$SSL_OK" != true ]; then
banner "5Stack : Updated (SSL incomplete)"
# install.sh and game-node-server-setup.sh source this file, and an `exit`
# here would take them down with it -- suppressing the install banner and,
# on a game node, the Tailscale IP the operator needs to finish joining it.
# The cluster work all succeeded; only issuance is outstanding. So report a
# non-zero status when update.sh is what was run, and let a caller finish
# its own output otherwise.
if [ "${BASH_SOURCE[0]}" = "${0}" ]; then
exit 1
fi
return 1
fi
banner "5Stack : Updated"