Commit ec28bc2a authored by Nikos Psaromanolakis's avatar Nikos Psaromanolakis
Browse files

fix: Edit .gitlab-ci.yml to support nightly jobs

parent ad08bfaa
Loading
Loading
Loading
Loading
Loading
+314 −0
Original line number Diff line number Diff line
@@ -8,6 +8,9 @@ stages:
  - update_values
  - package_publish
  - release
  - nightly_deploy
  - nightly_workflows
  - nightly_result

default:
  image: labs.etsi.org:5050/osl/hypo/code/org.etsi.osl.hypo.ops/cicd/integration.tests/docker:20.10.16
@@ -17,6 +20,18 @@ variables:
  HELM_NAMESPACE: "test"
  REMOTE_DEPLOY_DIR: "/home/ubuntu/etsi_installer"
  GIT_DEPTH: 0
  NIGHTLY_IMAGES: |
    labs.etsi.org:5050/osl/hypo/code/org.etsi.osl.hypo.api/fabric/fabric-api-jvm
    labs.etsi.org:5050/osl/hypo/code/org.etsi.osl.hypo.api/peering/peering-api-jvm
    labs.etsi.org:5050/osl/hypo/code/org.etsi.osl.hypo.api/registry/registry-api-jvm
    labs.etsi.org:5050/osl/hypo/code/org.etsi.osl.hypo.api/tmf/tmf-api-jvm
    labs.etsi.org:5050/osl/hypo/code/org.etsi.osl.hypo.clients/oss/oss-client-jvm
    labs.etsi.org:5050/osl/hypo/code/org.etsi.osl.hypo.clients/telemetry/telemetry-api-jvm
    labs.etsi.org:5050/osl/hypo/code/org.etsi.osl.hypo.core/pkg-manager.helm/pkg-manager
    labs.etsi.org:5050/osl/hypo/code/org.etsi.osl.hypo.core/service.monitor/lcm
    labs.etsi.org:5050/osl/hypo/code/org.etsi.osl.hypo.core/sonata/sonata-core-jvm
    labs.etsi.org:5050/osl/hypo/code/org.etsi.osl.hypo.portal/cart/hypo-portal-jvm
    labs.etsi.org:5050/osl/hypo/code/org.etsi.osl.hypo.portal/web/hypo-portal
  
lint:
  stage: lint
@@ -439,3 +454,302 @@ release_job:
    variables:
      - '$CI_COMMIT_MESSAGE =~ /^release:\s/'


