diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..e5bb499 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,29 @@ +name: "docker-debug" + +on: push + +jobs: + build-images: + runs-on: ubuntu-latest + env: + DOCKER_REPO: "seemscloud" + steps: + - name: "[Repository] Clone" + uses: actions/checkout@v2 + - name: "[Login] Docker Hub" + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: "[Setup] JDK 17" + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + architecture: x64 + - name: "[Build] Maven Clean Package" + run: | + mvn clean package + git config --global user.email "versioner@seems.cloud" + git config --global user.name "VersionerBot" + mvn clean install \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e673575 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.idea/ +target/ \ No newline at end of file diff --git a/images/debug/Dockerfile b/images/debug/Dockerfile new file mode 100644 index 0000000..28d1ae5 --- /dev/null +++ b/images/debug/Dockerfile @@ -0,0 +1,29 @@ +FROM alpine:latest + +ARG USER_HOME="/tmp/debug" +ARG USER_NAME="debug" +ARG USER_UID="1000" +ARG GROUP_NAME="${USER_NAME}" +ARG GROUP_UID="${USER_UID}" + +ARG KUBECTL_VERSION="1.25.3" + +RUN addgroup -g "${GROUP_UID}" "${GROUP_NAME}" && \ + adduser -G "${GROUP_NAME}" -s /bin/bash -u "${USER_UID}" -h "${USER_HOME}" "${USER_NAME}" -D + +RUN apk update && \ + apk add bash + +SHELL ["/bin/bash", "-c"] + +RUN apk add bind-tools iperf3 busybox-extras curl fio + +RUN wget "https://dl.k8s.io/release/v${KUBECTL_VERSION}/bin/linux/amd64/kubectl" -O /usr/local/bin/kubectl && \ + chmod 0755 /usr/local/bin/kubectl + +COPY docker-entrypoint.sh / + +WORKDIR "${USER_HOME}" +USER "${USER_NAME}" + +ENTRYPOINT ["/bin/bash", "/docker-entrypoint.sh"] diff --git a/images/debug/docker-entrypoint.sh b/images/debug/docker-entrypoint.sh new file mode 100644 index 0000000..e1d7434 --- /dev/null +++ b/images/debug/docker-entrypoint.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +while true; do + true +done diff --git a/images/debug/pom.xml b/images/debug/pom.xml new file mode 100644 index 0000000..c642a24 --- /dev/null +++ b/images/debug/pom.xml @@ -0,0 +1,61 @@ + + + + 4.0.0 + pom + + cicd.images.debug + com.seemscloud.cicd.images.debug + + + cicd.images + com.seemscloud.cicd.images + 1.4.2-SNAPSHOT + + + + + + io.fabric8 + docker-maven-plugin + + true + + + debug + ${env.DOCKER_REPO}/debug:latest + + ${project.basedir} + @ + + + + debug + ${env.DOCKER_REPO}/debug:${project.version} + + ${project.basedir} + @ + + + + + + + build docker + package + + build + + + + push docker + package + + push + + + + + + + \ No newline at end of file diff --git a/images/fastapi/Dockerfile b/images/fastapi/Dockerfile new file mode 100644 index 0000000..45f8036 --- /dev/null +++ b/images/fastapi/Dockerfile @@ -0,0 +1,31 @@ +FROM python:3.11-alpine + +ARG USER_HOME="/app" +ARG USER_NAME="app" +ARG USER_UID="1000" +ARG GROUP_NAME="${USER_NAME}" +ARG GROUP_UID="${USER_UID}" + +ENV PATH="${PATH}:${USER_HOME}/.local/bin/" + +RUN addgroup -g "${GROUP_UID}" "${GROUP_NAME}" && \ + adduser -G "${GROUP_NAME}" -s /bin/bash -u "${USER_UID}" -h "${USER_HOME}" "${USER_NAME}" -D + +RUN apk update && \ + apk add bash + +SHELL ["/bin/bash", "-c"] + +RUN apk add bind-tools iperf3 busybox-extras curl fio + +COPY docker-entrypoint.sh / + +WORKDIR "${USER_HOME}" +USER "${USER_NAME}" + +COPY ./src/* . + +RUN python3 -m pip install --upgrade pip && \ + python3 -m pip install --upgrade hypercorn uvicorn fastapi + +ENTRYPOINT ["/bin/bash", "/docker-entrypoint.sh"] diff --git a/images/fastapi/docker-entrypoint.sh b/images/fastapi/docker-entrypoint.sh new file mode 100644 index 0000000..3eb072c --- /dev/null +++ b/images/fastapi/docker-entrypoint.sh @@ -0,0 +1,45 @@ +#!/bin/bash + +CONF_COLORS="$CONF_COLORS" + +function logger_format() { + DATE=$(date +"%Y-%m-%d %H:%M:%S,%3N") + + if [[ "${CONF_COLORS}" == "true" ]]; then + echo -e "${DATE} \e[${3}m${1}\e[m\t ${2}" + else + echo -e "${DATE} ${1}\t ${2}" + fi +} + +function logger_msg() { + if [ "${2}" == "error" ]; then + logger_format "ERROR" "${1}" "91" + elif [ "${2}" == "success" ]; then + logger_format "SUCCESS" "${1}" "92" + elif [ "${2}" == "warning" ]; then + logger_format "WARNING" "${1}" "93" + elif [ "${2}" == "info" ]; then + logger_format "INFO" "${1}" "96" + else + logger_format "LOGGER" "Incorrect logger type: '${2}'.." "31" && exit 4 + fi +} + +function logger() { + [ "${#}" -lt 2 ] || [ "${#}" -gt 2 ] && exit 1 + + logger_msg "${2}" "${1}" +} + +# Main + +if [ "${SERVER_TYPE}" == "hypercorn" ]; then + logger info "Starting '${SERVER_TYPE}' server.." + + hypercorn --bind "0.0.0.0:${SERVER_PORT}" app:app +elif [ "${SERVER_TYPE}" == "uvicorn" ]; then + logger info "Starting '${SERVER_TYPE}' server.." + + uvicorn --host "0.0.0.0" --port "${SERVER_PORT}" app:app +fi diff --git a/images/fastapi/pom.xml b/images/fastapi/pom.xml new file mode 100644 index 0000000..a0d0f3b --- /dev/null +++ b/images/fastapi/pom.xml @@ -0,0 +1,61 @@ + + + + 4.0.0 + pom + + cicd.images.fastapi + com.seemscloud.cicd.images.fastapi + + + cicd.images + com.seemscloud.cicd.images + 1.4.2-SNAPSHOT + + + + + + io.fabric8 + docker-maven-plugin + + true + + + fastapi + seemscloud/fastapi:latest + + ${project.basedir} + @ + + + + fastapi + seemscloud/fastapi:${project.version} + + ${project.basedir} + @ + + + + + + + build docker + package + + build + + + + push docker + deploy + + push + + + + + + + \ No newline at end of file diff --git a/images/fastapi/src/app.py b/images/fastapi/src/app.py new file mode 100644 index 0000000..7071c09 --- /dev/null +++ b/images/fastapi/src/app.py @@ -0,0 +1,8 @@ +from fastapi import FastAPI + +app = FastAPI() + + +@app.get("/") +async def root(): + return {"message": "Hello world!"} diff --git a/images/grpc-client/Dockerfile b/images/grpc-client/Dockerfile new file mode 100644 index 0000000..f1765a6 --- /dev/null +++ b/images/grpc-client/Dockerfile @@ -0,0 +1,29 @@ +FROM python:3.10-alpine + +ARG USER_HOME="/app" +ARG USER_NAME="grpc" +ARG USER_UID="1000" +ARG GROUP_NAME="${USER_NAME}" +ARG GROUP_UID="${USER_UID}" + +ENV GRPC_DEFAULT_SSL_ROOTS_FILE_PATH="${USER_HOME}/ca.crt.pem" + +RUN addgroup -g "${GROUP_UID}" "${GROUP_NAME}" && \ + adduser -G "${GROUP_NAME}" -s /bin/bash -u "${USER_UID}" -h "${USER_HOME}" "${USER_NAME}" -D + +RUN apk update && \ + apk add bash + +SHELL ["/bin/bash", "-c"] + +COPY docker-entrypoint.sh / + +WORKDIR "${USER_HOME}" +USER "${USER_NAME}" + +RUN python3 -m pip install --upgrade pip && \ + python3 -m pip install --upgrade grpcio grpcio-tools + +COPY src . + +ENTRYPOINT ["/bin/bash", "/docker-entrypoint.sh"] \ No newline at end of file diff --git a/images/grpc-client/docker-entrypoint.sh b/images/grpc-client/docker-entrypoint.sh new file mode 100644 index 0000000..a4fb851 --- /dev/null +++ b/images/grpc-client/docker-entrypoint.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +CONF_COLORS="$CONF_COLORS" + +function logger_format() { + DATE=$(date +"%Y-%m-%d %H:%M:%S,%3N") + + if [[ "${CONF_COLORS}" == "true" ]]; then + echo -e "${DATE} \e[${3}m${1}\e[m\t ${2}" + else + echo -e "${DATE} ${1}\t ${2}" + fi +} + +function logger_msg() { + if [ "${2}" == "error" ]; then + logger_format "ERROR" "${1}" "91" + elif [ "${2}" == "success" ]; then + logger_format "SUCCESS" "${1}" "92" + elif [ "${2}" == "warning" ]; then + logger_format "WARNING" "${1}" "93" + elif [ "${2}" == "info" ]; then + logger_format "INFO" "${1}" "96" + else + logger_format "LOGGER" "Incorrect logger type: '${2}'.." "31" && exit 4 + fi +} + +function logger() { + [ "${#}" -lt 2 ] || [ "${#}" -gt 2 ] && exit 1 + + logger_msg "${2}" "${1}" +} + +# Defaults + +if [ -z "${ENDPOINT}" ]; then + logger info "'ENDPOINT' is not set, using default endpoint 'localhost:9000'" + + ENDPOINT="localhost:9000" +fi + +# Main + +logger info "Connection to '${ENDPOINT}', TLS: '${USE_TLS}'.." +python3 -u client.py diff --git a/images/grpc-client/pom.xml b/images/grpc-client/pom.xml new file mode 100644 index 0000000..109455b --- /dev/null +++ b/images/grpc-client/pom.xml @@ -0,0 +1,61 @@ + + + + 4.0.0 + pom + + cicd.images.grpc-client + com.seemscloud.cicd.images.grpc-client + + + cicd.images + com.seemscloud.cicd.images + 1.4.2-SNAPSHOT + + + + + + io.fabric8 + docker-maven-plugin + + true + + + grpc-client + seemscloud/grpc-client:latest + + ${project.basedir} + @ + + + + grpc-client + seemscloud/grpc-client:${project.version} + + ${project.basedir} + @ + + + + + + + build docker + package + + build + + + + push docker + deploy + + push + + + + + + + \ No newline at end of file diff --git a/images/grpc-client/src/README.md b/images/grpc-client/src/README.md new file mode 100644 index 0000000..8603e69 --- /dev/null +++ b/images/grpc-client/src/README.md @@ -0,0 +1,6 @@ +```bash +export USE_TLS="true" +export ENDPOINT="localhost:9443" + +python3 client.py +``` \ No newline at end of file diff --git a/images/grpc-client/src/ca.crt.pem b/images/grpc-client/src/ca.crt.pem new file mode 100644 index 0000000..f5c9af0 --- /dev/null +++ b/images/grpc-client/src/ca.crt.pem @@ -0,0 +1,32 @@ +-----BEGIN CERTIFICATE----- +MIIFizCCA3OgAwIBAgIUKopXQejrND/MAJGQHsbVWmB0ViwwDQYJKoZIhvcNAQEL +BQAwVTELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB01hem92aWExDzANBgNVBAcMBldh +cnNhdzEUMBIGA1UECgwLU2VlbXMgQ2xvdWQxDTALBgNVBAsMBFJvb3QwHhcNMjIx +MjE5MjAxMDU3WhcNMzIxMjE2MjAxMDU3WjBVMQswCQYDVQQGEwJVUzEQMA4GA1UE +CAwHTWF6b3ZpYTEPMA0GA1UEBwwGV2Fyc2F3MRQwEgYDVQQKDAtTZWVtcyBDbG91 +ZDENMAsGA1UECwwEUm9vdDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AKhHHO6eb9Zk1B3MFUIg7ntUfs6l5TyPUi+vKn+/Jeu9eOmJX4skaHMGUh0fKF0z +FSQwXRuqO1okxG/c6AHtBgf6afHC620i6Pv+kOLEzEa3rL1ij34bCAccHREGHuyO +9u2T3IwacASZYdTvI6biXvRQq1x3zRCT+VWCuNoPbzet6GZ2h69IWgLZKFwLDdFU +AGLcwS8E7oLabxEZ4X8W9V9aPmMJczAxfXSAgewx4G71Z1rdIQ6WD03fOIKNeeBo +oJ+LGKbD9NYz7F6Gmw4ngPRYWqVUogi1qRuTOd7twOKw/PZzm0nf/g0o7m9ssQZM +WmFVdbQlsY4w0RLWZYd7kCcyTleBTZDgZFSfc1ynMmCKQvKV4PZaNCprKGtRHn2L +/80nY1NxQfgLN6w2aMW6y2Ps4wAp+LnBL1PtOUcGO2DQetK+7Y6a1ATnVH+zm4di +NXKDsYomgLUMqcdT+cCrdqQwpAFzNihC3v7U8xopuIdfmCpIHYPlTxBDi2wmQ93K +1XrEScMf7knAEgR7Ar5r0K4U79wx6SHc/Unxz/VzRI26Apnv3pIOi831zO4WScPg +/ydskvZegTCHwBov+BlZEzFDiVj6CCbM6cKj7RoMUyCmrbDb2B6BN+NmRIkDLJht +4eEhbLaF4sE8nQq0Xa9ZqI3rFJTfYC8kJrQPeQgf45v5AgMBAAGjUzBRMB0GA1Ud +DgQWBBSNd8vAscwWdDR7AV8slr98YMd9xjAfBgNVHSMEGDAWgBSNd8vAscwWdDR7 +AV8slr98YMd9xjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQBy +XOd7xcEw14hIqHYJOZ9Kw5L6OlTIZg9u1+snAcYKWi0hWPJFV/lC+oonl4MvrUYQ +ZXdXxL2Po3p2uyxpPpyaV0Rle4Alrz9ViOQwmqvUWzft3mLvpIJYnRRwXa2d5xX7 +Rz2x/DDRwacI1ew6v+D3CHm1LzILJsHwuk89sstWix48inYb4jFdHqvmfaK4XxCK +hg6w95jOKd3mBaOgciqkjROQDPQqjjFvJJvjWe5BWNFaiyG1zZMBNumstLni3t0R +d1pqhuZ4wnSUrybDGr7esYeECdApnkn3ryHjLBMS684/lMRpoyTWXaGPK/MePhoo +Y26SWssjtU0sw9opp069j5FwLEjLyovarNUY+i3H43aihhwJgWyrZT2dugdHEQp+ +FgJH9TXIXQxzur4xbUH50s13bHg8jYYGBwLruzvT4zOyRib7ZjvRZca/J9Pombca +Co2tQwulncbVh4+p8Vt6a10NmAlLetpylvpG/bU81T7wkB7QKwK4kGji20CvyBN0 +UfSitl9xwdsDmN9SjDOoeSNOnIgaE3FUyYq4U6eZbuvyojllZQtE+iWJvfOffaI8 +Dvm9lU52+fzpPR3kf0kXCfaryacEieQzxu7xW4DdjMosaHc2BGwPrnAdMtiFKsIH +LYlo25/dUfiI7D6ZnbXLTpypH1FYYFZBGoiIVKAK3w== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/images/grpc-client/src/client.py b/images/grpc-client/src/client.py new file mode 100644 index 0000000..9af0655 --- /dev/null +++ b/images/grpc-client/src/client.py @@ -0,0 +1,25 @@ +import os +import time + +import grpc.experimental + +protos, services = grpc.protos_and_services("helloworld.proto") + +name = "Lorem" +message = "Ping!" + +endpoint = os.environ["ENDPOINT"] + +if __name__ == "__main__": + request = protos.HelloRequest(name=name, message=message) + while True: + if 'USE_TLS' in os.environ and os.environ["USE_TLS"] == "true": + response = services.Greeter.SayHello(request, endpoint, insecure=False) + else: + response = services.Greeter.SayHello(request, endpoint, insecure=True) + + print("Sent '{}' as '{}' to '{}'".format(message, name, endpoint)) + print("Received '{}', from '{}' from '{}'".format(response.message, response.name, endpoint)) + print() + + time.sleep(1) diff --git a/images/grpc-client/src/helloworld.proto b/images/grpc-client/src/helloworld.proto new file mode 100644 index 0000000..119dc1e --- /dev/null +++ b/images/grpc-client/src/helloworld.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package helloworld; + +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +message HelloRequest { + string name = 1; + string message = 2; +} + +message HelloReply { + string name = 1; + string message = 2; +} \ No newline at end of file diff --git a/images/grpc-server/Dockerfile b/images/grpc-server/Dockerfile new file mode 100644 index 0000000..d47cbc9 --- /dev/null +++ b/images/grpc-server/Dockerfile @@ -0,0 +1,27 @@ +FROM python:3.10-alpine + +ARG USER_HOME="/app" +ARG USER_NAME="grpc" +ARG USER_UID="1000" +ARG GROUP_NAME="${USER_NAME}" +ARG GROUP_UID="${USER_UID}" + +RUN addgroup -g "${GROUP_UID}" "${GROUP_NAME}" && \ + adduser -G "${GROUP_NAME}" -s /bin/bash -u "${USER_UID}" -h "${USER_HOME}" "${USER_NAME}" -D + +RUN apk update && \ + apk add bash + +SHELL ["/bin/bash", "-c"] + +COPY docker-entrypoint.sh / + +WORKDIR "${USER_HOME}" +USER "${USER_NAME}" + +RUN python3 -m pip install --upgrade pip && \ + python3 -m pip install --upgrade grpcio grpcio-tools grpcio-reflection grpcio-health-checking + +COPY src . + +ENTRYPOINT ["/bin/bash", "/docker-entrypoint.sh"] \ No newline at end of file diff --git a/images/grpc-server/docker-entrypoint.sh b/images/grpc-server/docker-entrypoint.sh new file mode 100644 index 0000000..1a8a757 --- /dev/null +++ b/images/grpc-server/docker-entrypoint.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +CONF_COLORS="$CONF_COLORS" + +function logger_format() { + DATE=$(date +"%Y-%m-%d %H:%M:%S,%3N") + + if [[ "${CONF_COLORS}" == "true" ]]; then + echo -e "${DATE} \e[${3}m${1}\e[m\t ${2}" + else + echo -e "${DATE} ${1}\t ${2}" + fi +} + +function logger_msg() { + if [ "${2}" == "error" ]; then + logger_format "ERROR" "${1}" "91" + elif [ "${2}" == "success" ]; then + logger_format "SUCCESS" "${1}" "92" + elif [ "${2}" == "warning" ]; then + logger_format "WARNING" "${1}" "93" + elif [ "${2}" == "info" ]; then + logger_format "INFO" "${1}" "96" + else + logger_format "LOGGER" "Incorrect logger type: '${2}'.." "31" && exit 4 + fi +} + +function logger() { + [ "${#}" -lt 2 ] || [ "${#}" -gt 2 ] && exit 1 + + logger_msg "${2}" "${1}" +} + +# Defaults + +if [ -z "${LISTEN_PORT}" ]; then + logger info "'LISTEN_PORT' is not set, using default port '9000'" + + LISTEN_PORT="9000" +fi + +# Main + +logger info "Starting unsecured port on '${LISTEN_PORT}'.." + +if [ ! -z "${LISTEN_PORT_TLS}" ]; then + logger info "Starting secured port on '${LISTEN_PORT_TLS}'.." +fi + +python3 -u server.py diff --git a/images/grpc-server/pom.xml b/images/grpc-server/pom.xml new file mode 100644 index 0000000..48b254b --- /dev/null +++ b/images/grpc-server/pom.xml @@ -0,0 +1,61 @@ + + + + 4.0.0 + pom + + cicd.images.grpc-server + com.seemscloud.cicd.images.grpc-server + + + cicd.images + com.seemscloud.cicd.images + 1.4.2-SNAPSHOT + + + + + + io.fabric8 + docker-maven-plugin + + true + + + grpc-server + seemscloud/grpc-server:latest + + ${project.basedir} + @ + + + + grpc-server + seemscloud/grpc-server:${project.version} + + ${project.basedir} + @ + + + + + + + build docker + package + + build + + + + push docker + deploy + + push + + + + + + + \ No newline at end of file diff --git a/images/grpc-server/src/README.md b/images/grpc-server/src/README.md new file mode 100644 index 0000000..e275399 --- /dev/null +++ b/images/grpc-server/src/README.md @@ -0,0 +1,6 @@ +```bash +export LISTEN_PORT="9000" +export LISTEN_PORT_TLS="9443" + +python3 server.py +``` \ No newline at end of file diff --git a/images/grpc-server/src/health.proto b/images/grpc-server/src/health.proto new file mode 100644 index 0000000..c92ddc2 --- /dev/null +++ b/images/grpc-server/src/health.proto @@ -0,0 +1,29 @@ +syntax = "proto3"; + +package grpc.health.v1; + +option csharp_namespace = "Grpc.Health.V1"; +option go_package = "google.golang.org/grpc/health/grpc_health_v1"; +option java_multiple_files = true; +option java_outer_classname = "HealthProto"; +option java_package = "io.grpc.health.v1"; + +service Health { + rpc Check(HealthCheckRequest) returns (HealthCheckResponse); + + rpc Watch(HealthCheckRequest) returns (stream HealthCheckResponse); +} + +message HealthCheckRequest { + string service = 1; +} + +message HealthCheckResponse { + enum ServingStatus { + UNKNOWN = 0; + SERVING = 1; + NOT_SERVING = 2; + SERVICE_UNKNOWN = 3; + } + ServingStatus status = 1; +} \ No newline at end of file diff --git a/images/grpc-server/src/helloworld.proto b/images/grpc-server/src/helloworld.proto new file mode 100644 index 0000000..119dc1e --- /dev/null +++ b/images/grpc-server/src/helloworld.proto @@ -0,0 +1,17 @@ +syntax = "proto3"; + +package helloworld; + +service Greeter { + rpc SayHello (HelloRequest) returns (HelloReply) {} +} + +message HelloRequest { + string name = 1; + string message = 2; +} + +message HelloReply { + string name = 1; + string message = 2; +} \ No newline at end of file diff --git a/images/grpc-server/src/server.crt.pem b/images/grpc-server/src/server.crt.pem new file mode 100644 index 0000000..62e7c2e --- /dev/null +++ b/images/grpc-server/src/server.crt.pem @@ -0,0 +1,63 @@ +-----BEGIN CERTIFICATE----- +MIIFRzCCAy8CFEaAWxlfu65Ozgdst00u8yDMXnY6MA0GCSqGSIb3DQEBCwUAMFUx +CzAJBgNVBAYTAlVTMRAwDgYDVQQIDAdNYXpvdmlhMQ8wDQYDVQQHDAZXYXJzYXcx +FDASBgNVBAoMC1NlZW1zIENsb3VkMQ0wCwYDVQQLDARSb290MB4XDTIyMTIxOTIx +MDQ0M1oXDTI0MTIxODIxMDQ0M1owazELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB01h +em92aWExDzANBgNVBAcMBldhcnNhdzEUMBIGA1UECgwLU2VlbXMgQ2xvdWQxDTAL +BgNVBAsMBFJvb3QxFDASBgNVBAMMC2dycGMtc2VydmVyMIICIjANBgkqhkiG9w0B +AQEFAAOCAg8AMIICCgKCAgEAkCGCZoNVU7Ijp1nCWYYW45vTvF7gJX6DPKHXp7Lp +gLJUWzoBB9tvcl/i/b4UaEsRnHY/eaC0LJR9z54XeSSlLguaphai0GXhUkXAmJXZ +o7AmzJ/Se1Xsl9P9pUMWpwQtUIcyYkqPZc3+zUvJ7aHSLrhtvttialrdutnQodve +hdP7StWK9dSQHzj2m5PAH3ime3tCzEJQpuTR2qgeXau1hqeKjrckum3VwEfvd7qZ +n2DzDt9Om85KjZ5E7x2UVzCreE7NO8tkQoSwYTY632wjmzL215KWbZ5WN/qmYmuX +aNn307wqCc7YxaNKKmkZQaPw7Z72JF6W3IVWFtdWBWvF44lZMuOpsOif3xfZjF4S +QzDI+XKAjohU7jzCYnqaFGVva5eZf6u9ywRdukrGmkXjMtiv5/TdKfJLTHWgZOOO +yD87hMhCvOQL0VQadutSn1a3Mm6cZXozFdX3VlLrx27LODNgW7uQPtz180dW/6R/ +9qSCP/2dOQczq4Gxwu8tqVmMwglMMd7B/TqP/SZJb+/1aRRu9HYmuTzKfCl38X35 +ABuFKTToxLgO3gohWU4Bi/FNO/Ce8IQo3OuCdVvc/zWR4dNw6DLvS+C1YzuwIsmE +tCQP32G/9ICT/gjm1cfNot8SGls0JxdSG/Dnnk7H0W6oepZNfTKZmjlvD6RBXWix +tHECAwEAATANBgkqhkiG9w0BAQsFAAOCAgEAEL8ZIVxGlo1e6rv/7gI0F+x4/Zzs +XoIlCmJiWTJ1xdFPCd1mWKBi5WvxBJj7ZHyICqe8uCTlpfn6G+k8HAu/Nr4tKtX0 +Q358SSQH3GC5QCbnr1g35LyMgUwVqhHrTO3ye1RGtUkYnS5Vm2Qj/jzZbEKsslyd +8gCVxDqa/rx1iZfLfMuIn7aqzBdu9aF5fC487ag9vNRbDu1qTuAb6YelMt+glRNx +hGS7LSZFQeSnkaI7hP3UFEJHmOrL0n56CR+6g8oB7Vg1vKW+u2UaROo9qmHRnHCP +I9ZJkkcGpyJrQQUk0GikDWBuB/iTcOkWL3QEaWEGbsJqoI2bEWaHbpdXBxfRNCiY +zRwdx6y2e1pQDoclKoPMozshkkEtcbcj4H0nX+lz/jKwsj2HP8ebr4qj9iXt+n/N +LkbR8YfX9h2dIjFtX/yYZNenNq192bbwS8ZxNnXzUX13oYAepaJ3wO7zzOFxc7fE +obRl646HwsAFMibuUwpy2n3/mld0wBKIqPzqhNBKTp15+QLWfN1Ove1dybrztx/X +/aAajPIT2g2q5xKjIQVW7Ob+03ZRsx13vLrra/okpbZxikc0GiRsF13kFUjlqs6V +mAt/jp2aqXbYqngTBsHv3bVo/UIbDWdx7AgaqhWGLno3LVRRncXAhYIxYN/HOgr9 +U20Cds7FKlk58wY= +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +MIIFizCCA3OgAwIBAgIUKopXQejrND/MAJGQHsbVWmB0ViwwDQYJKoZIhvcNAQEL +BQAwVTELMAkGA1UEBhMCVVMxEDAOBgNVBAgMB01hem92aWExDzANBgNVBAcMBldh +cnNhdzEUMBIGA1UECgwLU2VlbXMgQ2xvdWQxDTALBgNVBAsMBFJvb3QwHhcNMjIx +MjE5MjAxMDU3WhcNMzIxMjE2MjAxMDU3WjBVMQswCQYDVQQGEwJVUzEQMA4GA1UE +CAwHTWF6b3ZpYTEPMA0GA1UEBwwGV2Fyc2F3MRQwEgYDVQQKDAtTZWVtcyBDbG91 +ZDENMAsGA1UECwwEUm9vdDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB +AKhHHO6eb9Zk1B3MFUIg7ntUfs6l5TyPUi+vKn+/Jeu9eOmJX4skaHMGUh0fKF0z +FSQwXRuqO1okxG/c6AHtBgf6afHC620i6Pv+kOLEzEa3rL1ij34bCAccHREGHuyO +9u2T3IwacASZYdTvI6biXvRQq1x3zRCT+VWCuNoPbzet6GZ2h69IWgLZKFwLDdFU +AGLcwS8E7oLabxEZ4X8W9V9aPmMJczAxfXSAgewx4G71Z1rdIQ6WD03fOIKNeeBo +oJ+LGKbD9NYz7F6Gmw4ngPRYWqVUogi1qRuTOd7twOKw/PZzm0nf/g0o7m9ssQZM +WmFVdbQlsY4w0RLWZYd7kCcyTleBTZDgZFSfc1ynMmCKQvKV4PZaNCprKGtRHn2L +/80nY1NxQfgLN6w2aMW6y2Ps4wAp+LnBL1PtOUcGO2DQetK+7Y6a1ATnVH+zm4di +NXKDsYomgLUMqcdT+cCrdqQwpAFzNihC3v7U8xopuIdfmCpIHYPlTxBDi2wmQ93K +1XrEScMf7knAEgR7Ar5r0K4U79wx6SHc/Unxz/VzRI26Apnv3pIOi831zO4WScPg +/ydskvZegTCHwBov+BlZEzFDiVj6CCbM6cKj7RoMUyCmrbDb2B6BN+NmRIkDLJht +4eEhbLaF4sE8nQq0Xa9ZqI3rFJTfYC8kJrQPeQgf45v5AgMBAAGjUzBRMB0GA1Ud +DgQWBBSNd8vAscwWdDR7AV8slr98YMd9xjAfBgNVHSMEGDAWgBSNd8vAscwWdDR7 +AV8slr98YMd9xjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4ICAQBy +XOd7xcEw14hIqHYJOZ9Kw5L6OlTIZg9u1+snAcYKWi0hWPJFV/lC+oonl4MvrUYQ +ZXdXxL2Po3p2uyxpPpyaV0Rle4Alrz9ViOQwmqvUWzft3mLvpIJYnRRwXa2d5xX7 +Rz2x/DDRwacI1ew6v+D3CHm1LzILJsHwuk89sstWix48inYb4jFdHqvmfaK4XxCK +hg6w95jOKd3mBaOgciqkjROQDPQqjjFvJJvjWe5BWNFaiyG1zZMBNumstLni3t0R +d1pqhuZ4wnSUrybDGr7esYeECdApnkn3ryHjLBMS684/lMRpoyTWXaGPK/MePhoo +Y26SWssjtU0sw9opp069j5FwLEjLyovarNUY+i3H43aihhwJgWyrZT2dugdHEQp+ +FgJH9TXIXQxzur4xbUH50s13bHg8jYYGBwLruzvT4zOyRib7ZjvRZca/J9Pombca +Co2tQwulncbVh4+p8Vt6a10NmAlLetpylvpG/bU81T7wkB7QKwK4kGji20CvyBN0 +UfSitl9xwdsDmN9SjDOoeSNOnIgaE3FUyYq4U6eZbuvyojllZQtE+iWJvfOffaI8 +Dvm9lU52+fzpPR3kf0kXCfaryacEieQzxu7xW4DdjMosaHc2BGwPrnAdMtiFKsIH +LYlo25/dUfiI7D6ZnbXLTpypH1FYYFZBGoiIVKAK3w== +-----END CERTIFICATE----- \ No newline at end of file diff --git a/images/grpc-server/src/server.key.pem b/images/grpc-server/src/server.key.pem new file mode 100644 index 0000000..e9c088b --- /dev/null +++ b/images/grpc-server/src/server.key.pem @@ -0,0 +1,52 @@ +-----BEGIN PRIVATE KEY----- +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 +F1Diykeauz3Qxwu6p3e7xmw3LkDO +-----END PRIVATE KEY----- \ No newline at end of file diff --git a/images/grpc-server/src/server.py b/images/grpc-server/src/server.py new file mode 100644 index 0000000..6ad5aed --- /dev/null +++ b/images/grpc-server/src/server.py @@ -0,0 +1,58 @@ +import os +import threading +from concurrent import futures + +import grpc +import grpc.experimental +from grpc_reflection.v1alpha import reflection + +protos, services = grpc.protos_and_services("helloworld.proto") + + +class Greeter(services.GreeterServicer): + def __init__(self): + self.name = "Ipsum" + self.message = "Pong!" + + def SayHello(self, request, context): + print("Received '{}' from '{}'".format(request.message, request.name)), + print("Sent '{}' as '{}'".format(self.message, self.name)) + print() + + return protos.HelloReply(name=self.name, message=self.message) + + +if __name__ == "__main__": + server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) + + greater = Greeter() + + services.add_GreeterServicer_to_server(greater, server) + + SERVICE_NAMES = ( + protos.DESCRIPTOR.services_by_name['Greeter'].full_name, + reflection.SERVICE_NAME, + ) + reflection.enable_server_reflection(SERVICE_NAMES, server) + + if 'LISTEN_PORT_TLS' in os.environ: + server_port_tls = "0.0.0.0:{}".format(os.environ["LISTEN_PORT_TLS"]) + + server_key_file = 'server.key.pem' + server_cert_file = 'server.crt.pem' + + server_key = open(server_key_file).read() + server_cert = open(server_cert_file).read() + + credentials = grpc.ssl_server_credentials([( + bytes(server_key, "UTF-8"), + bytes(server_cert, "UTF-8") + )]) + + server.add_secure_port(server_port_tls, credentials) + + server_port = "0.0.0.0:{}".format(os.environ["LISTEN_PORT"]) + server.add_insecure_port(server_port) + + server.start() + server.wait_for_termination() diff --git a/images/grpc-xds-server/Dockerfile b/images/grpc-xds-server/Dockerfile new file mode 100644 index 0000000..d176031 --- /dev/null +++ b/images/grpc-xds-server/Dockerfile @@ -0,0 +1,27 @@ +FROM python:3.10-alpine + +ARG USER_HOME="/app" +ARG USER_NAME="grpc" +ARG USER_UID="1000" +ARG GROUP_NAME="${USER_NAME}" +ARG GROUP_UID="${USER_UID}" + +RUN addgroup -g "${GROUP_UID}" "${GROUP_NAME}" && \ + adduser -G "${GROUP_NAME}" -s /bin/bash -u "${USER_UID}" -h "${USER_HOME}" "${USER_NAME}" -D + +RUN apk update && \ + apk add bash + +SHELL ["/bin/bash", "-c"] + +COPY docker-entrypoint.sh / + +WORKDIR "${USER_HOME}" +USER "${USER_NAME}" + +RUN python3 -m pip install --upgrade pip && \ + python3 -m pip install --upgrade grpcio grpcio-tools grpcio-reflection grpcio-health-checking protobuf + +COPY src . + +ENTRYPOINT ["/bin/bash", "/docker-entrypoint.sh"] \ No newline at end of file diff --git a/images/grpc-xds-server/docker-entrypoint.sh b/images/grpc-xds-server/docker-entrypoint.sh new file mode 100644 index 0000000..8811100 --- /dev/null +++ b/images/grpc-xds-server/docker-entrypoint.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +CONF_COLORS="$CONF_COLORS" + +function logger_format() { + DATE=$(date +"%Y-%m-%d %H:%M:%S,%3N") + + if [[ "${CONF_COLORS}" == "true" ]]; then + echo -e "${DATE} \e[${3}m${1}\e[m\t ${2}" + else + echo -e "${DATE} ${1}\t ${2}" + fi +} + +function logger_msg() { + if [ "${2}" == "error" ]; then + logger_format "ERROR" "${1}" "91" + elif [ "${2}" == "success" ]; then + logger_format "SUCCESS" "${1}" "92" + elif [ "${2}" == "warning" ]; then + logger_format "WARNING" "${1}" "93" + elif [ "${2}" == "info" ]; then + logger_format "INFO" "${1}" "96" + else + logger_format "LOGGER" "Incorrect logger type: '${2}'.." "31" && exit 4 + fi +} + +function logger() { + [ "${#}" -lt 2 ] || [ "${#}" -gt 2 ] && exit 1 + + logger_msg "${2}" "${1}" +} + +python3 -u server.py diff --git a/images/grpc-xds-server/pom.xml b/images/grpc-xds-server/pom.xml new file mode 100644 index 0000000..1f14af4 --- /dev/null +++ b/images/grpc-xds-server/pom.xml @@ -0,0 +1,61 @@ + + + + 4.0.0 + pom + + cicd.images.grpc-xds-server + com.seemscloud.cicd.images.grpc-xds-server + + + cicd.images + com.seemscloud.cicd.images + 1.4.2-SNAPSHOT + + + + + + io.fabric8 + docker-maven-plugin + + true + + + grpc-xds-server + seemscloud/grpc-xds-server:latest + + ${project.basedir} + @ + + + + grpc-xds-server + seemscloud/grpc-xds-server:${project.version} + + ${project.basedir} + @ + + + + + + + build docker + package + + build + + + + push docker + deploy + + push + + + + + + + \ No newline at end of file diff --git a/images/grpc-xds-server/src/helloworld_pb2.py b/images/grpc-xds-server/src/helloworld_pb2.py new file mode 100644 index 0000000..f5b4f2d --- /dev/null +++ b/images/grpc-xds-server/src/helloworld_pb2.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Generated by the protocol buffer compiler. DO NOT EDIT! +# source: helloworld.proto +"""Generated protocol buffer code.""" +from google.protobuf.internal import builder as _builder +from google.protobuf import descriptor as _descriptor +from google.protobuf import descriptor_pool as _descriptor_pool +from google.protobuf import symbol_database as _symbol_database +# @@protoc_insertion_point(imports) + +_sym_db = _symbol_database.Default() + + + + +DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x10helloworld.proto\x12\nhelloworld\"\x1c\n\x0cHelloRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"\x1d\n\nHelloReply\x12\x0f\n\x07message\x18\x01 \x01(\t2I\n\x07Greeter\x12>\n\x08SayHello\x12\x18.helloworld.HelloRequest\x1a\x16.helloworld.HelloReply\"\x00\x42\x36\n\x1bio.grpc.examples.helloworldB\x0fHelloWorldProtoP\x01\xa2\x02\x03HLWb\x06proto3') + +_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) +_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'helloworld_pb2', globals()) +if _descriptor._USE_C_DESCRIPTORS == False: + + DESCRIPTOR._options = None + DESCRIPTOR._serialized_options = b'\n\033io.grpc.examples.helloworldB\017HelloWorldProtoP\001\242\002\003HLW' + _HELLOREQUEST._serialized_start=32 + _HELLOREQUEST._serialized_end=60 + _HELLOREPLY._serialized_start=62 + _HELLOREPLY._serialized_end=91 + _GREETER._serialized_start=93 + _GREETER._serialized_end=166 +# @@protoc_insertion_point(module_scope) diff --git a/images/grpc-xds-server/src/helloworld_pb2_grpc.py b/images/grpc-xds-server/src/helloworld_pb2_grpc.py new file mode 100644 index 0000000..47c1869 --- /dev/null +++ b/images/grpc-xds-server/src/helloworld_pb2_grpc.py @@ -0,0 +1,70 @@ +# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! +"""Client and server classes corresponding to protobuf-defined services.""" +import grpc + +import helloworld_pb2 as helloworld__pb2 + + +class GreeterStub(object): + """The greeting service definition. + """ + + def __init__(self, channel): + """Constructor. + + Args: + channel: A grpc.Channel. + """ + self.SayHello = channel.unary_unary( + '/helloworld.Greeter/SayHello', + request_serializer=helloworld__pb2.HelloRequest.SerializeToString, + response_deserializer=helloworld__pb2.HelloReply.FromString, + ) + + +class GreeterServicer(object): + """The greeting service definition. + """ + + def SayHello(self, request, context): + """Sends a greeting + """ + context.set_code(grpc.StatusCode.UNIMPLEMENTED) + context.set_details('Method not implemented!') + raise NotImplementedError('Method not implemented!') + + +def add_GreeterServicer_to_server(servicer, server): + rpc_method_handlers = { + 'SayHello': grpc.unary_unary_rpc_method_handler( + servicer.SayHello, + request_deserializer=helloworld__pb2.HelloRequest.FromString, + response_serializer=helloworld__pb2.HelloReply.SerializeToString, + ), + } + generic_handler = grpc.method_handlers_generic_handler( + 'helloworld.Greeter', rpc_method_handlers) + server.add_generic_rpc_handlers((generic_handler,)) + + + # This class is part of an EXPERIMENTAL API. +class Greeter(object): + """The greeting service definition. + """ + + @staticmethod + def SayHello(request, + target, + options=(), + channel_credentials=None, + call_credentials=None, + insecure=False, + compression=None, + wait_for_ready=None, + timeout=None, + metadata=None): + return grpc.experimental.unary_unary(request, target, '/helloworld.Greeter/SayHello', + helloworld__pb2.HelloRequest.SerializeToString, + helloworld__pb2.HelloReply.FromString, + options, channel_credentials, + insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/images/grpc-xds-server/src/server.py b/images/grpc-xds-server/src/server.py new file mode 100644 index 0000000..915633e --- /dev/null +++ b/images/grpc-xds-server/src/server.py @@ -0,0 +1,111 @@ +import argparse +from concurrent import futures +import logging +import socket + +import grpc +from grpc_health.v1 import health +from grpc_health.v1 import health_pb2 +from grpc_health.v1 import health_pb2_grpc +from grpc_reflection.v1alpha import reflection +import helloworld_pb2 +import helloworld_pb2_grpc + +_DESCRIPTION = "A general purpose phony server." + +_LISTEN_HOST = "0.0.0.0" + +_THREAD_POOL_SIZE = 256 + +logger = logging.getLogger() +console_handler = logging.StreamHandler() +formatter = logging.Formatter(fmt='%(asctime)s: %(levelname)-8s %(message)s') +console_handler.setFormatter(formatter) +logger.addHandler(console_handler) + + +class Greeter(helloworld_pb2_grpc.GreeterServicer): + + def __init__(self, hostname: str): + self._hostname = hostname if hostname else socket.gethostname() + + def SayHello(self, request: helloworld_pb2.HelloRequest, + context: grpc.ServicerContext) -> helloworld_pb2.HelloReply: + return helloworld_pb2.HelloReply( + message=f"Hello {request.name} from {self._hostname}!") + + +def _configure_maintenance_server(server: grpc.Server, + maintenance_port: int) -> None: + listen_address = f"{_LISTEN_HOST}:{maintenance_port}" + server.add_insecure_port(listen_address) + + health_servicer = health.HealthServicer( + experimental_non_blocking=True, + experimental_thread_pool=futures.ThreadPoolExecutor( + max_workers=_THREAD_POOL_SIZE)) + + services = tuple( + service.full_name + for service in helloworld_pb2.DESCRIPTOR.services_by_name.values()) + ( + reflection.SERVICE_NAME, health.SERVICE_NAME) + + health_pb2_grpc.add_HealthServicer_to_server(health_servicer, server) + for service in services: + health_servicer.set(service, health_pb2.HealthCheckResponse.SERVING) + reflection.enable_server_reflection(services, server) + + +def _configure_greeter_server(server: grpc.Server, port: int, secure_mode: bool, + hostname) -> None: + helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(hostname), server) + listen_address = f"{_LISTEN_HOST}:{port}" + if not secure_mode: + server.add_insecure_port(listen_address) + else: + logger.info("Running with xDS Server credentials") + + server_fallback_creds = grpc.insecure_server_credentials() + server_creds = grpc.xds_server_credentials(server_fallback_creds) + server.add_secure_port(listen_address, server_creds) + + +def serve(port: int, hostname: str, maintenance_port: int, + secure_mode: bool) -> None: + if port == maintenance_port: + server = grpc.server(futures.ThreadPoolExecutor(max_workers=_THREAD_POOL_SIZE)) + _configure_greeter_server(server, port, secure_mode, hostname) + _configure_maintenance_server(server, maintenance_port) + server.start() + logger.info("Greeter server listening on port %d", port) + logger.info("Maintenance server listening on port %d", maintenance_port) + server.wait_for_termination() + else: + greeter_server = grpc.server( + futures.ThreadPoolExecutor(max_workers=_THREAD_POOL_SIZE), xds=secure_mode) + _configure_greeter_server(greeter_server, port, secure_mode, hostname) + greeter_server.start() + logger.info("Greeter server listening on port %d", port) + maintenance_server = grpc.server(futures.ThreadPoolExecutor(max_workers=_THREAD_POOL_SIZE)) + _configure_maintenance_server(maintenance_server, maintenance_port) + maintenance_server.start() + logger.info("Maintenance server listening on port %d", maintenance_port) + greeter_server.wait_for_termination() + maintenance_server.wait_for_termination() + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description=_DESCRIPTION) + parser.add_argument("port", default=50051, type=int, nargs="?", + help="The port on which to listen.") + + parser.add_argument("hostname", type=str, default=None, nargs="?", + help="The name clients will see in responses.") + + parser.add_argument("--xds-creds", action="store_true", + help="If specified, uses xDS credentials to connect to the server.") + + args = parser.parse_args() + logging.basicConfig() + logger.setLevel(logging.INFO) + serve(args.port, args.hostname, args.port + 1, args.xds_creds) diff --git a/images/k3s/Dockerfile b/images/k3s/Dockerfile new file mode 100644 index 0000000..574ea5b --- /dev/null +++ b/images/k3s/Dockerfile @@ -0,0 +1,28 @@ +FROM alpine:3.18.4 + +RUN rm -rf /bin +COPY --from=rancher/k3s:v1.27.4-k3s1 /bin /bin + +RUN set -ex; \ + apk add --no-cache iptables ip6tables nfs-utils rpcbind openrc bash; \ + echo 'hosts: files dns' > /etc/nsswitch.conf + +RUN rc-update add rpcbind && \ + rc-update add nfs + +RUN mkdir -p /run/openrc && \ + touch /run/openrc/softlevel + +VOLUME /var/lib/kubelet +VOLUME /var/lib/rancher/k3s +VOLUME /var/lib/cni +VOLUME /var/log + +ENV PATH="${PATH}:/bin/aux" +ENV CRI_CONFIG_FILE="/var/lib/rancher/k3s/agent/etc/crictl.yaml" + +COPY k3d-entrypoint-nfs.sh /bin +RUN chmod +x /bin/k3d-entrypoint-nfs.sh + +ENTRYPOINT ["/bin/k3d-entrypoint-nfs.sh"] +CMD ["agent"] \ No newline at end of file diff --git a/images/k3s/k3d-entrypoint-nfs.sh b/images/k3s/k3d-entrypoint-nfs.sh new file mode 100644 index 0000000..a7c067d --- /dev/null +++ b/images/k3s/k3d-entrypoint-nfs.sh @@ -0,0 +1,15 @@ +#!/bin/sh + +set -o errexit +set -o nounset +set -o pipefail + +( sleep 10 && \ + #/bin/rc-status > /tmp/rcstatus.moises && cat /tmp/rcstatus.moises && \ + /bin/rc-status ) & + +( sleep 20 && \ + touch /run/openrc/softlevel && \ + /sbin/rc-service nfs start ) & + +exec /bin/k3s "$@" \ No newline at end of file diff --git a/images/k3s/pom.xml b/images/k3s/pom.xml new file mode 100644 index 0000000..f599ab9 --- /dev/null +++ b/images/k3s/pom.xml @@ -0,0 +1,61 @@ + + + + 4.0.0 + pom + + cicd.images.k3s + com.seemscloud.cicd.images.k3s + + + cicd.images + com.seemscloud.cicd.images + 1.4.2-SNAPSHOT + + + + + + io.fabric8 + docker-maven-plugin + + true + + + debug + seemscloud/debug:latest + + ${project.basedir} + @ + + + + debug + seemscloud/debug:${project.version} + + ${project.basedir} + @ + + + + + + + build docker + package + + build + + + + push docker + deploy + + push + + + + + + + \ No newline at end of file diff --git a/images/pom.xml b/images/pom.xml new file mode 100644 index 0000000..ee66374 --- /dev/null +++ b/images/pom.xml @@ -0,0 +1,42 @@ + + + + 4.0.0 + pom + + cicd.images + com.seemscloud.cicd.images + + + cicd + com.seemscloud.cicd + 1.4.2-SNAPSHOT + + + + debug + fastapi + grpc-client + grpc-server + grpc-xds-server + k3s + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.4.0 + + + parse-version + + parse-version + + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..5877d9d --- /dev/null +++ b/pom.xml @@ -0,0 +1,97 @@ + + + + 4.0.0 + pom + + cicd + com.seemscloud.cicd + 1.4.2-SNAPSHOT + + + https://github.com/seemscloud/github-actions-maven-cicd + scm:git:https://github.com/seemscloud/github-actions-maven-cicd.git + scm:git:https://github.com/seemscloud/github-actions-maven-cicd.git + + + main + + + + images + + + + + + org.codehaus.mojo + build-helper-maven-plugin + 3.4.0 + + + parse-version + + parse-version + + + + + + org.apache.maven.plugins + maven-release-plugin + + + pom.xml + + + + + org.apache.maven.plugins + maven-release-plugin + 3.0.1 + + + org.apache.maven.plugins + maven-release-plugin + 3.0.0 + + + nl.basjes.maven.release + conventional-commits-version-policy + 1.0.4 + + + + [Versioner] Version @{releaseLabel} + [Versioner] Bump Patch version + [Versioner] Rollback the release of @{releaseLabel} + + + @{project.version} + true + true + + ConventionalCommitsVersionPolicy + + ^([0-9]+\.[0-9]+\.[0-9]+)$ + + ^feat: .*$ + + + + + + prepare-release + install + + prepare + + + true + + + + + + + \ No newline at end of file