Files
lofyerandfactory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> daffece57d feat(branding): update ZStack build tooling
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2026-08-04 14:37:07 +08:00

103 lines
3.0 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# build-image: one-shot build of the ZStack AIOS control-plane image from the
# workspace root. Builds the rebranded frontend, overlays it plus our patched
# backend sources onto the matching official release image, then (by default)
# smoke tests the result.
#
# It requires both forks to sit on the *same* v<version>-lofyer branch, so a
# build can never mix a frontend and backend from different upstream releases.
#
# Usage:
# scripts/build-image # build + verify
# scripts/build-image --no-verify # build only
# scripts/build-image --skip-ui-build # reuse existing frontend dist/
# scripts/build-image --push # push after a successful build
# scripts/build-image --dry-run # show what would happen
#
# Env knobs (also see gpustack-lofyer/hack/package-lofyer):
# NAMESPACE / REPOSITORY / TAG / IMAGE / BASE_IMAGE
# SMOKE_PORT host port used by the smoke test (default 18080)
#
set -o errexit
set -o nounset
set -o pipefail
source "$(dirname "${BASH_SOURCE[0]}")/lib/common.sh"
UI_BUILD=1
VERIFY=1
PUSH=0
DRY_RUN=0
SMOKE_PORT="${SMOKE_PORT:-18080}"
while [[ $# -gt 0 ]]; do
case "${1}" in
--skip-ui-build) UI_BUILD=0 ;;
--no-verify) VERIFY=0 ;;
--verify) VERIFY=1 ;;
--push) PUSH=1 ;;
--dry-run) DRY_RUN=1 ;;
-h|--help) sed -n '2,26p' "${0}"; exit 0 ;;
*) fail "unknown argument: ${1}" ;;
esac
shift
done
require_cmd docker git
require_repos
VERSION="$(resolve_workspace_version)"
TAG="${TAG:-${VERSION}}"
IMAGE="${IMAGE:-${NAMESPACE}/${REPOSITORY}:${TAG}}"
log "workspace version : ${VERSION}"
log "target image : ${IMAGE}"
# 1. Frontend.
step "Building frontend"
if [[ "${UI_BUILD}" == "1" ]]; then
require_cmd npm
if [[ "${DRY_RUN}" == "1" ]]; then
echo "(dry-run) (cd ${UI_REPO} && GPUSTACK_UI_VERSION=${VERSION} npm run build)"
else
(cd "${UI_REPO}" && GPUSTACK_UI_VERSION="${VERSION}" npm run build)
fi
else
log "skipping frontend build (--skip-ui-build)"
[[ -f "${UI_REPO}/dist/index.html" ]] \
|| fail "no existing frontend dist at ${UI_REPO}/dist (drop --skip-ui-build)"
fi
# 2. Image. Delegates to the backend packaging script, which stages the dist
# and only the python files that differ from the upstream tag.
step "Building image ${IMAGE}"
PACK_ENV=(
"NAMESPACE=${NAMESPACE}"
"REPOSITORY=${REPOSITORY}"
"TAG=${TAG}"
"IMAGE=${IMAGE}"
"UI_REPO=${UI_REPO}"
"PUSH=${PUSH}"
"DRY_RUN=${DRY_RUN}"
)
[[ -n "${BASE_IMAGE:-}" ]] && PACK_ENV+=("BASE_IMAGE=${BASE_IMAGE}")
env "${PACK_ENV[@]}" "${BACKEND_REPO}/hack/package-lofyer"
if [[ "${DRY_RUN}" == "1" ]]; then
log "dry-run complete"
exit 0
fi
# 3. Verify.
if [[ "${VERIFY}" == "1" ]]; then
step "Verifying ${IMAGE}"
IMAGE="${IMAGE}" SMOKE_PORT="${SMOKE_PORT}" "$(dirname "${BASH_SOURCE[0]}")/verify-image"
fi
step "Done"
log "image: ${IMAGE}"
log "run it with:"
echo " docker run -d --name zstack-aios -p 80:80 -v /var/run/docker.sock:/var/run/docker.sock ${IMAGE}"