nightly_deploy_job:
  stage: nightly_deploy
  image:
    name: labs.etsi.org:5050/osl/hypo/code/org.etsi.osl.hypo.ops/cicd/integration.tests/python-argocd:3.9
    pull_policy: [always, if-not-present]
  before_script:
    - mkdir -p /tmp/bin ~/.ssh
    - chmod 700 ~/.ssh
    - export PATH="/tmp/bin:$PATH"

    # Install SSH client and required utilities
    - |
      if command -v apk >/dev/null 2>&1; then
        apk add --no-cache openssh-client curl tar
      elif command -v apt-get >/dev/null 2>&1; then
        apt-get update
        apt-get install -y --no-install-recommends \
          openssh-client curl tar
        rm -rf /var/lib/apt/lists/*
      else
        echo "Unsupported container base image."
        exit 1
      fi

    # Install age
    - curl -L -o /tmp/age.tar.gz https://github.com/FiloSottile/age/releases/download/v1.2.1/age-v1.2.1-linux-amd64.tar.gz
    - tar -xzf /tmp/age.tar.gz -C /tmp
    - mv /tmp/age/age /tmp/age/age-keygen /tmp/bin/

    # Install sops
    - curl -L -o /tmp/bin/sops https://github.com/getsops/sops/releases/download/v3.10.2/sops-v3.10.2.linux.amd64
    - chmod +x /tmp/bin/sops

    - sops --version
    - age --version

    # Configure the SSH private key
    - chmod 600 "$ETSI_SSH_KEY"

    # SOPS key
    - echo "$SOPS_AGE_KEY_PRIVATE" > ~/.sops-age-key.txt
    - chmod 600 ~/.sops-age-key.txt
    - export SOPS_AGE_KEY_FILE=~/.sops-age-key.txt

    # Add the deployment server host key
    - ssh-keyscan -H "$DEPLOYMENT_SERVER_IP" >> ~/.ssh/known_hosts
    - chmod 644 ~/.ssh/known_hosts

    # Verify SSH connection
    - |
      ssh \
        -i "$ETSI_SSH_KEY" \
        -o IdentitiesOnly=yes \
        -o BatchMode=yes \
        -o ConnectTimeout=10 \
        "$DEPLOYMENT_SERVER_USER@$DEPLOYMENT_SERVER_IP" \
        'echo "SSH connection successful on $(hostname)"'

  script:

    # Decrypt the installer values directly inside the chart
    - |
      set -eu

      sops --decrypt \
        --input-type yaml \
        --output-type yaml \
        --output charts/hypo/values-nightly.yaml \
        "$HELM_NIGHTLY_VALUES_FILE"

      chmod 600 charts/hypo/values-nightly.yaml

      # Remove and recreate the temporary remote directory
    - |
      ssh \
        -i "$ETSI_SSH_KEY" \
        -o IdentitiesOnly=yes \
        "$DEPLOYMENT_SERVER_USER@$DEPLOYMENT_SERVER_IP" "
          rm -rf '$REMOTE_DEPLOY_DIR'
          mkdir -p '$REMOTE_DEPLOY_DIR'
        "
    - |
      scp \
        -i "$ETSI_SSH_KEY" \
        -o IdentitiesOnly=yes \
        -r \
        charts/hypo/. \
        "$DEPLOYMENT_SERVER_USER@$DEPLOYMENT_SERVER_IP:$REMOTE_DEPLOY_DIR/"

    # Build dependencies and deploy
    - |
      ssh \
        -i "$ETSI_SSH_KEY" \
        -o IdentitiesOnly=yes \
        "$DEPLOYMENT_SERVER_USER@$DEPLOYMENT_SERVER_IP" "

          set -e
          
          cd '$REMOTE_DEPLOY_DIR'

          helm dependency build .
  
          helm upgrade --install nightly . \
            --namespace nightly \
            --create-namespace \
            --values values-nightly.yaml \
            --wait \
            --timeout 10m

          echo 'Helm deployment completed successfully.'
        "
  rules:
    - if: '$CI_PIPELINE_SOURCE == "schedule"'
      when: on_success
    - when: never

nightly_workflows_job:
  stage: nightly_workflows
  image: labs.etsi.org:5050/osl/hypo/code/org.etsi.osl.hypo.ops/cicd/integration.tests/maven:3.9-eclipse-temurin-17
  before_script:
    # clone the integration tests repo
    - git clone --depth 1 --branch develop "https://oauth2:$GROUP_ACCESS_TOKEN@$INTEGRATION_REPO"
    - cd integration.tests
  script:
    - mvn -B -q test "-Dkarate.env=$KARATE_ENV_INSTALLER" "-Dkarate.options=--tags @smoke-e2e-workflow-private"
  needs:
    - job: nightly_deploy_job
      artifacts: false
  rules:
    - if: '$CI_PIPELINE_SOURCE == "schedule"'
      when: on_success
    - when: never



nightly_promote_images_job:
  stage: nightly_result
  tags:
    - hypo
  image:
    name: labs.etsi.org:5050/osl/hypo/code/org.etsi.osl.hypo.ops/cicd/integration.tests/docker:29.1.3
  needs:
    - job: nightly_workflows_job
      artifacts: false
  before_script:
    - docker info >/dev/null
    - |
      echo -n "$CI_REGISTRY_PASSWORD" |
        docker login \
          --username "$CI_REGISTRY_USER" \
          --password-stdin \
          "$CI_REGISTRY"
  script:
    - |
      set -eu

      DATE_TAG="nightly-$(date +%Y-%m-%d)"

      for IMAGE in $NIGHTLY_IMAGES; do
        DEV_IMAGE="${IMAGE}:dev-latest"
        LATEST_IMAGE="${IMAGE}:latest"
        DATED_IMAGE="${IMAGE}:${DATE_TAG}"

        docker pull "$DEV_IMAGE"

        docker tag "$DEV_IMAGE" "$LATEST_IMAGE"
        docker tag "$DEV_IMAGE" "$DATED_IMAGE"

        docker push "$LATEST_IMAGE"
        docker push "$DATED_IMAGE"

        docker image rm -f "$DEV_IMAGE" "$LATEST_IMAGE" "$DATED_IMAGE" >/dev/null 2>&1 || true
      done
  rules:
    - if: '$CI_PIPELINE_SOURCE == "schedule"'
      when: on_success
    - when: never


nightly_compare_failed_images_job:
  stage: nightly_result
  tags:
    - hypo
  image:
    name: labs.etsi.org:5050/osl/hypo/code/org.etsi.osl.hypo.ops/cicd/integration.tests/docker:29.1.3
  needs:
    - job: nightly_workflows_job
      artifacts: false
      optional: true
  before_script:
    - docker info >/dev/null
    - |
      echo -n "$CI_REGISTRY_PASSWORD" |
        docker login \
          --username "$CI_REGISTRY_USER" \
          --password-stdin \
          "$CI_REGISTRY"

  script:
    - |
      set -eu

      REPORT_FILE="different_images.txt"
      FAILED_DATE_TAG="failed-nightly-$(date +%Y-%m-%d)"

      : > "$REPORT_FILE"

      echo "Nightly workflows failed."
      echo "Comparing dev-latest images with latest..."
      echo

      for IMAGE in $NIGHTLY_IMAGES; do
        DEV_IMAGE="${IMAGE}:dev-latest"
        LATEST_IMAGE="${IMAGE}:latest"
        FAILED_IMAGE="${IMAGE}:${FAILED_DATE_TAG}"

        echo "=============================================="
        echo "Checking: $IMAGE"

        if ! docker pull "$DEV_IMAGE"; then
          echo "$IMAGE - dev-latest could not be pulled" \
            >> "$REPORT_FILE"

          echo "Skipping rollback because dev-latest is unavailable."
          continue
        fi

        if ! docker pull "$LATEST_IMAGE"; then
          echo "$IMAGE - latest could not be pulled" \
            >> "$REPORT_FILE"

          echo "Skipping rollback because latest is unavailable."

          docker image rm -f "$DEV_IMAGE" \
            >/dev/null 2>&1 || true

          continue
        fi

        DEV_IMAGE_ID=$(
          docker image inspect \
            --format '{{.Id}}' \
            "$DEV_IMAGE"
        )

        LATEST_IMAGE_ID=$(
          docker image inspect \
            --format '{{.Id}}' \
            "$LATEST_IMAGE"
        )

        if [ "$DEV_IMAGE_ID" != "$LATEST_IMAGE_ID" ]; then
          echo "Result: DIFFERENT"
          echo "$IMAGE" >> "$REPORT_FILE"

          # Preserve the failed dev-latest image
          docker tag "$DEV_IMAGE" "$FAILED_IMAGE"
          docker push "$FAILED_IMAGE"

          # Replace dev-latest with the last successful latest image
          docker tag "$LATEST_IMAGE" "$DEV_IMAGE"
          docker push "$DEV_IMAGE"

          echo "Saved failed image as:"
          echo "  $FAILED_IMAGE"

          echo "Restored dev-latest from:"
          echo "  $LATEST_IMAGE"
        else
          echo "Result: SAME"
        fi

        docker image rm -f \
          "$DEV_IMAGE" \
          "$LATEST_IMAGE" \
          "$FAILED_IMAGE" \
          >/dev/null 2>&1 || true
      done

      echo
      echo "Images requiring investigation:"
      echo "=============================================="

      if [ -s "$REPORT_FILE" ]; then
        cat "$REPORT_FILE"
      else
        echo "No differences were found."
      fi

  artifacts:
    when: always
    expire_in: 30 days
    paths:
      - different_images.txt

  rules:
    - if: '$CI_PIPELINE_SOURCE == "schedule"'
      when: on_failure