#!/bin/bash if [[ "$0" != "${BASH_SOURCE[0]}" ]] ; then echo >&2 "Don't source this file, execute it instead, eg: ${BASH_SOURCE[0]} --help" return 1 fi usage() { cat <&2 "${tty_on}$*${tty_off}" } info() { local tty_on tty_off if [[ -t 2 ]] ; then tty_on=$'\033[0;36m' tty_off=$'\033[0m' fi echo >&2 "${tty_on}$*${tty_off}" } source "$(dirname "$0")"/import-stx || return 1 PROGNAME=$(basename "$0") MINIKUBE=minikube HELM=helm DOCKER=docker PYTHON3=python3 KUBECTL=kubectl DOCKER_PREFIX=${STX_PREBUILT_BUILDER_IMAGE_PREFIX:-'starlingx/'} DOCKER_IMAGES="stx-builder stx-pkgbuilder stx-lat-tool stx-aptly" DOCKER_TAG="$STX_PREBUILT_BUILDER_IMAGE_TAG" DOCKERHUB_LOGIN=0 BUILD_DOCKER=0 DELETE_ENV=0 RESTART_MINIKUBE=0 CLEAN_CONFIG=0 USE_DOCKER_CACHE=0 START_PODS=1 minikube_started() { local result result=$( minikube profile list \ | tr -d '|' \ | awk -v profile="$MINIKUBENAME" '{ if ($1 == profile && $7 == "Running") print $1 }' ) [[ -n "$result" ]] } minikube_exists() { local script=$(cat <<'END' import json,sys data = json.load (sys.stdin) if 'valid' not in data or 'invalid' not in data: sys.exit(1) for x in data['valid']+data['invalid']: if x['Name'] == sys.argv[1]: sys.exit(0) sys.exit(1) END ) $MINIKUBE profile list -l -o json | $PYTHON3 -c "$script" "$MINIKUBENAME" } helm_started() { local result result=$( if [ "$STX_PLATFORM" == "minikube" ]; then helm --kube-context "$MINIKUBENAME" ls --short --filter '^stx$' else helm --namespace "$STX_K8S_NAMESPACE" ls --short --filter '^stx$' fi 2>/dev/null ) || true [[ -n "$result" ]] } cmdline_error() { if [[ -n "$1" ]] ; then echo "error: $1" >&2 fi echo "Type \`$0 --help' for more info." >&2 exit 1 } # process command line temp=$(getopt -o hR --long help,clean,restart-minikube,rebuild::,cache,nuke,dockerhub-login,no-start -n "$PROGNAME" -- "$@") || cmdline_error eval set -- "$temp" while true ; do case "$1" in -h|--help) usage exit 0 ;; -R|--restart-minikube) RESTART_MINIKUBE=1 shift ;; --clean) CLEAN_CONFIG=1 shift ;; --rebuild) if [[ -n "$2" ]] ; then for img in $(echo "$2" | sed 's/,,*/ /g') ; do img_ok=no for known_img in $DOCKER_IMAGES ; do if [[ "$img" == "$known_img" || "stx-$img" == "$known_img" ]] ; then BUILD_DOCKER_IMAGES+="$known_img " img_ok=yes break fi done if [[ $img_ok != yes ]] ; then cmdline_error "invalid image \"$img\"" fi done else BUILD_DOCKER_IMAGES="$DOCKER_IMAGES" fi shift 2 ;; --cache) USE_DOCKER_CACHE=1 shift ;; --nuke) DELETE_ENV=1 shift ;; --dockerhub-login) DOCKERHUB_LOGIN=1 shift ;; --no-start) START_PODS=0 shift ;; --) shift break ;; -?*) cmdline_error ;; *) break ;; esac done [[ "$#" -le 0 ]] || cmdline_error "too many arguments" # make sure required programs are installed if [ "$STX_PLATFORM" = "minikube" ]; then if ! command -v "$MINIKUBE" &> /dev/null; then echo >&2 "Command $MINIKUBE could not be found." echo >&2 "Please install it as https://minikube.sigs.k8s.io/docs/start/" echo "" exit 1 fi fi if [ "$STX_PLATFORM" = "kubernetes" ]; then if ! command -v "$KUBECTL" &> /dev/null; then echo >&2 "Command $KUBECTL could not be found." echo >&2 "Please install and configure kubectl." echo "" exit 1 fi fi if ! command -v "$HELM" &> /dev/null; then echo >&2 "Command $HELM could not be found." echo >&2 "Please install it as https://helm.sh/" echo "" exit 1 fi if ! command -v "$DOCKER" &> /dev/null; then echo >&2 "Command $DOCKER could not be found. Please install it." echo >&2 "" exit 1 fi # clean the configuration and configmap data if [[ $CLEAN_CONFIG -eq 1 ]] ; then if helm_started ; then notice "Please firstly stop the helm project with 'stx control stop' command." notice "Then execute this cleanup operation again." exit 1 fi notice "Clean the config file and configmap data for builder|pkgbuilder container." # copy a fresh config file rm -f stx.conf cp stx.conf.sample stx.conf rm -f stx/lib/stx/__pycache__/* rm -f stx/stx-build-tools-chart/stx-builder/Chart.lock rm -f stx/stx-build-tools-chart/stx-builder/charts/* rm -f stx/stx-build-tools-chart/stx-builder/configmap/stx-localrc rm -f stx/stx-build-tools-chart/stx-builder/dependency_chart/stx-pkgbuilder/configmap/stx-localrc exit 0 fi # Make sure $STX_BUILD_HOME exists if [[ ! -d "$STX_BUILD_HOME" ]] ; then echo >&2 "The directory $STX_BUILD_HOME doesn't exist, please create it with the command:" echo >&2 "" echo >&2 " mkdir -p $STX_BUILD_HOME" echo >&2 "" echo >&2 "Then execute this script again!" exit 1 fi # Make sure mirror directory exists. If this directory doesn't exist, # it will be automatically created with root permission. if [[ ! -d "$STX_BUILD_HOME/mirrors/starlingx" ]] ; then mkdir -p $STX_BUILD_HOME/mirrors/starlingx || exit 1 fi # Login to docker hub if necessary if [[ "$DOCKERHUB_LOGIN" -eq 1 ]] ; then # This will save docker hub credentials in $HOME/.docker/config.json. If docker hub # credentials in that file are missing or invalid, this will ask for the username # and password on the current TTY and save them in the json file. If credentials # are already in the file, it will reuse them. In any case this will instruct # host's docker daemon to obtain an authentication token for all subsequent # interactions with docker hub. info "authenticating host docker daemon with docker hub" docker login || exit 1 fi if [ "$STX_PLATFORM" = "minikube" ]; then # MINIKUBE # --nuke: just delete the cluster and exit if [[ $DELETE_ENV -eq 1 ]] ; then if minikube_exists ; then notice "Deleting minikube cluster \`$MINIKUBENAME'" $MINIKUBE delete -p "$MINIKUBENAME" || exit 1 else notice "Please check your minikube cluster MINIKUBENAME: \`$MINIKUBENAME'." notice "It doesn't exist or it existed but not for your MINIKUBE_HOME: \`$MINIKUBE_HOME'." notice "Please re-export the correct project variable pairs!!!" fi exit 0 fi # Stop minikube if necessary WANT_START_MINIKUBE=0 if [[ $RESTART_MINIKUBE -eq 1 ]] ; then if minikube_started ; then notice "Stopping minikube cluster \`$MINIKUBENAME'" $MINIKUBE stop -p $MINIKUBENAME if minikube_started ; then echo >&2 "minikube container $MINIKUBENAME exist!" echo >&2 "And the command 'minikube -p $MINIKUBENAME stop' failed. The reason may be" echo >&2 "the current MINIKUBE_HOME/HOME is not the same as the $MINIKUBENAME" echo >&2 "Please change the MINIKUBE_HOME/HOME directory to the previous value" echo >&2 "then re-execute this script" exit 1 fi fi WANT_START_MINIKUBE=1 elif ! minikube_started ; then WANT_START_MINIKUBE=1 fi # Start minikube if [[ $WANT_START_MINIKUBE -eq 1 ]] ; then # FIXME: inject docker hub credentials into minikube's embedded docker daemon notice "Starting minikube cluster \`$MINIKUBENAME'" $MINIKUBE start --driver=docker -p $MINIKUBENAME \ --cpus=$STX_BUILD_CPUS \ --memory=$MINIKUBEMEMORY \ --mount=true \ --mount-string="$STX_BUILD_HOME:/workspace" \ || exit 1 fi # Record the project environment variables echo "The last minikube cluster startup date: `date`" > minikube_history.log echo "MINIKUBE_HOME: $MINIKUBE_HOME" >> minikube_history.log echo "MINIKUBENAME: $MINIKUBENAME" >> minikube_history.log echo "STX_BUILD_HOME: $STX_BUILD_HOME" >> minikube_history.log # Import minikube's docker environment. This points docker CLI to minikube's # embedded docker daemon. eval $(minikube -p $MINIKUBENAME docker-env) # Ask minikube's docker daemon to obtain docker hub's access token if [[ "$DOCKERHUB_LOGIN" -eq 1 ]] ; then info "authenticating minikube's docker daemon with docker hub" docker login || exit 1 fi elif [ "$STX_PLATFORM" = "kubernetes" ]; then if [[ $DELETE_ENV -eq 1 ]] ; then notice "--nuke not supported for Kubernetes platform" fi fi # Build docker images if [[ -n "${BUILD_DOCKER_IMAGES}" ]] ; then notice "Building docker images" declare -a docker_build_args if [[ "$USE_DOCKER_CACHE" != "1" ]] ; then docker_build_args+=("--no-cache") fi for img in $BUILD_DOCKER_IMAGES; do docker build "${docker_build_args[@]}" -t $img:$DOCKER_TAG_LOCAL -f stx/dockerfiles/$img.Dockerfile . || exit 1 info "built image $img:$DOCKER_TAG_LOCAL" done fi # Pull images that we didn't rebuild PULL_DOCKER_IMAGES=$( for img in ${DOCKER_IMAGES} ; do built=no for build_img in ${BUILD_DOCKER_IMAGES} ; do if [[ "$img" == "$build_img" ]] ; then built=yes break fi done if [[ "$built" != "yes" ]] && \ { [[ "$USE_DOCKER_CACHE" != 1 ]] || ! docker image inspect ${img}:${DOCKER_TAG_LOCAL} >/dev/null 2>&1 ; } ; then echo "$img" fi done ) if [[ -n "$PULL_DOCKER_IMAGES" ]] ; then notice "Pulling docker images: "$PULL_DOCKER_IMAGES for img in $PULL_DOCKER_IMAGES; do docker pull ${DOCKER_PREFIX}${img}:${DOCKER_TAG} || exit 1 docker tag ${DOCKER_PREFIX}${img}:${DOCKER_TAG} ${img}:${DOCKER_TAG_LOCAL} || exit 1 info "created image ${img}:${DOCKER_TAG_LOCAL} from pre-built ${DOCKER_PREFIX}${img}:${DOCKER_TAG}" done fi # Restart pods if [[ $START_PODS -eq 1 ]] ; then notice "Restarting pods" stx control stop || exit 1 stx config --upgrade || exit 1 # FIXME: inject docker hub credentials into k8s # FIXME: inject docker hub credentials into builder pod stx control start || exit 1 notice "Run 'stx control status' to check the pod startup status" fi