From 5b0e931a7e9887639e835a993d239c17d8a1947e Mon Sep 17 00:00:00 2001 From: Adarshdeep Cheema Date: Thu, 16 Dec 2021 12:31:21 -0500 Subject: [PATCH] Containerization work for sample-node-api Signed-off-by: Adarshdeep Cheema --- .github/workflows/build_test.yml | 1 + .github/workflows/sample-node-api-images.yml | 156 ++++++++++++++++++- container/.gitignore | 4 + container/Dockerfile | 43 +++++ container/README.md | 32 ++++ container/prepare.sh | 121 ++++++++++++++ container/sample-node-api.yml | 135 ++++++++++++++++ 7 files changed, 488 insertions(+), 4 deletions(-) create mode 100644 container/.gitignore create mode 100644 container/Dockerfile create mode 100644 container/README.md create mode 100644 container/prepare.sh create mode 100644 container/sample-node-api.yml diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml index 0b6dbcc..009cada 100644 --- a/.github/workflows/build_test.yml +++ b/.github/workflows/build_test.yml @@ -11,6 +11,7 @@ on: description: '[Release] perform release' required: false default: 'false' + type: boolean jobs: diff --git a/.github/workflows/sample-node-api-images.yml b/.github/workflows/sample-node-api-images.yml index eff8a78..9b1ee4c 100644 --- a/.github/workflows/sample-node-api-images.yml +++ b/.github/workflows/sample-node-api-images.yml @@ -5,15 +5,163 @@ on: workflow_dispatch: inputs: release: - description: 'Set to "true" if we want to release the images' + description: 'release the images?' required: false default: 'false' + type: boolean env: IMAGE_BASE_DIR: container jobs: - dummy: + + build-ubuntu-amd64: runs-on: ubuntu-latest steps: - - id: dummy - run: echo "NO OPS" \ No newline at end of file + - uses: actions/checkout@v2 + + - uses: zowe-actions/shared-actions/prepare-workflow@main + + - uses: zowe-actions/shared-actions/docker-prepare@main + with: + registry-user: ${{ secrets.ARTIFACTORY_X_USERNAME }} + registry-password: ${{ secrets.ARTIFACTORY_X_PASSWORD }} + release: ${{ github.event.inputs.release }} + base-directory: ${{ env.IMAGE_BASE_DIR }} + image-name: sample-node-api + linux-distro: ubuntu + cpu-arch: amd64 + + - uses: zowe-actions/shared-actions/docker-build-local@main + with: + build-arg-list: ZOWE_BASE_IMAGE=latest-ubuntu + timeout-minutes: 5 + + build-ubuntu-s390x: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - uses: zowe-actions/shared-actions/prepare-workflow@main + + - uses: zowe-actions/shared-actions/docker-prepare@main + with: + registry-user: ${{ secrets.ARTIFACTORY_X_USERNAME }} + registry-password: ${{ secrets.ARTIFACTORY_X_PASSWORD }} + release: ${{ github.event.inputs.release }} + base-directory: ${{ env.IMAGE_BASE_DIR }} + image-name: sample-node-api + linux-distro: ubuntu + cpu-arch: s390x + + - uses: zowe-actions/shared-actions/docker-build-zlinux@main + with: + zlinux-host: ${{ secrets.ZLINUX_HOST }} + zlinux-ssh-user: ${{ secrets.ZLINUX_SSH_USER }} + zlinux-ssh-key: ${{ secrets.ZLINUX_SSH_KEY }} + zlinux-ssh-passphrase: ${{ secrets.ZLINUX_SSH_PASSPHRASE }} + build-arg-list: ZOWE_BASE_IMAGE=latest-ubuntu + timeout-minutes: 10 + + define-ubuntu-manifest: + needs: + - build-ubuntu-amd64 + - build-ubuntu-s390x + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - uses: zowe-actions/shared-actions/prepare-workflow@main + + - uses: zowe-actions/shared-actions/docker-prepare@main + with: + registry-user: ${{ secrets.ARTIFACTORY_X_USERNAME }} + registry-password: ${{ secrets.ARTIFACTORY_X_PASSWORD }} + release: ${{ github.event.inputs.release }} + base-directory: ${{ env.IMAGE_BASE_DIR }} + image-name: sample-node-api + linux-distro: ubuntu + + - uses: zowe-actions/shared-actions/docker-manifest@main + with: + linux-distro: ubuntu + cpu-arch-list: "amd64 s390x" + timeout-minutes: 2 + + build-ubi-amd64: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - uses: zowe-actions/shared-actions/prepare-workflow@main + + - uses: zowe-actions/shared-actions/docker-prepare@main + with: + registry-user: ${{ secrets.ARTIFACTORY_X_USERNAME }} + registry-password: ${{ secrets.ARTIFACTORY_X_PASSWORD }} + release: ${{ github.event.inputs.release }} + base-directory: ${{ env.IMAGE_BASE_DIR }} + image-name: sample-node-api + linux-distro: ubi + cpu-arch: amd64 + redhat-registry: ${{ env.DEFAULT_REDHAT_DOCKER_REGISTRY }} + redhat-registry-user: ${{ secrets.REDHAT_DEVELOPER_USER }} + redhat-registry-password: ${{ secrets.REDHAT_DEVELOPER_PASSWORD }} + + - uses: zowe-actions/shared-actions/docker-build-local@main + with: + build-arg-list: ZOWE_BASE_IMAGE=latest-ubi + timeout-minutes: 5 + + build-ubi-s390x: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - uses: zowe-actions/shared-actions/prepare-workflow@main + + - uses: zowe-actions/shared-actions/docker-prepare@main + with: + registry-user: ${{ secrets.ARTIFACTORY_X_USERNAME }} + registry-password: ${{ secrets.ARTIFACTORY_X_PASSWORD }} + release: ${{ github.event.inputs.release }} + base-directory: ${{ env.IMAGE_BASE_DIR }} + image-name: sample-node-api + linux-distro: ubi + cpu-arch: s390x + + - uses: zowe-actions/shared-actions/docker-build-zlinux@main + with: + zlinux-host: ${{ secrets.ZLINUX_HOST }} + zlinux-ssh-user: ${{ secrets.ZLINUX_SSH_USER }} + zlinux-ssh-key: ${{ secrets.ZLINUX_SSH_KEY }} + zlinux-ssh-passphrase: ${{ secrets.ZLINUX_SSH_PASSPHRASE }} + redhat-registry: ${{ env.DEFAULT_REDHAT_DOCKER_REGISTRY }} + redhat-registry-user: ${{ secrets.REDHAT_DEVELOPER_USER }} + redhat-registry-password: ${{ secrets.REDHAT_DEVELOPER_PASSWORD }} + build-arg-list: ZOWE_BASE_IMAGE=latest-ubi + timeout-minutes: 10 + + define-ubi-manifest: + needs: + - build-ubi-amd64 + - build-ubi-s390x + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + + - uses: zowe-actions/shared-actions/prepare-workflow@main + + - uses: zowe-actions/shared-actions/docker-prepare@main + with: + registry-user: ${{ secrets.ARTIFACTORY_X_USERNAME }} + registry-password: ${{ secrets.ARTIFACTORY_X_PASSWORD }} + release: ${{ github.event.inputs.release }} + base-directory: ${{ env.IMAGE_BASE_DIR }} + image-name: sample-node-api + linux-distro: ubi + + - uses: zowe-actions/shared-actions/docker-manifest@main + with: + linux-distro: ubi + cpu-arch-list: "amd64 s390x" + timeout-minutes: 2 \ No newline at end of file diff --git a/container/.gitignore b/container/.gitignore new file mode 100644 index 0000000..db8aee6 --- /dev/null +++ b/container/.gitignore @@ -0,0 +1,4 @@ +# temporary context +tmp/ +# temporary context for each Dockerfile +*/*/component/ \ No newline at end of file diff --git a/container/Dockerfile b/container/Dockerfile new file mode 100644 index 0000000..440ed2b --- /dev/null +++ b/container/Dockerfile @@ -0,0 +1,43 @@ +####################################################################### +# This program and the accompanying materials are made available +# under the terms of the Eclipse Public License v2.0 which +# accompanies this distribution, and is available at +# https://www.eclipse.org/legal/epl-v20.html +# +# SPDX-License-Identifier: EPL-2.0 +# +# Copyright Contributors to the Zowe Project. +####################################################################### + +# base image tag +ARG ZOWE_BASE_IMAGE=latest-ubuntu + +FROM zowe-docker-release.jfrog.io/ompzowe/base-node:${ZOWE_BASE_IMAGE} AS builder + +################################## +# labels +LABEL name="sample-node-api" \ + maintainer="kajank@ca.ibm.com" \ + vendor="Zowe" \ + version="0.0.0" \ + release="0" \ + summary="A sample node js api api" \ + description="It is used to demonstrate the steps to extend API/ML with your own rest api." + +################################## +# switch context +USER zowe +WORKDIR /component + +################################## +# copy files +COPY --chown=zowe:zowe component . +COPY --chown=zowe:zowe component/LICENSE /licenses + +################################## +# build component +RUN npm install --only=prod + +# start command +EXPOSE 18000 +ENTRYPOINT [ "bin/start.sh" ] \ No newline at end of file diff --git a/container/README.md b/container/README.md new file mode 100644 index 0000000..ccc4e9b --- /dev/null +++ b/container/README.md @@ -0,0 +1,32 @@ +# Sample-node-api + +## General Information + +This image can be used to start Sample-node-api. + +It includes 2 Linux Distro: + + Ubuntu + Red Hat UBI + +Each image supports both amd64 and s390x CPU architectures. +## Usage + +Image zowe-docker-release.jfrog.io/ompzowe/sample-node-api:latest should be able to run with minimal environment variables: + +- `KEYSTORE_KEY`: You can supply your own certificate private key +- `KEYSTORE_CERTIFICATE`: You can supply your own certificate +- `MY_API_NAME`: You can supply your API NAme (Default is sample-node-api) +- `MY_API_PORT`: You can supply your own API_PORT (Default is 18000) + +Example commands: + +``` +# pull image +docker pull zowe-docker-release.jfrog.io/ompzowe/sample-node-api:latest +# start container +docker run -it --rm -p 8546:8546 \ + -e KEYSTORE_KEY= \ + -e KEYSTORE_CERTIFICATE= \ + zowe-docker-release.jfrog.io/ompzowe/sample-node-api:latest +``` \ No newline at end of file diff --git a/container/prepare.sh b/container/prepare.sh new file mode 100644 index 0000000..2366ccf --- /dev/null +++ b/container/prepare.sh @@ -0,0 +1,121 @@ +#!/bin/bash + +################################################################################ +# This program and the accompanying materials are made available under the terms of the +# Eclipse Public License v2.0 which accompanies this distribution, and is available at +# https://www.eclipse.org/legal/epl-v20.html +# +# SPDX-License-Identifier: EPL-2.0 +# +# Copyright Contributors to the Zowe Project. +################################################################################ + +################################################################################ +# prepare docker build context +# +# This script will be executed with 2 parameters: +# - linux-distro +# - cpu-arch + +################################################################################ +# This script prepares all required files we plan to put into explorer-ip +# image. +# +# Prereqs: +# - must run with Github Actions (with GITHUB_RUN_NUMBER and GITHUB_SHA) +# - must provide $GITHUB_PR_ID is it's pull request +# - jq + +# exit if there are errors +set -e + +############################### +# check parameters +linux_distro=$1 +cpu_arch=$2 +if [ -z "${linux_distro}" ]; then + echo "Error: linux-distro parameter is missing." + exit 1 +fi +if [ -z "${cpu_arch}" ]; then + echo "Error: cpu-arch parameter is missing." + exit 1 +fi + +################################################################################ +# CONSTANTS +BASE_DIR=$(cd $(dirname $0);pwd) +REPO_ROOT_DIR=$(cd $(dirname $0)/../;pwd) +WORK_DIR=tmp +JFROG_REPO_SNAPSHOT=libs-snapshot-local +JFROG_REPO_RELEASE=libs-release-local +JFROG_URL=https://zowe.jfrog.io/zowe/ + +################################ +echo ">>>>> prepare basic files" +cd "${REPO_ROOT_DIR}" +package_version=$(jq -r '.version' package.json) +package_release=$(echo "${package_version}" | awk -F. '{print $1;}') + + +############################### +echo ">>>>> clean up folders" +rm -fr "${BASE_DIR}/${WORK_DIR}" +mkdir -p "${BASE_DIR}/${WORK_DIR}" +rm -fr “${BASE_DIR}/${linux_distro}/${cpu_arch}” + +################################ +# copy Dockerfile +echo ">>>>> copy Dockerfile to ${linux_distro}/${cpu_arch}/Dockerfile" +cd "${BASE_DIR}" +mkdir -p "${linux_distro}/${cpu_arch}" +if [ ! -f Dockerfile ]; then + echo "Error: Dockerfile file is missing." + exit 2 +fi +cat Dockerfile | sed -e "s#version=\"0\.0\.0\"#version=\"${package_version}\"#" -e "s#release=\"0\"#release=\"${package_release}\"#" > "${linux_distro}/${cpu_arch}/Dockerfile" + + +cd "${REPO_ROOT_DIR}" +cp manifest.yaml "${BASE_DIR}/${WORK_DIR}" +cp README.md "${BASE_DIR}/${WORK_DIR}" +cp LICENSE "${BASE_DIR}/${WORK_DIR}" + +# build client +echo "[${SCRIPT_NAME}] building client ..." +npm install +npm run build + +# copy sample-node-api to target folder +# copy start script to target folder - included in dist +echo "[${SCRIPT_NAME}] copying sample node api backend ..." +cp -r dist/. "${BASE_DIR}/${WORK_DIR}" + +############################### +echo ">>>>> prepare manifest.json" +cd "${REPO_ROOT_DIR}" +if [ -n "${GITHUB_PR_ID}" ]; then + GITHUB_BRANCH=PR-${GITHUB_PR_ID} +else + GITHUB_BRANCH=${GITHUB_REF#refs/heads/} +fi + +echo " - branch: ${GITHUB_BRANCH}" +echo " - build number: ${GITHUB_RUN_NUMBER}" +echo " - commit hash: ${GITHUB_SHA}" +# assume to run in Github Actions +cat manifest.yaml | \ + sed -e "s#{{build\.branch}}#${GITHUB_BRANCH}#" \ + -e "s#{{build\.number}}#${GITHUB_RUN_NUMBER}#" \ + -e "s#{{build\.commitHash}}#${GITHUB_SHA}#" \ + -e "s#{{build\.timestamp}}#$(date +%s)#" \ + > "${BASE_DIR}/${WORK_DIR}/manifest.yaml" + +############################### +# copy to target context +echo ">>>>> copy to target build context" +cp -r "${BASE_DIR}/${WORK_DIR}" "${BASE_DIR}/${linux_distro}/${cpu_arch}/component" + +############################### +# done +echo ">>>>> all done" \ No newline at end of file diff --git a/container/sample-node-api.yml b/container/sample-node-api.yml new file mode 100644 index 0000000..7d28d14 --- /dev/null +++ b/container/sample-node-api.yml @@ -0,0 +1,135 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: sample-node-api + namespace: zowe + labels: + app.kubernetes.io/name: zowe + app.kubernetes.io/instance: zowe + # app.kubernetes.io/version: + app.kubernetes.io/component: sample-node-api + # app.kubernetes.io/part-of: + app.kubernetes.io/managed-by: manual +spec: + selector: + matchLabels: + app.kubernetes.io/name: zowe + app.kubernetes.io/instance: zowe + app.kubernetes.io/component: sample-node-api + template: + metadata: + labels: + app.kubernetes.io/name: zowe + app.kubernetes.io/instance: zowe + app.kubernetes.io/component: sample-node-api + spec: + securityContext: + runAsUser: 20000 + runAsGroup: 20000 + fsGroup: 20000 + serviceAccountName: zowe-sa + volumes: + - name: zowe-runtime + emptyDir: {} + - name: zowe-instance + emptyDir: {} + - name: zowe-config + configMap: + name: zowe-config + - name: zowe-keystore + projected: + sources: + - configMap: + name: zowe-certificates-cm + - secret: + name: zowe-certificates-secret + - name: zowe-workspace + persistentVolumeClaim: + claimName: zowe-workspace-pvc + containers: + - name: sample-node-api + image: zowe-docker-snapshot.jfrog.io/ompzowe/sample-node-api:1.0.0-ubuntu-amd64.containerization-6 + imagePullPolicy: Always + resources: + requests: + memory: "64Mi" + cpu: "10m" + limits: + memory: "128Mi" + cpu: "100m" + ports: + - name: sna-port + containerPort: 18000 + protocol: TCP + readinessProbe: + tcpSocket: + port: 18000 + initialDelaySeconds: 30 + # this should give 18 * periodSeconds(default to 10) seconds about 3 minutes to confirm it's ready + failureThreshold: 18 + command: ["/bin/bash", "-c"] + args: + - "/home/zowe/runtime/bin/internal/run-zowe.sh -c /home/zowe/instance" + env: + - name: ZWE_POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + lifecycle: + preStop: + exec: + command: ["/bin/sh", "-c", "/home/zowe/runtime/bin/internal/container-prestop.sh"] + securityContext: + readOnlyRootFilesystem: true + volumeMounts: + - name: zowe-runtime + mountPath: "/home/zowe/runtime" + - name: zowe-instance + mountPath: "/home/zowe/instance" + - name: zowe-config + mountPath: "/home/zowe/instance/instance.env" + subPath: instance.env + readOnly: true + - name: zowe-keystore + mountPath: "/home/zowe/keystore/" + readOnly: true + - name: zowe-workspace + mountPath: "/home/zowe/instance/workspace" + initContainers: + - name: init-zowe + image: zowe-docker-release.jfrog.io/ompzowe/zowe-launch-scripts:latest-ubuntu + imagePullPolicy: Always + resources: + requests: + memory: "64Mi" + cpu: "10m" + limits: + memory: "128Mi" + cpu: "100m" + securityContext: + readOnlyRootFilesystem: true + volumeMounts: + - name: zowe-runtime + mountPath: "/home/zowe/runtime" + - name: zowe-instance + mountPath: "/home/zowe/instance" +--- +apiVersion: policy/v1beta1 +kind: PodDisruptionBudget +metadata: + name: sample-node-api-pdb + namespace: zowe + labels: + app.kubernetes.io/name: zowe + app.kubernetes.io/instance: zowe + # app.kubernetes.io/version: + app.kubernetes.io/component: pdb + app.kubernetes.io/managed-by: manual +spec: + minAvailable: 1 + selector: + matchLabels: + app.kubernetes.io/name: zowe + app.kubernetes.io/instance: zowe + app.kubernetes.io/component: sample-node-api \ No newline at end of file