feat(objectstorage): add Aliyun OSS support and auto-detect provider in deploy workflows

Introduces Aliyun OSS as an alternative to MinIO; deploy scripts and CI
workflows now read object_storage.provider from config and conditionally
include or skip MinIO resources in both Docker Compose and k3s paths.
Also adds ops scheduler domain and its migration tables.

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-20 10:25:02 +08:00
parent 00eb514efc
commit 98f73c5bea
18 changed files with 901 additions and 34 deletions
+244
View File
@@ -697,6 +697,103 @@ jobs:
printf '%s:%s' "$(image_name "$1")" "${IMAGE_TAG}"
}
ensure_config_aliases() {
for yaml in config.yaml config.local.yaml ops-config.yaml ops-config.local.yaml; do
yml="${yaml%.yaml}.yml"
if [ ! -f "${release_dir}/deploy/${yaml}" ] && [ -f "${release_dir}/deploy/${yml}" ]; then
cp "${release_dir}/deploy/${yml}" "${release_dir}/deploy/${yaml}"
echo "Created ${yaml} from ${yml} for deployment mounts."
fi
done
if [ ! -f "${release_dir}/deploy/prompts.yml" ] && [ -f "${release_dir}/deploy/prompts.yaml" ]; then
cp "${release_dir}/deploy/prompts.yaml" "${release_dir}/deploy/prompts.yml"
echo "Created prompts.yml from prompts.yaml for deployment mounts."
fi
}
config_file_path() {
base="$1"
for file in "${release_dir}/deploy/${base}.yaml" "${release_dir}/deploy/${base}.yml"; do
if [ -f "${file}" ]; then
printf '%s' "${file}"
return 0
fi
done
}
read_object_storage_provider() {
provider="minio"
for file in "$(config_file_path config)" "$(config_file_path config.local)"; do
if [ -z "${file}" ] || [ ! -f "${file}" ]; then
continue
fi
next="$(
awk '
/^[[:space:]]*object_storage:[[:space:]]*$/ {
in_section=1
base=match($0, /[^[:space:]]/) - 1
next
}
in_section {
indent=match($0, /[^[:space:]]/) - 1
if ($0 ~ /^[[:space:]]*$/ || $0 ~ /^[[:space:]]*#/) {
next
}
if (indent <= base) {
in_section=0
next
}
if ($0 ~ /^[[:space:]]*provider[[:space:]]*:/) {
value=$0
sub(/^[[:space:]]*provider[[:space:]]*:[[:space:]]*/, "", value)
sub(/[[:space:]]+#.*$/, "", value)
gsub(/^["'\'']|["'\'']$/, "", value)
print value
}
}
' "${file}" | tail -1
)"
if [ -n "${next}" ]; then
provider="${next}"
fi
done
printf '%s' "$(printf '%s' "${provider}" | tr '[:upper:]' '[:lower:]' | tr -d '[:space:]')"
}
use_minio_for_object_storage() {
case "$(read_object_storage_provider)" in
""|minio|mino)
return 0
;;
aliyun|aliyun_oss|aliyun-oss|oss)
return 1
;;
*)
return 0
;;
esac
}
sync_k3s_config() {
mkdir -p "${release_dir}/deploy/k3s/config"
for name in config ops-config prompts; do
output="${name}.yaml"
if [ "${name}" = "prompts" ]; then
output="prompts.yml"
fi
source=""
for candidate in "${release_dir}/deploy/${name}.yaml" "${release_dir}/deploy/${name}.yml"; do
if [ -f "${candidate}" ]; then
source="${candidate}"
break
fi
done
if [ -n "${source}" ]; then
cp "${source}" "${release_dir}/deploy/k3s/config/${output}"
fi
done
}
echo "Sudo mode: ${SUDO_MODE}"
kubectl_cmd version --client
@@ -797,6 +894,128 @@ jobs:
sed -i "\#name: ${old_name}#,\#newTag:# s#newTag: .*#newTag: ${IMAGE_TAG}#" "${rendered_dir}/kustomization.yaml"
}
apply_object_storage_kustomize_mode() {
sync_k3s_config
provider="$(read_object_storage_provider)"
if use_minio_for_object_storage; then
echo "object_storage.provider=${provider}; deploying MinIO."
return 0
fi
echo "object_storage.provider=${provider}; skipping MinIO."
sed -i '/^patches:[[:space:]]*$/,/^[^[:space:]-]/{/^patches:[[:space:]]*$/d;/^[^[:space:]-]/!d;}' "${rendered_dir}/kustomization.yaml"
mkdir -p "${rendered_dir}/patches"
cat > "${rendered_dir}/patches/object-storage-env.yaml" <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
name: tenant-api
spec:
template:
spec:
containers:
- name: tenant-api
env:
- name: OBJECT_STORAGE_ACCESS_KEY
$patch: delete
- name: OBJECT_STORAGE_SECRET_KEY
$patch: delete
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: worker-generate
spec:
template:
spec:
containers:
- name: worker-generate
env:
- name: OBJECT_STORAGE_ACCESS_KEY
$patch: delete
- name: OBJECT_STORAGE_SECRET_KEY
$patch: delete
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: kol-assist-worker
spec:
template:
spec:
containers:
- name: kol-assist-worker
env:
- name: OBJECT_STORAGE_ACCESS_KEY
$patch: delete
- name: OBJECT_STORAGE_SECRET_KEY
$patch: delete
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: scheduler
spec:
template:
spec:
containers:
- name: scheduler
env:
- name: OBJECT_STORAGE_ACCESS_KEY
$patch: delete
- name: OBJECT_STORAGE_SECRET_KEY
$patch: delete
EOF
cat >> "${rendered_dir}/kustomization.yaml" <<'EOF'
patches:
- target:
version: v1
kind: Service
name: minio
patch: |-
$patch: delete
apiVersion: v1
kind: Service
metadata:
name: minio
- target:
group: apps
version: v1
kind: StatefulSet
name: minio
patch: |-
$patch: delete
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: minio
- target:
group: batch
version: v1
kind: Job
name: minio-init
patch: |-
$patch: delete
apiVersion: batch/v1
kind: Job
metadata:
name: minio-init
- path: patches/object-storage-env.yaml
EOF
}
cleanup_minio_if_external_object_storage() {
if use_minio_for_object_storage; then
return 0
fi
kubectl_cmd -n "${K3S_NAMESPACE}" delete statefulset minio --ignore-not-found
kubectl_cmd -n "${K3S_NAMESPACE}" delete service minio --ignore-not-found
kubectl_cmd -n "${K3S_NAMESPACE}" delete job minio-init --ignore-not-found
for svc in tenant-api worker-generate kol-assist-worker scheduler; do
kubectl_cmd -n "${K3S_NAMESPACE}" set env "deployment/${svc}" OBJECT_STORAGE_ACCESS_KEY- OBJECT_STORAGE_SECRET_KEY- >/dev/null 2>&1 || true
done
}
render_kustomize() {
rm -rf "${rendered_dir}"
mkdir -p "${rendered_dir}"
@@ -808,6 +1027,7 @@ jobs:
# Migrations are applied explicitly by this workflow after preflight.
sed -i '/^[[:space:]]*- jobs.yaml[[:space:]]*$/d' "${rendered_dir}/kustomization.yaml"
apply_object_storage_kustomize_mode
patch_kustomize_image "geo-rankly/migrate" "migrate"
patch_kustomize_image "geo-rankly/tenant-api" "tenant-api"
@@ -832,6 +1052,7 @@ jobs:
}
apply_config_map() {
sync_k3s_config
kubectl_cmd -n "${K3S_NAMESPACE}" create configmap geo-rankly-app-config \
--from-file=config.yaml="${release_dir}/deploy/k3s/config/config.yaml" \
--from-file=prompts.yml="${release_dir}/deploy/k3s/config/prompts.yml" \
@@ -847,6 +1068,27 @@ jobs:
sed -i "s#image: geo-rankly/migrate:latest#image: $(image_ref migrate)#" "${rendered_jobs}"
kubectl_cmd -n "${K3S_NAMESPACE}" delete job migrate minio-init --ignore-not-found
if ! use_minio_for_object_storage; then
awk '
/^---[[:space:]]*$/ { doc=doc "\n" $0 "\n"; next }
{ doc=doc $0 "\n" }
END {
n=split(doc, docs, /\n---\n/)
for (i=1; i<=n; i++) {
if (docs[i] ~ /kind:[[:space:]]*Job/ && docs[i] ~ /name:[[:space:]]*minio-init/) {
continue
}
if (docs[i] ~ /[^[:space:]]/) {
if (printed) print "---"
printf "%s", docs[i]
if (substr(docs[i], length(docs[i]), 1) != "\n") print ""
printed=1
}
}
}
' "${rendered_jobs}" > "${rendered_jobs}.tmp"
mv "${rendered_jobs}.tmp" "${rendered_jobs}"
fi
kubectl_cmd -n "${K3S_NAMESPACE}" apply -f "${rendered_jobs}"
}
@@ -959,7 +1201,9 @@ jobs:
if [ -n "${IMAGE_LIST}" ]; then
ensure_plain_http_registry
fi
ensure_config_aliases
ensure_namespace
cleanup_minio_if_external_object_storage
if [ -n "${IMAGE_LIST}" ]; then
ensure_registry_secret
else