From 21d1812dfd078396ff2681af3a4c51a611f85bf7 Mon Sep 17 00:00:00 2001 From: Pavel Sturc Date: Fri, 1 Jul 2022 17:20:35 +0200 Subject: [PATCH] feat: add openshift-ci related scripts --- .ci/openshift-ci/Dockerfile | 9 +- .gitignore | 1 + Makefile | 12 ++ cmd/mage/main.go | 9 + docs/Installation.md | 21 +-- go.mod | 1 + go.sum | 4 + mage | 11 ++ magefiles/magefile.go | 230 ++++++++++++++++++++++++++ magefiles/types.go | 49 ++++++ magefiles/utils.go | 51 ++++++ scripts/install-appstudio.sh | 47 ++++++ scripts/provision-openshift-user.sh | 4 +- scripts/run-appstudio-healthchecks.sh | 54 ++++++ 14 files changed, 480 insertions(+), 23 deletions(-) create mode 100644 cmd/mage/main.go create mode 100755 mage create mode 100644 magefiles/magefile.go create mode 100644 magefiles/types.go create mode 100644 magefiles/utils.go create mode 100755 scripts/install-appstudio.sh create mode 100755 scripts/run-appstudio-healthchecks.sh diff --git a/.ci/openshift-ci/Dockerfile b/.ci/openshift-ci/Dockerfile index 523d2ddf1..9a7e16ec6 100644 --- a/.ci/openshift-ci/Dockerfile +++ b/.ci/openshift-ci/Dockerfile @@ -2,7 +2,8 @@ FROM registry.ci.openshift.org/openshift/release:golang-1.17 SHELL ["/bin/bash", "-c"] -# Install yq, kubectl, and oc -RUN curl -LO https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && \ - chmod +x ./kubectl && \ - mv ./kubectl /usr/local/bin +ENV YQ_VERSION=v4.25.2 + +# Install yq and kubectl +RUN curl -Lso /usr/local/bin/yq https://github.com/mikefarah/yq/releases/download/${YQ_VERSION}/yq_linux_amd64 && chmod +x /usr/local/bin/yq +RUN curl -Lso /usr/local/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/$(curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt)/bin/linux/amd64/kubectl && chmod +x /usr/local/bin/kubectl \ No newline at end of file diff --git a/.gitignore b/.gitignore index f7a18890b..8feee74f6 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ tmp/ .vscode/configurationCache.log .vscode/dryrun.log .vscode/targets.log +.cache/ diff --git a/Makefile b/Makefile index fc5cdf1da..e89de86d1 100644 --- a/Makefile +++ b/Makefile @@ -14,3 +14,15 @@ push-container: run: $(E2E_BIN) $(E2E_ARGS_EXEC) + +ci/test/e2e: + ./mage -v ci:teste2e + +ci/prepare/e2e-branch: + ./mage -v ci:prepareE2Ebranch + +local/cluster/prepare: + ./mage -v local:prepareCluster + +local/test/e2e: + ./mage -v local:teste2e \ No newline at end of file diff --git a/cmd/mage/main.go b/cmd/mage/main.go new file mode 100644 index 000000000..1b47cd0c4 --- /dev/null +++ b/cmd/mage/main.go @@ -0,0 +1,9 @@ +package main + +import ( + "os" + + "github.com/magefile/mage/mage" +) + +func main() { os.Exit(mage.Main()) } diff --git a/docs/Installation.md b/docs/Installation.md index 3fcda747c..a3c247663 100644 --- a/docs/Installation.md +++ b/docs/Installation.md @@ -32,26 +32,17 @@ Before starting the deployment steps of appstudio in e2e mode in Openshift CI yo 3. Install Red Hat App Studio in e2e mode. The e2e framework by default will use the `redhat-appstudio-qe` github organization by default. If you want to change the github org you should define `GITHUB_E2E_ORGANIZATION` environment with your custom github organization ```bash - # In Openshift CI there are some example about how to use the installation script. See infra-deployments script https://github.com/redhat-appstudio/application-service/blob/main/.ci/oci-e2e-has.sh#L59 - $ROOT_DIR/scripts/install-appstudio-e2e-mode.sh install + make local/cluster/prepare ``` -4. Compile the e2e tests +4. Run the e2e tests ```bash - make build - ``` - -5. Run the e2e tests - - ```bash - `$ROOT_DIR/bin/e2e-appstudio` + make local/test/e2e ``` Where are: -- `install` - Flag to indicate the installation. If the flag will not be present you can `source` the script and use the bash functions. - The following environments are used to launch the Red Hat AppStudio installation in e2e mode and the tests execution: | Variable | Required | Explanation | Default Value | @@ -88,8 +79,4 @@ potentially could exists in the developer's fork of the e2e repository For example, if a developer with GH account `cooljohn` opens a PR (for application-service repo) from a branch `new-feature`, then the logic checks if there is a branch `new-feature` also in the `cooljohn/e2e-tests` fork and if exists will start to install the e2e framework from those branch -To install App Studio E2E framework in openshift-ci and use the pairing feature it is necessary to perform: - -```bash - $ROOT_DIR/scripts/e2e-openshift-ci.sh -``` +Pairing PRs is handled automatically by running `make ci/test/e2e` \ No newline at end of file diff --git a/go.mod b/go.mod index b760d8110..7ccbe3b1b 100644 --- a/go.mod +++ b/go.mod @@ -12,6 +12,7 @@ require ( github.com/gosuri/uiprogress v0.0.1 github.com/gosuri/uitable v0.0.4 github.com/hacbs-contract/enterprise-contract-controller v0.0.0-20220608144538-7d47a3f5da49 + github.com/magefile/mage v1.13.0 github.com/onsi/ginkgo/v2 v2.1.4 github.com/onsi/gomega v1.19.0 github.com/openshift/api v0.0.0-20220525145417-ee5b62754c68 diff --git a/go.sum b/go.sum index a48e5fbaa..f74b1ceed 100644 --- a/go.sum +++ b/go.sum @@ -915,6 +915,7 @@ github.com/go-redis/redis v6.15.8+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8w github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/go-test/deep v1.0.1/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= @@ -1147,6 +1148,7 @@ github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1 h1:K6RDEckDVWvDI9JAJYCmNdQXq6neHJOYx3V6jnqNEec= github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= @@ -1583,6 +1585,8 @@ github.com/lunixbochs/vtclean v0.0.0-20180621232353-2d01aacdc34a/go.mod h1:pHhQN github.com/lyft/protoc-gen-star v0.5.3/go.mod h1:V0xaHgaf5oCCqmcxYcWiDfTiKsZsRc87/1qhoTACD8w= github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ= github.com/machinebox/graphql v0.2.2/go.mod h1:F+kbVMHuwrQ5tYgU9JXlnskM8nOaFxCAEolaQybkjWA= +github.com/magefile/mage v1.13.0 h1:XtLJl8bcCM7EFoO8FyH8XK3t7G5hQAeK+i4tq+veT9M= +github.com/magefile/mage v1.13.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.4/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= diff --git a/mage b/mage new file mode 100755 index 000000000..4cc8a6b8b --- /dev/null +++ b/mage @@ -0,0 +1,11 @@ +#!/usr/bin/env bash +set -euo pipefail + +export MAGEFILE_CACHE=$PWD/.cache/magefile +export GOFLAGS="" + +if [ ! -f "bin/mage" ]; then + go build -o bin/mage ./cmd/mage +fi + +exec ./bin/mage "$@" \ No newline at end of file diff --git a/magefiles/magefile.go b/magefiles/magefile.go new file mode 100644 index 000000000..05d995088 --- /dev/null +++ b/magefiles/magefile.go @@ -0,0 +1,230 @@ +package main + +import ( + "encoding/json" + "fmt" + "os" + "strings" + + "github.com/magefile/mage/sh" + "github.com/redhat-appstudio/e2e-tests/pkg/utils" + "k8s.io/klog/v2" +) + +var ( + requiredBinaries = []string{"jq", "kubectl", "oc", "yq", "jq", "git"} + artifactDir = utils.GetEnv("ARTIFACT_DIR", ".") + openshiftJobSpec = &OpenshiftJobSpec{} + pr = &PullRequestMetadata{} +) + +func (CI) parseJobSpec() error { + jobSpecEnvVarData := os.Getenv("JOB_SPEC") + + if err := json.Unmarshal([]byte(jobSpecEnvVarData), openshiftJobSpec); err != nil { + return fmt.Errorf("error when parsing openshift job spec data: %v", err) + } + return nil +} + +func (ci CI) init() error { + var err error + + if err = ci.parseJobSpec(); err != nil { + return err + } + + pr.Author = openshiftJobSpec.Refs.Pulls[0].Author + pr.Organization = openshiftJobSpec.Refs.Organization + pr.RepoName = openshiftJobSpec.Refs.Repo + pr.CommitSHA = openshiftJobSpec.Refs.Pulls[0].SHA + pr.Number = openshiftJobSpec.Refs.Pulls[0].Number + + prUrl := fmt.Sprintf("https://api.github.com/repos/%s/%s/pulls/%d", pr.Organization, pr.RepoName, pr.Number) + pr.RemoteName, pr.BranchName, err = getRemoteAndBranchNameFromPRLink(prUrl) + if err != nil { + return err + } + + return nil +} + +func (ci CI) PrepareE2EBranch() error { + + if err := ci.init(); err != nil { + return err + } + + if openshiftJobSpec.Refs.Repo == "e2e-tests" { + gitCheckoutRemoteBranch(pr.Author, pr.CommitSHA) + } else { + if ci.isPRPairingRequired() { + gitCheckoutRemoteBranch(pr.Author, pr.BranchName) + } + } + + return nil +} + +func (Local) PrepareCluster() error { + if err := PreflightChecks(); err != nil { + return fmt.Errorf("error when running preflight checks: %v", err) + } + if err := BootstrapCluster(); err != nil { + return fmt.Errorf("error when bootstrapping cluster: %v", err) + } + + if err := ConfigureSPI(); err != nil { + return fmt.Errorf("error when configuring SPI: %v", err) + } + + if err := RunAppstudioHealthChecks(); err != nil { + return fmt.Errorf("error when running appstudio healthchecks: %v", err) + } + return nil +} + +func (Local) TestE2E() error { + return RunE2ETests() +} + +func (ci CI) TestE2E() error { + + if err := ci.init(); err != nil { + return err + } + + if err := PreflightChecks(); err != nil { + return fmt.Errorf("error when running preflight checks: %v", err) + } + + if err := ci.setRequiredEnvVars(); err != nil { + return fmt.Errorf("error when setting up required env vars: %v", err) + } + + if err := ci.createOpenshiftUser(); err != nil { + return fmt.Errorf("error when creating openshift user: %v", err) + } + + if err := BootstrapCluster(); err != nil { + return fmt.Errorf("error when bootstrapping cluster: %v", err) + } + + if err := ConfigureSPI(); err != nil { + return fmt.Errorf("error when configuring SPI: %v", err) + } + + if err := RunAppstudioHealthChecks(); err != nil { + return fmt.Errorf("error when running appstudio healthchecks: %v", err) + } + + if err := RunE2ETests(); err != nil { + return fmt.Errorf("error when running e2e tests: %v", err) + } + + return nil +} + +func RunE2ETests() error { + cwd, _ := os.Getwd() + + // TODO add "-p" flag to run tests in parallel once our tests are prepared for it + return sh.RunV("ginkgo", fmt.Sprintf("--output-dir=%s", artifactDir), "--junit-report=e2e-report.xml", "--v", "--progress", "--focus=$E2E_TEST_SUITE", "./cmd", "--", fmt.Sprintf("--config-suites=%s/tests/e2e-demos/config/default.yaml", cwd)) +} + +func PreflightChecks() error { + if os.Getenv("GITHUB_TOKEN") == "" || os.Getenv("QUAY_TOKEN") == "" { + return fmt.Errorf("required env vars containing secrets (QUAY_TOKEN, GITHUB_TOKEN) not defined or empty") + } + + for _, binaryName := range requiredBinaries { + if err := sh.Run("which", binaryName); err != nil { + return fmt.Errorf("binary %s not found in PATH - please install it first", binaryName) + } + } + + if err := sh.RunV("go", "install", "-mod=mod", "github.com/onsi/ginkgo/v2/ginkgo"); err != nil { + return err + } + + return nil +} + +func (CI) setRequiredEnvVars() error { + + if openshiftJobSpec.Refs.Repo != "e2e-tests" { + + if strings.Contains(openshiftJobSpec.Refs.Repo, "-service") { + var envVarPrefix, imageTagSuffix, testSuiteName string + sp := strings.Split(os.Getenv("COMPONENT_IMAGE"), "@") + + switch openshiftJobSpec.Refs.Repo { + case "application-service": + envVarPrefix = "HAS" + imageTagSuffix = "has-image" + testSuiteName = "has-suite" + case "build-service": + envVarPrefix = "BUILD_SERVICE" + imageTagSuffix = "build-service-image" + testSuiteName = "build-service-suite" + case "jvm-build-service": + envVarPrefix = "JVM_BUILD_SERVICE" + imageTagSuffix = "jvm-build-service-image" + testSuiteName = "jvm-build-service-suite" + } + + os.Setenv(fmt.Sprintf("%s_IMAGE_REPO", envVarPrefix), sp[0]) + os.Setenv(fmt.Sprintf("%s_IMAGE_TAG", envVarPrefix), fmt.Sprintf("redhat-appstudio-%s", imageTagSuffix)) + os.Setenv(fmt.Sprintf("%s_PR_OWNER", envVarPrefix), openshiftJobSpec.Refs.Pulls[0].Author) + os.Setenv(fmt.Sprintf("%s_PR_SHA", envVarPrefix), openshiftJobSpec.Refs.Pulls[0].SHA) + os.Setenv("E2E_TEST_SUITE", testSuiteName) + + } else if openshiftJobSpec.Refs.Repo == "infra-deployments" { + + os.Setenv("INFRA_DEPLOYMENTS_ORG", pr.Organization) + os.Setenv("INFRA_DEPLOYMENTS_BRANCH", pr.BranchName) + } + + } + + return nil +} + +func (CI) createOpenshiftUser() error { + tempKubeconfigPath := "/tmp/kubeconfig" + os.Setenv("KUBECONFIG_TEST", tempKubeconfigPath) + if err := sh.Run("./scripts/provision-openshift-user.sh"); err != nil { + return err + } + os.Setenv("KUBECONFIG", tempKubeconfigPath) + + return nil +} + +func BootstrapCluster() error { + return sh.Run("./scripts/install-appstudio-e2e-mode.sh") +} + +func ConfigureSPI() error { + return sh.Run("./scripts/spi-e2e-setup.sh") +} + +func RunAppstudioHealthChecks() error { + return sh.Run("./scripts/run-appstudio-healthchecks.sh") +} + +func (CI) isPRPairingRequired() bool { + ghBranches := &GithubBranches{} + if err := sendHttpRequestAndParseResponse(fmt.Sprintf("https://api.github.com/repos/%s/e2e-tests/branches", pr.Author), "GET", ghBranches); err != nil { + klog.Infof("cannot determine e2e-tests Github branches for author %s: %v. will stick with the redhat-appstudio/e2e-tests main branch for running testss", pr.Author, err) + return false + } + + for _, b := range ghBranches.Branches { + if b.Name == pr.BranchName { + return true + } + } + + return false +} diff --git a/magefiles/types.go b/magefiles/types.go new file mode 100644 index 000000000..346c46699 --- /dev/null +++ b/magefiles/types.go @@ -0,0 +1,49 @@ +package main + +import "github.com/magefile/mage/mg" + +type Local mg.Namespace +type CI mg.Namespace + +type OpenshiftJobSpec struct { + Refs Refs `json:"refs"` +} +type Refs struct { + Repo string `json:"repo"` + Organization string `json:"org"` + Pulls []Pull `json:"pulls"` +} + +type Pull struct { + Number int `json:"number"` + Author string `json:"author"` + SHA string `json:"sha"` + PRLink string `json:"link"` + AuthorLink string `json:"author_link"` +} + +type GithubPRInfo struct { + Head Head `json:"head"` +} + +type Head struct { + Label string `json:"label"` +} + +type GithubBranches struct { + Branches []Branch +} + +type Branch struct { + Name string `json:"name"` +} + +type PullRequestMetadata struct { + Author string + Organization string + RepoName string + BranchName string + CommitSHA string + Number int + RemoteName string +} diff --git a/magefiles/utils.go b/magefiles/utils.go new file mode 100644 index 000000000..976de4ef6 --- /dev/null +++ b/magefiles/utils.go @@ -0,0 +1,51 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "os" + "strings" + + "github.com/magefile/mage/sh" +) + +func getRemoteAndBranchNameFromPRLink(url string) (remote, branchName string, err error) { + ghRes := &GithubPRInfo{} + sendHttpRequestAndParseResponse(url, "GET", ghRes) + + split := strings.Split(ghRes.Head.Label, ":") + remote, branchName = split[0], split[1] + + return remote, branchName, nil +} + +func gitCheckoutRemoteBranch(remoteName, branchName string) { + sh.Run("git", "remote", "add", remoteName, fmt.Sprintf("https://github.com/%s/e2e-tests.git", remoteName)) + sh.Run("git", "fetch", remoteName) + sh.Run("git", "checkout", branchName) +} + +func sendHttpRequestAndParseResponse(url, method string, v interface{}) error { + req, err := http.NewRequestWithContext(context.Background(), method, url, nil) + if err != nil { + return err + } + req.Header.Set("Authorization", fmt.Sprintf("token %s", os.Getenv("GITHUB_TOKEN"))) + res, err := http.DefaultClient.Do(req) + if err != nil { + return err + } + defer res.Body.Close() + body, err := io.ReadAll(res.Body) + if err != nil { + return err + } + if err := json.Unmarshal(body, v); err != nil { + return err + } + + return nil +} diff --git a/scripts/install-appstudio.sh b/scripts/install-appstudio.sh new file mode 100755 index 000000000..852dbc756 --- /dev/null +++ b/scripts/install-appstudio.sh @@ -0,0 +1,47 @@ +#!/bin/bash +# +# Download gitops repository to install AppStudio in e2e mode. +# +# exit immediately when a command fails +set -e +# only exit with zero if all commands of the pipeline exit successfully +set -o pipefail +# error on unset variables +set -u + +# Mandatory env vars defined in local environment/CI +export MY_GITHUB_TOKEN="${GITHUB_TOKEN}" + +# Optionally provided env vars +export MY_GITHUB_ORG=${GITHUB_E2E_ORGANIZATION:-"redhat-appstudio-qe"} +export MY_GIT_FORK_REMOTE="qe" +export E2E_APPLICATIONS_NAMESPACE=${E2E_APPLICATIONS_NAMESPACE:-appstudio-e2e-test} +export SHARED_SECRET_NAMESPACE="build-templates" +export TMP_DIR TEST_BRANCH_ID ROOT_E2E +TMP_DIR=$(mktemp -d) +TEST_BRANCH_ID=$(date +%s) +# Environment variable used to override the default "protected" image repository in HAS +# https://github.com/redhat-appstudio/application-service/blob/6b9d21b8f835263b2e92f1e9343a1453caa2e561/gitops/generate_build.go#L50 +# Users are allowed to push images to this repo only in case the image contains a tag that consists of "-" +# For example: "quay.io/redhat-appstudio-qe/test-images-protected:appstudio-e2e-test-mytag123" +export HAS_DEFAULT_IMAGE_REPOSITORY="quay.io/${QUAY_E2E_ORGANIZATION:-redhat-appstudio-qe}/test-images-protected" + + +pushd "${TMP_DIR}" + +INFRA_DEPLOYMENTS_ORG="${INFRA_DEPLOYMENTS_ORG:-"redhat-appstudio"}" +INFRA_DEPLOYMENTS_BRANCH="${INFRA_DEPLOYMENTS_BRANCH:-"main"}" +git clone --no-checkout "https://${MY_GITHUB_TOKEN}@github.com/${INFRA_DEPLOYMENTS_ORG}/infra-deployments.git" . +git checkout "${INFRA_DEPLOYMENTS_BRANCH}" +# Add a custom remote for infra-deployments repository. +git remote add "${MY_GIT_FORK_REMOTE}" https://github.com/"${MY_GITHUB_ORG}"/infra-deployments.git +# Run the bootstrap script +./hack/bootstrap-cluster.sh preview +# Secret used by pipelines to push component containers to quay.io +QUAY_TOKEN=${QUAY_TOKEN:-} +echo -e "[INFO] Creating application-service related secret in $SHARED_SECRET_NAMESPACE namespace" +echo "$QUAY_TOKEN" | base64 --decode > docker.config +kubectl create secret docker-registry redhat-appstudio-user-workload -n $SHARED_SECRET_NAMESPACE --from-file=.dockerconfigjson=docker.config || true +rm docker.config + +popd \ No newline at end of file diff --git a/scripts/provision-openshift-user.sh b/scripts/provision-openshift-user.sh index a617e1ee3..5b34513cf 100755 --- a/scripts/provision-openshift-user.sh +++ b/scripts/provision-openshift-user.sh @@ -38,9 +38,9 @@ oc adm policy add-cluster-role-to-user cluster-admin appstudioci function waitForNewOCPLogin() { while ! oc login --kubeconfig="${KUBECONFIG_TEST}" --server $API_SERVER --username="${TMP_CI_USER}" --password=${TMP_CI_USER} --insecure-skip-tls-verify; do - sleep 10 + sleep 20 done } export -f waitForNewOCPLogin -timeout --foreground 6m bash -c waitForNewOCPLogin +timeout --foreground 10m bash -c waitForNewOCPLogin diff --git a/scripts/run-appstudio-healthchecks.sh b/scripts/run-appstudio-healthchecks.sh new file mode 100755 index 000000000..cdeca324f --- /dev/null +++ b/scripts/run-appstudio-healthchecks.sh @@ -0,0 +1,54 @@ +#!/bin/bash + +# exit immediately when a command fails +set -e +# only exit with zero if all commands of the pipeline exit successfully +set -o pipefail +# error on unset variables +set -u + +export GITOPS_NAMESPACE="openshift-gitops" +export GITOPS_ALL_APPS_CR_NAME="all-components-staging" + +function waitHASApplicationToBeReady() { + while [ "$(kubectl get applications.argoproj.io has -n ${GITOPS_NAMESPACE} -o jsonpath='{.status.health.status}')" != "Healthy" ]; do + sleep 30 + echo "[INFO] Waiting for HAS to be ready." + done +} + +function waitAppStudioToBeReady() { + while [ "$(kubectl get applications.argoproj.io ${GITOPS_ALL_APPS_CR_NAME} -n ${GITOPS_NAMESPACE} -o jsonpath='{.status.health.status}')" != "Healthy" ] || + [ "$(kubectl get applications.argoproj.io ${GITOPS_ALL_APPS_CR_NAME} -n ${GITOPS_NAMESPACE} -o jsonpath='{.status.sync.status}')" != "Synced" ]; do + sleep 30 + echo "[INFO] Waiting for AppStudio to be ready." + done +} + +function waitBuildToBeReady() { + while [ "$(kubectl get applications.argoproj.io build -n ${GITOPS_NAMESPACE} -o jsonpath='{.status.health.status}')" != "Healthy" ] || + [ "$(kubectl get applications.argoproj.io build -n ${GITOPS_NAMESPACE} -o jsonpath='{.status.sync.status}')" != "Synced" ]; do + sleep 30 + echo "[INFO] Waiting for Build to be ready." + done +} + +function waitSPIToBeReady() { + while [ "$(kubectl get applications.argoproj.io spi -n ${GITOPS_NAMESPACE} -o jsonpath='{.status.health.status}')" != "Healthy" ] || + [ "$(kubectl get applications.argoproj.io spi -n ${GITOPS_NAMESPACE} -o jsonpath='{.status.sync.status}')" != "Synced" ]; do + echo "[INFO] Waiting for spi to be ready." + sleep 30 + done +} + + +export -f waitAppStudioToBeReady +export -f waitBuildToBeReady +export -f waitHASApplicationToBeReady +export -f waitSPIToBeReady + +# Install AppStudio Controllers and wait for HAS and other AppStudio application to be running. +timeout --foreground 10m bash -c waitAppStudioToBeReady +timeout --foreground 10m bash -c waitBuildToBeReady +timeout --foreground 10m bash -c waitHASApplicationToBeReady +timeout --foreground 10m bash -c waitSPIToBeReady