diff --git a/Dockerfile b/Dockerfile index c1a54b9..59b04f6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -9,8 +9,14 @@ ARG WORKDIR ENV PYTHONUNBUFFERED=1 # Don't create `.pyc` files: ENV PYTHONDONTWRITEBYTECODE=1 +# https://github.com/rust-lang/cargo/issues/2808 +ENV CARGO_NET_GIT_FETCH_WITH_CLI=true -RUN pip install poetry && poetry config virtualenvs.in-project true +# For building CFFI / Crypgotraphy: +RUN apk add gcc make musl-dev libffi-dev rust cargo git openssl-dev + +RUN pip install poetry +RUN poetry config virtualenvs.in-project true WORKDIR ${WORKDIR} diff --git a/Jenkinsfile b/Jenkinsfile index 1a93404..53ebb8e 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -1,100 +1,124 @@ -def privateImage // My personal git / container registry -def publicImage // GitHub Container Registry and Docker Hub pipeline { agent { label 'linux-x64' } environment { - APP_VERSION = 'v0.5.3' - HS_VERSION = "v0.20.0" // Version of Headscale this is compatible with - BUILD_DATE = '' + APP_VERSION = 'v0.5.4' + HS_VERSION = "v0.20.0" // Version of Headscale this is compatible with + BUILD_DATE = '' + BUILDER_NAME = "multiarch" + + DOCKERHUB_URL = "https://registry-1.docker.io/" + DOCKERHUB_CRED = credentials('dockerhub-ifargle-pat') + + GHCR_URL = "https://ghcr.io/" + GHCR_CRED = credentials('github-ifargle-pat') + + SYSCTL_URL = "https://git.sysctl.io/" + SYSCTL_CRED = credentials('gitea-jenkins-pat') } options { buildDiscarder(logRotator(numToKeepStr: '100', artifactNumToKeepStr: '20')) timestamps() } stages { - stage ('ENV') { + stage ('Jenkins ENV') { steps { sh 'printenv' script { BUILD_DATE = java.time.LocalDate.now() } } } + stage('Create Build ENV') { + steps { + sh """ + # Create the builder: + docker buildx create --name $BUILDER_NAME + docker buildx use $BUILDER_NAME + docker buildx inspect --bootstrap + + docker buildx ls + """ + + sh 'docker login -u ${DOCKERHUB_CRED_USR} -p ${DOCKERHUB_CRED_PSW} $DOCKERHUB_URL' + sh 'docker login -u ${GHCR_CRED_USR} -p ${GHCR_CRED_PSW} $GHCR_URL' + sh 'docker login -u ${SYSCTL_CRED_USR} -p ${SYSCTL_CRED_PSW} $SYSCTL_URL' + } + } stage('Build') { - options { timeout(time: 30, unit: 'MINUTES') } - steps { - script { - privateImage = docker.build("albert/headscale-webui:${env.BRANCH_NAME}-${env.BUILD_ID}", - "--label \"GIT_COMMIT=${env.GIT_COMMIT}\" " - + " --build-arg GIT_COMMIT_ARG=${env.GIT_COMMIT} " - + " --build-arg GIT_BRANCH_ARG=${env.BRANCH_NAME} " - + " --build-arg APP_VERSION_ARG=${APP_VERSION} " - + " --build-arg BUILD_DATE_ARG=${BUILD_DATE} " - + " --build-arg HS_VERSION_ARG=${HS_VERSION} " - + " ." - ) - publicImage = docker.build("ifargle/headscale-webui:${env.BRANCH_NAME}-${env.BUILD_ID}", - "--label \"GIT_COMMIT=${env.GIT_COMMIT}\" " - + " --build-arg GIT_COMMIT_ARG=${env.GIT_COMMIT} " - + " --build-arg GIT_BRANCH_ARG=${env.BRANCH_NAME} " - + " --build-arg APP_VERSION_ARG=${APP_VERSION} " - + " --build-arg BUILD_DATE_ARG=${BUILD_DATE} " - + " --build-arg HS_VERSION_ARG=${HS_VERSION} " - + " ." - ) - } - } - } - stage('Test') { - options { timeout(time: 3, unit: 'MINUTES') } - steps { - script { - privateImage.inside { - sh 'ls -lah /app' - sh 'python --version' - sh 'pip list' - } - publicImage.inside { - sh 'ls -lah /app' - sh 'python --version' - sh 'pip list' - } - } - } - } - stage('Push') { - options { timeout(time: 5, unit: 'MINUTES') } + options { timeout(time: 2, unit: 'HOURS') } steps { script { if (env.BRANCH_NAME == 'main') { - docker.withRegistry('https://git.sysctl.io/', 'gitea-jenkins-pat') { - privateImage.push("latest") - privateImage.push(APP_VERSION) - } - docker.withRegistry('https://ghcr.io/', 'github-ifargle-pat') { - publicImage.push("latest") - publicImage.push(APP_VERSION) - } - docker.withRegistry('https://registry-1.docker.io/', 'dockerhub-ifargle-pat') { - publicImage.push("latest") - publicImage.push(APP_VERSION) - } - } else { - docker.withRegistry('https://git.sysctl.io/', 'gitea-jenkins-pat') { - privateImage.push("${env.BRANCH_NAME}") - privateImage.push("testing") - } + sh """ + docker build . \ + -t git.sysctl.io/albert/headscale-webui:latest \ + -t git.sysctl.io/albert/headscale-webui:${APP_VERSION} \ + --build-arg GIT_COMMIT_ARG=${env.GIT_COMMIT} \ + --build-arg GIT_BRANCH_ARG=${env.BRANCH_NAME} \ + --build-arg APP_VERSION_ARG=${APP_VERSION} \ + --build-arg BUILD_DATE_ARG=${BUILD_DATE} \ + --build-arg HS_VERSION_ARG=${HS_VERSION} \ + --label \"GIT_COMMIT=${env.GIT_COMMIT}\" \ + --platform linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 \ + --push + """ + } else { // IF I'm just testing, I don't need to build for ARM + sh """ + docker build . \ + -t git.sysctl.io/albert/headscale-webui:testing \ + -t git.sysctl.io/albert/headscale-webui:${env.BRANCH_NAME} \ + --build-arg GIT_COMMIT_ARG=${env.GIT_COMMIT} \ + --build-arg GIT_BRANCH_ARG=${env.BRANCH_NAME} \ + --build-arg APP_VERSION_ARG=${APP_VERSION} \ + --build-arg BUILD_DATE_ARG=${BUILD_DATE} \ + --build-arg HS_VERSION_ARG=${HS_VERSION} \ + --label \"GIT_COMMIT=${env.GIT_COMMIT}\" \ + --platform linux/amd64 \ + --push + """ } } } } - stage('Clean') { - options { timeout(time: 3, unit: 'MINUTES') } + stage('Build Public') { + options { timeout(time: 2, unit: 'HOURS') } steps { script { - sh 'docker system prune --force' + if (env.BRANCH_NAME == 'main') { + sh """ + docker build . \ + -t docker.io/ifargle/headscale-webui:latest \ + -t docker.io/ifargle/headscale-webui:${APP_VERSION} \ + -t ghcr.io/ifargle/headscale-webui:latest \ + -t ghcr.io/ifargle/headscale-webui:${APP_VERSION} \ + --build-arg GIT_COMMIT_ARG=${env.GIT_COMMIT} \ + --build-arg GIT_BRANCH_ARG=${env.BRANCH_NAME} \ + --build-arg APP_VERSION_ARG=${APP_VERSION} \ + --build-arg BUILD_DATE_ARG=${BUILD_DATE} \ + --build-arg HS_VERSION_ARG=${HS_VERSION} \ + --label \"GIT_COMMIT=${env.GIT_COMMIT}\" \ + --platform linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 \ + --push + """ + } } } } } + post { + always { + script { + sh """ + docker buildx use default + docker buildx rm $BUILDER_NAME + + ## Sanity check step + docker buildx ls + docker logout + + docker system prune --force + """ + } + } + } } diff --git a/renderer.py b/renderer.py index 6369c8b..b825b94 100644 --- a/renderer.py +++ b/renderer.py @@ -406,14 +406,15 @@ def render_machines_cards(): app.logger.debug("Appending iterable: "+str(i)) iterable.append(i) # Flask-Executor Method: - app.logger.info("Starting futures") - futures = [executor.submit(thread_machine_content, machines_list["machines"][idx], machine_content, idx) for idx in iterable] - # Wait for the executor to finish all jobs: - wait(futures, return_when=ALL_COMPLETED) - app.logger.info("Finished futures") - - # DEBUG: Do in a forloop: - # for idx in iterable: thread_machine_content(machines_list["machines"][idx], machine_content, idx) + if LOG_LEVEL == "DEBUG": + # DEBUG: Do in a forloop: + for idx in iterable: thread_machine_content(machines_list["machines"][idx], machine_content, idx) + else: + app.logger.info("Starting futures") + futures = [executor.submit(thread_machine_content, machines_list["machines"][idx], machine_content, idx) for idx in iterable] + # Wait for the executor to finish all jobs: + wait(futures, return_when=ALL_COMPLETED) + app.logger.info("Finished futures") # Sort the content by machine_id: sorted_machines = {key: val for key, val in sorted(machine_content.items(), key = lambda ele: ele[0])}