From 92fe6154e658cb0f68f5dd22ec44035a251bf396 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 11:53:56 +0100 Subject: [PATCH 01/62] code styling --- app/main.py | 50 +++++++++++++------------------------------------- app/util.py | 17 +++++++++++++++++ 2 files changed, 30 insertions(+), 37 deletions(-) create mode 100644 app/util.py diff --git a/app/main.py b/app/main.py index b21c8c1..4eb1d4e 100644 --- a/app/main.py +++ b/app/main.py @@ -3,7 +3,7 @@ from base64 import b64encode as b64enc from hashlib import sha256 from uuid import uuid4 from os.path import join, dirname -from os import getenv +from os import getenv as env from dotenv import load_dotenv from fastapi import FastAPI, HTTPException @@ -20,52 +20,28 @@ from starlette.responses import StreamingResponse, JSONResponse, HTMLResponse from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker -try: - # Crypto | Cryptodome on Debian - from Crypto.PublicKey import RSA - from Crypto.PublicKey.RSA import RsaKey -except ModuleNotFoundError: - from Cryptodome.PublicKey import RSA - from Cryptodome.PublicKey.RSA import RsaKey +from app.util import load_key, load_file from orm import Origin, Lease, init as db_init logger = logging.getLogger() load_dotenv('../version.env') -VERSION, COMMIT, DEBUG = getenv('VERSION', 'unknown'), getenv('COMMIT', 'unknown'), bool(getenv('DEBUG', False)) +VERSION, COMMIT, DEBUG = env('VERSION', 'unknown'), env('COMMIT', 'unknown'), bool(env('DEBUG', False)) - -def load_file(filename) -> bytes: - with open(filename, 'rb') as file: - content = file.read() - return content - - -def load_key(filename) -> RsaKey: - return RSA.import_key(extern_key=load_file(filename), passphrase=None) - - -# todo: initialize certificate (or should be done by user, and passed through "volumes"?) - -__details = dict( - title='FastAPI-DLS', - description='Minimal Delegated License Service (DLS).', - version=VERSION, -) - -app, db = FastAPI(**__details), create_engine(str(getenv('DATABASE', 'sqlite:///db.sqlite'))) +app = FastAPI(title='FastAPI-DLS', description='Minimal Delegated License Service (DLS).', version=VERSION) +db = create_engine(str(env('DATABASE', 'sqlite:///db.sqlite'))) db_init(db) -DLS_URL = str(getenv('DLS_URL', 'localhost')) -DLS_PORT = int(getenv('DLS_PORT', '443')) -SITE_KEY_XID = str(getenv('SITE_KEY_XID', '00000000-0000-0000-0000-000000000000')) -INSTANCE_REF = str(getenv('INSTANCE_REF', '00000000-0000-0000-0000-000000000000')) -INSTANCE_KEY_RSA = load_key(str(getenv('INSTANCE_KEY_RSA', join(dirname(__file__), 'cert/instance.private.pem')))) -INSTANCE_KEY_PUB = load_key(str(getenv('INSTANCE_KEY_PUB', join(dirname(__file__), 'cert/instance.public.pem')))) +DLS_URL = str(env('DLS_URL', 'localhost')) +DLS_PORT = int(env('DLS_PORT', '443')) +SITE_KEY_XID = str(env('SITE_KEY_XID', '00000000-0000-0000-0000-000000000000')) +INSTANCE_REF = str(env('INSTANCE_REF', '00000000-0000-0000-0000-000000000000')) +INSTANCE_KEY_RSA = load_key(str(env('INSTANCE_KEY_RSA', join(dirname(__file__), 'cert/instance.private.pem')))) +INSTANCE_KEY_PUB = load_key(str(env('INSTANCE_KEY_PUB', join(dirname(__file__), 'cert/instance.public.pem')))) TOKEN_EXPIRE_DELTA = relativedelta(hours=1) # days=1 -LEASE_EXPIRE_DELTA = relativedelta(days=int(getenv('LEASE_EXPIRE_DAYS', 90))) +LEASE_EXPIRE_DELTA = relativedelta(days=int(env('LEASE_EXPIRE_DAYS', 90))) -CORS_ORIGINS = getenv('CORS_ORIGINS').split(',') if (getenv('CORS_ORIGINS')) else f'https://{DLS_URL}' # todo: prevent static https +CORS_ORIGINS = env('CORS_ORIGINS').split(',') if (env('CORS_ORIGINS')) else f'https://{DLS_URL}' # todo: prevent static https jwt_encode_key = jwk.construct(INSTANCE_KEY_RSA.export_key().decode('utf-8'), algorithm=ALGORITHMS.RS256) jwt_decode_key = jwk.construct(INSTANCE_KEY_PUB.export_key().decode('utf-8'), algorithm=ALGORITHMS.RS256) diff --git a/app/util.py b/app/util.py new file mode 100644 index 0000000..0d36472 --- /dev/null +++ b/app/util.py @@ -0,0 +1,17 @@ +try: + # Crypto | Cryptodome on Debian + from Crypto.PublicKey import RSA + from Crypto.PublicKey.RSA import RsaKey +except ModuleNotFoundError: + from Cryptodome.PublicKey import RSA + from Cryptodome.PublicKey.RSA import RsaKey + + +def load_file(filename) -> bytes: + with open(filename, 'rb') as file: + content = file.read() + return content + + +def load_key(filename) -> RsaKey: + return RSA.import_key(extern_key=load_file(filename), passphrase=None) From dacfd2084fc2671d9ec2ffaf74f7db00b314e2a2 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 11:54:01 +0100 Subject: [PATCH 02/62] code styling --- .gitlab-ci.yml | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 9c02650..bbcba5d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,6 +1,20 @@ cache: key: one-key-to-rule-them-all +build:docker: + image: docker:dind + interruptible: true + stage: build + rules: + - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH + tags: [ docker ] + before_script: + - echo "COMMIT=${CI_COMMIT_SHA}" >> version.env # COMMIT=`git rev-parse HEAD` + script: + - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY + - docker build . --tag ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_BUILD_REF_NAME}:${CI_BUILD_REF} + - docker push ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_BUILD_REF_NAME}:${CI_BUILD_REF} + build:debian: # debian:bullseye-slim image: debian:bookworm-slim # just to get "python3-jose" working @@ -28,20 +42,6 @@ build:debian: paths: - build/build.deb -build:docker: - image: docker:dind - interruptible: true - stage: build - rules: - - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH - tags: [ docker ] - before_script: - - echo "COMMIT=${CI_COMMIT_SHA}" >> version.env # COMMIT=`git rev-parse HEAD` - script: - - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY - - docker build . --tag ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_BUILD_REF_NAME}:${CI_BUILD_REF} - - docker push ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_BUILD_REF_NAME}:${CI_BUILD_REF} - test: image: python:3.10-slim-bullseye stage: test @@ -113,8 +113,8 @@ deploy:debian: # doc: https://git.collinwebdesigns.de/help/user/packages/debian_repository/index.md#install-a-package image: debian:bookworm-slim stage: deploy -# rules: -# - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + # rules: + # - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH needs: - job: build:debian artifacts: true From fb858adc0c222e390671e4c1a29993a633feb937 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 12:01:57 +0100 Subject: [PATCH 03/62] README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 095f975..072546d 100644 --- a/README.md +++ b/README.md @@ -200,7 +200,7 @@ Packages are available here: Successful tested with: -- Debian 12 (Bookworm) +- Debian 12 (Bookworm) (works but not recommended because it is currently in *testing* state) - Ubuntu 22.10 (Kinetic Kudu) **Run this on your server instance** From 5af1ba106d367cc55715e72c4a2b25284e552cd2 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 12:05:56 +0100 Subject: [PATCH 04/62] .gitlab-ci.yml improvements --- .gitlab-ci.yml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bbcba5d..e2da6f7 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,6 +7,10 @@ build:docker: stage: build rules: - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH + - changes: + - Dockerfile + - requirements.txt + - app/**/* tags: [ docker ] before_script: - echo "COMMIT=${CI_COMMIT_SHA}" >> version.env # COMMIT=`git rev-parse HEAD` @@ -19,6 +23,10 @@ build:debian: # debian:bullseye-slim image: debian:bookworm-slim # just to get "python3-jose" working stage: build + rules: + - changes: + - DEBIAN/**/* + - app/**/* before_script: - apt-get update -qq && apt-get install -qq -y build-essential - chmod 0755 -R . From a7fb43e1dc81b141f81562f6f400dcab938074a0 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 12:08:13 +0100 Subject: [PATCH 05/62] .gitlab-ci.yml improvements --- .gitlab-ci.yml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e2da6f7..f8c8ab9 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,10 +7,6 @@ build:docker: stage: build rules: - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH - - changes: - - Dockerfile - - requirements.txt - - app/**/* tags: [ docker ] before_script: - echo "COMMIT=${CI_COMMIT_SHA}" >> version.env # COMMIT=`git rev-parse HEAD` @@ -23,10 +19,6 @@ build:debian: # debian:bullseye-slim image: debian:bookworm-slim # just to get "python3-jose" working stage: build - rules: - - changes: - - DEBIAN/**/* - - app/**/* before_script: - apt-get update -qq && apt-get install -qq -y build-essential - chmod 0755 -R . @@ -99,6 +91,10 @@ deploy:docker: stage: deploy rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + - changes: + - Dockerfile + - requirements.txt + - app/**/* before_script: - echo "COMMIT=${CI_COMMIT_SHA}" >> version.env - source version.env @@ -121,8 +117,11 @@ deploy:debian: # doc: https://git.collinwebdesigns.de/help/user/packages/debian_repository/index.md#install-a-package image: debian:bookworm-slim stage: deploy - # rules: - # - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + rules: + #- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + - changes: + - DEBIAN/**/* + - app/**/* needs: - job: build:debian artifacts: true From 8633190e97afac409435d5baf4efa23b0cee9ae3 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 13:45:42 +0100 Subject: [PATCH 06/62] removed todo for migrating to flask --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index 072546d..38fd4a6 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,6 @@ Only the clients need a connection to this service on configured port. ## ToDo's -- migrate from `fastapi` to `flask` - Support http mode for using external https proxy (disable uvicorn ssl for using behind proxy) ## Endpoints From 2663901988ae64f00c6857d124ce9c191ef6f1bc Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 14:30:42 +0100 Subject: [PATCH 07/62] util.py - implemented generate key method --- app/util.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/util.py b/app/util.py index 0d36472..2de1a57 100644 --- a/app/util.py +++ b/app/util.py @@ -15,3 +15,7 @@ def load_file(filename) -> bytes: def load_key(filename) -> RsaKey: return RSA.import_key(extern_key=load_file(filename), passphrase=None) + + +def generate_key() -> RsaKey: + return RSA.generate(bits=2048) From d91b81e50f3b0d85542a77e1c0aea37bb18e3542 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 14:30:54 +0100 Subject: [PATCH 08/62] improved tests --- test/main.py | 47 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 44 insertions(+), 3 deletions(-) diff --git a/test/main.py b/test/main.py index 22c1c6b..01b0a7e 100644 --- a/test/main.py +++ b/test/main.py @@ -1,9 +1,18 @@ +from base64 import b64encode as b64enc +from hashlib import sha256 +from calendar import timegm +from datetime import datetime +from os.path import dirname, join from uuid import uuid4 -from jose import jwt +from dateutil.relativedelta import relativedelta +from jose import jwt, jwk +from jose.constants import ALGORITHMS from starlette.testclient import TestClient import sys +from app.util import generate_key, load_key + # add relative path to use packages as they were in the app/ dir sys.path.append('../') sys.path.append('../app') @@ -13,6 +22,16 @@ from app import main client = TestClient(main.app) ORIGIN_REF = str(uuid4()) +SECRET = "HelloWorld" + +# INSTANCE_KEY_RSA = generate_key() +# INSTANCE_KEY_PUB = INSTANCE_KEY_RSA.public_key() + +INSTANCE_KEY_RSA = load_key(str(join(dirname(__file__), '../app/cert/instance.private.pem'))) +INSTANCE_KEY_PUB = load_key(str(join(dirname(__file__), '../app/cert/instance.public.pem'))) + +jwt_encode_key = jwk.construct(INSTANCE_KEY_RSA.export_key().decode('utf-8'), algorithm=ALGORITHMS.RS256) +jwt_decode_key = jwk.construct(INSTANCE_KEY_PUB.export_key().decode('utf-8'), algorithm=ALGORITHMS.RS256) def test_index(): @@ -54,7 +73,7 @@ def test_auth_v1_origin(): def test_auth_v1_code(): payload = { - "code_challenge": "0wmaiAMAlTIDyz4Fgt2/j0tXnGv72TYbbLs4ISRCZlY", + "code_challenge": b64enc(sha256(SECRET.encode('utf-8')).digest()).rstrip(b'=').decode('utf-8'), "origin_ref": ORIGIN_REF, } @@ -66,7 +85,29 @@ def test_auth_v1_code(): def test_auth_v1_token(): - pass + cur_time = datetime.utcnow() + access_expires_on = cur_time + relativedelta(hours=1) + + payload = { + "iat": timegm(cur_time.timetuple()), + "exp": timegm(access_expires_on.timetuple()), + "challenge": b64enc(sha256(SECRET.encode('utf-8')).digest()).rstrip(b'=').decode('utf-8'), + "origin_ref": ORIGIN_REF, + "key_ref": "00000000-0000-0000-0000-000000000000", + "kid": "00000000-0000-0000-0000-000000000000" + } + payload = { + "auth_code": jwt.encode(payload, key=jwt_encode_key, headers={'kid': payload.get('kid')}, + algorithm=ALGORITHMS.RS256), + "code_verifier": SECRET, + } + + response = client.post('/auth/v1/token', json=payload) + assert response.status_code == 200 + + token = response.json()['auth_token'] + payload = jwt.decode(token=token, key=jwt_decode_key, algorithms=ALGORITHMS.RS256, options={'verify_aud': False}) + assert payload['origin_ref'] == ORIGIN_REF def test_leasing_v1_lessor(): From 9ab0eb47965d307c66e5415f4e8a2b3f6248079f Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 14:31:11 +0100 Subject: [PATCH 09/62] .gitlab-ci.yml - added ubuntu to test:debian stage --- .gitlab-ci.yml | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f8c8ab9..0176c7c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,7 +15,7 @@ build:docker: - docker build . --tag ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_BUILD_REF_NAME}:${CI_BUILD_REF} - docker push ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_BUILD_REF_NAME}:${CI_BUILD_REF} -build:debian: +build:package: # debian:bullseye-slim image: debian:bookworm-slim # just to get "python3-jose" working stage: build @@ -57,14 +57,13 @@ test: script: - pytest main.py -test:debian: - image: debian:bookworm-slim +.test:linux: stage: test + needs: + - job: build:package + artifacts: true variables: DEBIAN_FRONTEND: noninteractive - needs: - - job: build:debian - artifacts: true before_script: - apt-get update -qq && apt-get install -qq -y jq script: @@ -87,6 +86,14 @@ test:debian: - apt-get purge -qq -y fastapi-dls - apt-get autoremove -qq -y && apt-get clean -qq +test:debian: + extends: .test:linux + image: debian:bookworm-slim + +test:ubuntu: + extends: .test:linux + image: ubuntu:22.10 + deploy:docker: stage: deploy rules: @@ -123,7 +130,7 @@ deploy:debian: - DEBIAN/**/* - app/**/* needs: - - job: build:debian + - job: build:package artifacts: true before_script: - apt-get update -qq && apt-get install -qq -y curl lsb-release From d4ca6ba1aa6775c6645005d63617253a6df23024 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 14:39:04 +0100 Subject: [PATCH 10/62] fixed imports --- test/main.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/main.py b/test/main.py index 01b0a7e..8c242aa 100644 --- a/test/main.py +++ b/test/main.py @@ -11,13 +11,12 @@ from jose.constants import ALGORITHMS from starlette.testclient import TestClient import sys -from app.util import generate_key, load_key - # add relative path to use packages as they were in the app/ dir sys.path.append('../') sys.path.append('../app') from app import main +from app.util import generate_key, load_key client = TestClient(main.app) From 837721fd7b41c7a2b09ec17c09c4bad4e1a937b7 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 14:53:17 +0100 Subject: [PATCH 11/62] finished all remaining tests --- test/main.py | 69 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 64 insertions(+), 5 deletions(-) diff --git a/test/main.py b/test/main.py index 8c242aa..34903db 100644 --- a/test/main.py +++ b/test/main.py @@ -20,7 +20,7 @@ from app.util import generate_key, load_key client = TestClient(main.app) -ORIGIN_REF = str(uuid4()) +ORIGIN_REF, LEASE_REF = str(uuid4()), str(uuid4()) SECRET = "HelloWorld" # INSTANCE_KEY_RSA = generate_key() @@ -70,6 +70,27 @@ def test_auth_v1_origin(): assert response.json()['origin_ref'] == ORIGIN_REF +def auth_v1_origin_update(): + payload = { + "registration_pending": False, + "environment": { + "guest_driver_version": "guest_driver_version", + "hostname": "myhost", + "ip_address_list": ["192.168.1.123"], + "os_version": "os_version", + "os_platform": "os_platform", + "fingerprint": {"mac_address_list": ["ff:ff:ff:ff:ff:ff"]}, + "host_driver_version": "host_driver_version" + }, + "update_pending": False, + "candidate_origin_ref": ORIGIN_REF, + } + + response = client.post('/auth/v1/origin/update', json=payload) + assert response.status_code == 200 + assert response.json()['origin_ref'] == ORIGIN_REF + + def test_auth_v1_code(): payload = { "code_challenge": b64enc(sha256(SECRET.encode('utf-8')).digest()).rstrip(b'=').decode('utf-8'), @@ -110,16 +131,54 @@ def test_auth_v1_token(): def test_leasing_v1_lessor(): - pass + payload = { + 'fulfillment_context': { + 'fulfillment_class_ref_list': [] + }, + 'lease_proposal_list': [{ + 'license_type_qualifiers': {'count': 1}, + 'product': {'name': 'NVIDIA RTX Virtual Workstation'} + }], + 'proposal_evaluation_mode': 'ALL_OF', + 'scope_ref_list': [LEASE_REF] + } + + bearer_token = jwt.encode({"origin_ref": ORIGIN_REF}, key=jwt_encode_key, algorithm=ALGORITHMS.RS256) + bearer_token = f'Bearer {bearer_token}' + response = client.post('/leasing/v1/lessor', json=payload, headers={'authorization': bearer_token}) + assert response.status_code == 200 + + lease_result_list = response.json()['lease_result_list'] + assert len(lease_result_list) == 1 + assert lease_result_list[0]['lease']['ref'] == LEASE_REF def test_leasing_v1_lessor_lease(): - pass + bearer_token = jwt.encode({"origin_ref": ORIGIN_REF}, key=jwt_encode_key, algorithm=ALGORITHMS.RS256) + bearer_token = f'Bearer {bearer_token}' + response = client.get('/leasing/v1/lessor/leases', headers={'authorization': bearer_token}) + assert response.status_code == 200 + + active_lease_list = response.json()['active_lease_list'] + assert len(active_lease_list) == 1 + assert active_lease_list[0] == LEASE_REF def test_leasing_v1_lease_renew(): - pass + bearer_token = jwt.encode({"origin_ref": ORIGIN_REF}, key=jwt_encode_key, algorithm=ALGORITHMS.RS256) + bearer_token = f'Bearer {bearer_token}' + response = client.put(f'/leasing/v1/lease/{LEASE_REF}', headers={'authorization': bearer_token}) + assert response.status_code == 200 + + assert response.json()['lease_ref'] == LEASE_REF def test_leasing_v1_lessor_lease_remove(): - pass + bearer_token = jwt.encode({"origin_ref": ORIGIN_REF}, key=jwt_encode_key, algorithm=ALGORITHMS.RS256) + bearer_token = f'Bearer {bearer_token}' + response = client.delete('/leasing/v1/lessor/leases', headers={'authorization': bearer_token}) + assert response.status_code == 200 + + released_lease_list = response.json()['released_lease_list'] + assert len(released_lease_list) == 1 + assert released_lease_list[0] == LEASE_REF From 12f661707fe25a2a4215d9b9a7c8a6560dfb0ccc Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 15:24:04 +0100 Subject: [PATCH 12/62] added PKGBUILD --- .gitlab-ci.yml | 17 +++++++++++++---- PKGBUILD | 23 +++++++++++++++++++++++ 2 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 PKGBUILD diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0176c7c..10ede8f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -15,8 +15,7 @@ build:docker: - docker build . --tag ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_BUILD_REF_NAME}:${CI_BUILD_REF} - docker push ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_BUILD_REF_NAME}:${CI_BUILD_REF} -build:package: - # debian:bullseye-slim +build:apt: image: debian:bookworm-slim # just to get "python3-jose" working stage: build before_script: @@ -42,6 +41,16 @@ build:package: paths: - build/build.deb +build:pamac: + image: archlinux:base-devel + stage: build + rules: + - if: $CI_COMMIT_BRANCH == "archlinux-makepkg" + script: + - ls -lah + - makepkg + - ls -lah + test: image: python:3.10-slim-bullseye stage: test @@ -60,7 +69,7 @@ test: .test:linux: stage: test needs: - - job: build:package + - job: build:apt artifacts: true variables: DEBIAN_FRONTEND: noninteractive @@ -130,7 +139,7 @@ deploy:debian: - DEBIAN/**/* - app/**/* needs: - - job: build:package + - job: build:apt artifacts: true before_script: - apt-get update -qq && apt-get install -qq -y curl lsb-release diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 0000000..d616130 --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,23 @@ +# Maintainer: Oscar Krause +pkgname=fastapi-dls +pkgver=1.0.0 +pkgrel=3 +pkgdesc="Minimal Delegated License Service (DLS)." +arch=('any') +url="https://git.collinwebdesigns.de/oscar.krause/fastapi-dls" +#license=('MIT') +depends=('python3' 'python-fastapi' 'uvicorn' 'python-dotenv' 'python-dateutil' 'python-jose' 'python-sqlalchemy' 'python-pycryptodome' 'python-markdown' 'openssl') +#source=("$pkgname-$pkgver.tar.gz::$url/archive/refs/tags/v$pkgver.tar.gz") +#sha256sums=('...') + +check() { + cd "$pkgname-$pkgver" + python3 "$pkgname.py" --version +} + +package() { + cd "$pkgname-$pkgver" + install -m 755 -TD "$pkgname.py" "$pkgdir/usr/bin/$pkgname" + install -m 644 -TD "README.md" "$pkgdir/usr/share/doc/$pkgname/README.md" + install -m 644 -TD "LICENSE" "$pkgdir/usr/share/licenses/$pkgname/LICENSE" +} From bb43fc3f496aabdd506e174819248a86e93010c0 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 15:27:16 +0100 Subject: [PATCH 13/62] .gitlab-ci.yml --- .gitlab-ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 10ede8f..af11941 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -48,7 +48,8 @@ build:pamac: - if: $CI_COMMIT_BRANCH == "archlinux-makepkg" script: - ls -lah - - makepkg + - makepkg --help + - makepkg -si - ls -lah test: From 321cd17b0267338642def000ea9de128a8ddbdd3 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 15:57:55 +0100 Subject: [PATCH 14/62] updated PKGBUILD --- .gitlab-ci.yml | 9 +++++++-- PKGBUILD | 22 +++++++++------------- 2 files changed, 16 insertions(+), 15 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index af11941..72fad73 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -46,11 +46,16 @@ build:pamac: stage: build rules: - if: $CI_COMMIT_BRANCH == "archlinux-makepkg" + before_script: + - useradd --no-create-home --shell=/bin/false build && usermod -L build + - 'echo "build ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers' + - 'echo "root ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers' + - chown -R build:build . script: - ls -lah - - makepkg --help - - makepkg -si + - source PKGBUILD && pacman -Syu --noconfirm --needed --asdeps "${makedepends[@]}" "${depends[@]}" - ls -lah + - sudo -u build makepkg --noextract #makepkg -si test: image: python:3.10-slim-bullseye diff --git a/PKGBUILD b/PKGBUILD index d616130..ff1757e 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -1,23 +1,19 @@ # Maintainer: Oscar Krause pkgname=fastapi-dls pkgver=1.0.0 -pkgrel=3 +pkgrel=1 pkgdesc="Minimal Delegated License Service (DLS)." -arch=('any') +arch=('any') # x86_64? url="https://git.collinwebdesigns.de/oscar.krause/fastapi-dls" #license=('MIT') depends=('python3' 'python-fastapi' 'uvicorn' 'python-dotenv' 'python-dateutil' 'python-jose' 'python-sqlalchemy' 'python-pycryptodome' 'python-markdown' 'openssl') -#source=("$pkgname-$pkgver.tar.gz::$url/archive/refs/tags/v$pkgver.tar.gz") -#sha256sums=('...') - -check() { - cd "$pkgname-$pkgver" - python3 "$pkgname.py" --version -} +source=('README.md' 'version.env' 'app/main.py' 'app/orm.py' 'app/util.py') +sha512sums=("SKIP") package() { - cd "$pkgname-$pkgver" - install -m 755 -TD "$pkgname.py" "$pkgdir/usr/bin/$pkgname" - install -m 644 -TD "README.md" "$pkgdir/usr/share/doc/$pkgname/README.md" - install -m 644 -TD "LICENSE" "$pkgdir/usr/share/licenses/$pkgname/LICENSE" + mkdir -p "${pkgdir}/usr/share" + + cp "${srcdir}/README.md" "${pkgdir}/usr/share/README.md" + cp "${srcdir}/version.env" "${pkgdir}/usr/share/version.env" + cp -r "${srcdir}/app" "${pkgdir}/usr/share" } From 32a512b89bd69a10617d4f1754cd944dfedc19f9 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 15:59:38 +0100 Subject: [PATCH 15/62] fixes --- .gitlab-ci.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 72fad73..3f7cb42 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -52,10 +52,10 @@ build:pamac: - 'echo "root ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers' - chown -R build:build . script: - - ls -lah + - pwd - source PKGBUILD && pacman -Syu --noconfirm --needed --asdeps "${makedepends[@]}" "${depends[@]}" - ls -lah - - sudo -u build makepkg --noextract #makepkg -si + - sudo -u build makepkg -si test: image: python:3.10-slim-bullseye From 62af76b95abd5b058ce464e991e12243beb85b5d Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 17:00:35 +0100 Subject: [PATCH 16/62] added PKGBUILD --- PKGBUILD | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/PKGBUILD b/PKGBUILD index ff1757e..adb3dce 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -7,13 +7,21 @@ arch=('any') # x86_64? url="https://git.collinwebdesigns.de/oscar.krause/fastapi-dls" #license=('MIT') depends=('python3' 'python-fastapi' 'uvicorn' 'python-dotenv' 'python-dateutil' 'python-jose' 'python-sqlalchemy' 'python-pycryptodome' 'python-markdown' 'openssl') -source=('README.md' 'version.env' 'app/main.py' 'app/orm.py' 'app/util.py') +source=() # 'README.md' 'version.env' 'app/main.py' 'app/orm.py' 'app/util.py' sha512sums=("SKIP") package() { mkdir -p "${pkgdir}/usr/share" + echo "pkgdir: ${pkgdir}" + echo "srcdir: ${srcdir}" + echo "startDir: ${startDir}" + cp "${srcdir}/README.md" "${pkgdir}/usr/share/README.md" cp "${srcdir}/version.env" "${pkgdir}/usr/share/version.env" cp -r "${srcdir}/app" "${pkgdir}/usr/share" } + + +# https://bbs.archlinux.org/viewtopic.php?id=213287 +# https://itsfoss.com/create-pkgbuild/ From 15d52f7586523625b788fdb56a56ab0ead988177 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 17:01:57 +0100 Subject: [PATCH 17/62] added PKGBUILD --- PKGBUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PKGBUILD b/PKGBUILD index adb3dce..07b34e9 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -7,7 +7,7 @@ arch=('any') # x86_64? url="https://git.collinwebdesigns.de/oscar.krause/fastapi-dls" #license=('MIT') depends=('python3' 'python-fastapi' 'uvicorn' 'python-dotenv' 'python-dateutil' 'python-jose' 'python-sqlalchemy' 'python-pycryptodome' 'python-markdown' 'openssl') -source=() # 'README.md' 'version.env' 'app/main.py' 'app/orm.py' 'app/util.py' +source=(".") # 'README.md' 'version.env' 'app/main.py' 'app/orm.py' 'app/util.py' sha512sums=("SKIP") package() { From 7f99c260ce01ed17b528f7b946fc845f6531843e Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 17:05:59 +0100 Subject: [PATCH 18/62] added PKGBUILD --- .gitlab-ci.yml | 5 +++-- PKGBUILD | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3f7cb42..d57937d 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -53,8 +53,9 @@ build:pamac: - chown -R build:build . script: - pwd - - source PKGBUILD && pacman -Syu --noconfirm --needed --asdeps "${makedepends[@]}" "${depends[@]}" + #- source PKGBUILD && pacman -Syu --noconfirm --needed --asdeps "${makedepends[@]}" "${depends[@]}" - ls -lah + - ls -lah app/ - sudo -u build makepkg -si test: @@ -135,7 +136,7 @@ deploy:docker: - docker push $PUBLIC_REGISTRY_USER/${CI_PROJECT_NAME}:${VERSION} - docker push $PUBLIC_REGISTRY_USER/${CI_PROJECT_NAME}:latest -deploy:debian: +deploy:apt: # doc: https://git.collinwebdesigns.de/help/user/packages/debian_repository/index.md#install-a-package image: debian:bookworm-slim stage: deploy diff --git a/PKGBUILD b/PKGBUILD index 07b34e9..1dd571c 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -7,7 +7,7 @@ arch=('any') # x86_64? url="https://git.collinwebdesigns.de/oscar.krause/fastapi-dls" #license=('MIT') depends=('python3' 'python-fastapi' 'uvicorn' 'python-dotenv' 'python-dateutil' 'python-jose' 'python-sqlalchemy' 'python-pycryptodome' 'python-markdown' 'openssl') -source=(".") # 'README.md' 'version.env' 'app/main.py' 'app/orm.py' 'app/util.py' +source=('README.md' 'version.env' 'app/main.py' 'app/orm.py' 'app/util.py') sha512sums=("SKIP") package() { From f04d4905dfd26e2458623158215545e5eea88be5 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 21:13:20 +0100 Subject: [PATCH 19/62] applied changes from samicrusader --- .gitlab-ci.yml | 6 +---- PKGBUILD | 55 ++++++++++++++++++++++++++++----------------- fastapi-dls.default | 23 +++++++++++++++++++ fastapi-dls.install | 14 ++++++++++++ fastapi-dls.service | 15 +++++++++++++ 5 files changed, 88 insertions(+), 25 deletions(-) create mode 100644 fastapi-dls.default create mode 100644 fastapi-dls.install create mode 100644 fastapi-dls.service diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index d57937d..1fde992 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -52,11 +52,7 @@ build:pamac: - 'echo "root ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers' - chown -R build:build . script: - - pwd - #- source PKGBUILD && pacman -Syu --noconfirm --needed --asdeps "${makedepends[@]}" "${depends[@]}" - - ls -lah - - ls -lah app/ - - sudo -u build makepkg -si + - sudo -u build makepkg -s test: image: python:3.10-slim-bullseye diff --git a/PKGBUILD b/PKGBUILD index 1dd571c..a70b36e 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -1,27 +1,42 @@ +# Maintainer: samicrusader # Maintainer: Oscar Krause + pkgname=fastapi-dls -pkgver=1.0.0 +pkgver=1.0 pkgrel=1 -pkgdesc="Minimal Delegated License Service (DLS)." -arch=('any') # x86_64? -url="https://git.collinwebdesigns.de/oscar.krause/fastapi-dls" -#license=('MIT') -depends=('python3' 'python-fastapi' 'uvicorn' 'python-dotenv' 'python-dateutil' 'python-jose' 'python-sqlalchemy' 'python-pycryptodome' 'python-markdown' 'openssl') -source=('README.md' 'version.env' 'app/main.py' 'app/orm.py' 'app/util.py') -sha512sums=("SKIP") +pkgdesc='NVIDIA DLS server implementation with FastAPI' +arch=('any') +url='https://git.collinwebdesigns.de/oscar.krause/fastapi-dls' +license=('MIT') +depends=('python' 'python-jose' 'python-starlette' 'python-httpx' 'python-fastapi' 'python-dotenv' 'python-dateutil' 'python-sqlalchemy' 'python-pycryptodome' 'uvicorn' 'python-markdown' 'openssl') +provider=("$pkgname") +install="$pkgname.install" +source=('git+https://git.collinwebdesigns.de/oscar.krause/fastapi-dls.git#commit=3d5203dae054020e6f56e5f457fac1fbacc6f05d' # https://gitea.publichub.eu/oscar.krause/fastapi-dls.git + "$pkgname.default" + "$pkgname.service") +sha256sums=('SKIP' + 'd8b2216b67a2f8f35ad6f07c825839794f7c34456a72caadd9fc110810348d90' + '10cb98d64f8bf37b11a60510793c187cc664e63c895d1205781c21fa2e703f32') -package() { - mkdir -p "${pkgdir}/usr/share" - - echo "pkgdir: ${pkgdir}" - echo "srcdir: ${srcdir}" - echo "startDir: ${startDir}" - - cp "${srcdir}/README.md" "${pkgdir}/usr/share/README.md" - cp "${srcdir}/version.env" "${pkgdir}/usr/share/version.env" - cp -r "${srcdir}/app" "${pkgdir}/usr/share" +check() { + cd "$srcdir/$pkgname/test" + mkdir "$srcdir/$pkgname/app/cert" + openssl genrsa -out "$srcdir/$pkgname/app/cert/instance.private.pem" 2048 + openssl rsa -in "$srcdir/$pkgname/app/cert/instance.private.pem" -outform PEM -pubout -out "$srcdir/$pkgname/app/cert/instance.public.pem" + python "$srcdir/$pkgname/test/main.py" + rm -rf "$srcdir/$pkgname/app/cert" } +package() { + install -d "$pkgdir/usr/share/doc/$pkgname" + install -d "$pkgdir/var/lib/$pkgname/cert" + cp -r "$srcdir/$pkgname/doc"/* "$pkgdir/usr/share/doc/$pkgname/" + install -Dm644 "$srcdir/$pkgname/README.md" "$pkgdir/usr/share/doc/$pkgname/README.md" -# https://bbs.archlinux.org/viewtopic.php?id=213287 -# https://itsfoss.com/create-pkgbuild/ + sed -i "s/README.md/\/usr\/share\/doc\/$pkgname\/README.md/g" "$srcdir/$pkgname/app/main.py" + sed -i "s/join(dirname(__file__), 'cert\//join('\/var\/lib\/$pkgname', 'cert\//g" "$srcdir/$pkgname/app/main.py" + install -Dm755 "$srcdir/$pkgname/app/main.py" "$pkgdir/opt/$pkgname/main.py" + install -Dm755 "$srcdir/$pkgname/app/orm.py" "$pkgdir/opt/$pkgname/orm.py" + install -Dm644 "$srcdir/$pkgname.default" "$pkgdir/etc/default/$pkgname" + install -Dm644 "$srcdir/$pkgname.service" "$pkgdir/usr/lib/systemd/system/$pkgname.service" +} diff --git a/fastapi-dls.default b/fastapi-dls.default new file mode 100644 index 0000000..079679b --- /dev/null +++ b/fastapi-dls.default @@ -0,0 +1,23 @@ +# Toggle FastAPI debug mode +DEBUG=false + +# Where the client can find the DLS server +## DLS_URL should be a hostname +DLS_URL="localhost.localdomain" +DLS_PORT=8443 +CORS_ORIGINS="https://$DLS_URL:$DLS_PORT" + +# Lease expiration in days +LEASE_EXPIRE_DAYS=90 + +# Database location +## See https://dataset.readthedocs.io/en/latest/quickstart.html for details +DATABASE="sqlite:////var/lib/fastapi-dls/db.sqlite" + +# UUIDs for identifying the instance +SITE_KEY_XID="<>" +INSTANCE_REF="<>" + +# Site-wide signing keys +INSTANCE_KEY_RSA="/var/lib/fastapi-dls/instance.private.pem" +INSTANCE_KEY_PUB="/var/lib/fastapi-dls/instance.public.pem" diff --git a/fastapi-dls.install b/fastapi-dls.install new file mode 100644 index 0000000..17ad880 --- /dev/null +++ b/fastapi-dls.install @@ -0,0 +1,14 @@ +post_install() { + sed -i "s/<>/$(uuidgen)/" /etc/default/fastapi-dls + sed -i "s/<>/$(uuidgen)/" /etc/default/fastapi-dls + + echo 'The environment variables for this server can be edited at: /etc/default/fastapi-dls' + echo 'The server can be started with: systemctl start fastapi-dls.service' + echo + echo 'A valid HTTPS certificate needs to be installed to /var/lib/fastapi-dls/cert/webserver.{crt,key}' + echo 'A self-signed certificate can be generated with: openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout /var/lib/fastapi-dls/cert/webserver.key -out /var/lib/fastapi-dls/cert/webserver.crt' + echo + echo 'The signing keys for your instance need to be generated as well. Generate them with these commands:' + echo 'openssl genrsa -out /var/lib/fastapi-dls/instance.private.pem 2048' + echo 'openssl rsa -in /var/lib/fastapi-dls/instance.private.pem -outform PEM -pubout -out /var/lib/fastapi-dls/instance.public.pem' +} diff --git a/fastapi-dls.service b/fastapi-dls.service new file mode 100644 index 0000000..1bca7b7 --- /dev/null +++ b/fastapi-dls.service @@ -0,0 +1,15 @@ +[Unit] +Description=FastAPI-DLS +Documentation=https://git.collinwebdesigns.de/oscar.krause/fastapi-dls +After=network.target + +[Service] +Type=forking +EnvironmentFile=/etc/default/fastapi-dls +ExecStart=/usr/bin/python /opt/fastapi-dls/main.py +WorkingDir=/opt/fastapi-dls +Restart=on-abort +User=root + +[Install] +WantedBy=multi-user.target From 571e654af15da0f776baab1ced9519ba068e54e4 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 21:14:14 +0100 Subject: [PATCH 20/62] fixes --- .gitlab-ci.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1fde992..ec85d6b 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -52,6 +52,9 @@ build:pamac: - 'echo "root ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers' - chown -R build:build . script: + # download dependencies + - source PKGBUILD && pacman -Syu --noconfirm --needed --asdeps "${makedepends[@]}" "${depends[@]}" + # build - sudo -u build makepkg -s test: From abb56be3bb78553b42fb383b1691bb0f992592ca Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 21:15:32 +0100 Subject: [PATCH 21/62] added git --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index ec85d6b..8ffad3e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -47,6 +47,7 @@ build:pamac: rules: - if: $CI_COMMIT_BRANCH == "archlinux-makepkg" before_script: + - pacman -Syu --noconfirm git - useradd --no-create-home --shell=/bin/false build && usermod -L build - 'echo "build ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers' - 'echo "root ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers' From 34283555a11db3839d7de494e12a51fc9819d64b Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 21:40:26 +0100 Subject: [PATCH 22/62] refactorings --- {DEBIAN => .DEBIAN}/conffiles | 0 {DEBIAN => .DEBIAN}/control | 0 {DEBIAN => .DEBIAN}/postinst | 0 {DEBIAN => .DEBIAN}/postrm | 0 {DEBIAN => .DEBIAN}/prerm | 0 .gitlab-ci.yml | 4 ++-- 6 files changed, 2 insertions(+), 2 deletions(-) rename {DEBIAN => .DEBIAN}/conffiles (100%) rename {DEBIAN => .DEBIAN}/control (100%) rename {DEBIAN => .DEBIAN}/postinst (100%) rename {DEBIAN => .DEBIAN}/postrm (100%) rename {DEBIAN => .DEBIAN}/prerm (100%) diff --git a/DEBIAN/conffiles b/.DEBIAN/conffiles similarity index 100% rename from DEBIAN/conffiles rename to .DEBIAN/conffiles diff --git a/DEBIAN/control b/.DEBIAN/control similarity index 100% rename from DEBIAN/control rename to .DEBIAN/control diff --git a/DEBIAN/postinst b/.DEBIAN/postinst similarity index 100% rename from DEBIAN/postinst rename to .DEBIAN/postinst diff --git a/DEBIAN/postrm b/.DEBIAN/postrm similarity index 100% rename from DEBIAN/postrm rename to .DEBIAN/postrm diff --git a/DEBIAN/prerm b/.DEBIAN/prerm similarity index 100% rename from DEBIAN/prerm rename to .DEBIAN/prerm diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 0176c7c..3cbaa87 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -25,7 +25,7 @@ build:package: # create build directory for .deb sources - mkdir build # copy install instructions - - cp -r DEBIAN build/ + - cp -r .DEBIAN build/DEBIAN # copy app into "/usr/share/fastapi-dls" as "/usr/share/fastapi-dls/app" & copy README.md and version.env - mkdir -p build/usr/share/fastapi-dls - cp -r app build/usr/share/fastapi-dls @@ -127,7 +127,7 @@ deploy:debian: rules: #- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - changes: - - DEBIAN/**/* + - .DEBIAN/**/* - app/**/* needs: - job: build:package From a02d1ab9dff3791df17b53abf0796119246ea954 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 21:20:19 +0100 Subject: [PATCH 23/62] .gitlab-ci.yml - handle artifact --- PKGBUILD => .PKGBUILD/PKGBUILD | 2 +- fastapi-dls.default => .PKGBUILD/fastapi-dls.default | 0 fastapi-dls.install => .PKGBUILD/fastapi-dls.install | 0 fastapi-dls.service => .PKGBUILD/fastapi-dls.service | 0 .gitlab-ci.yml | 9 ++++++++- 5 files changed, 9 insertions(+), 2 deletions(-) rename PKGBUILD => .PKGBUILD/PKGBUILD (91%) rename fastapi-dls.default => .PKGBUILD/fastapi-dls.default (100%) rename fastapi-dls.install => .PKGBUILD/fastapi-dls.install (100%) rename fastapi-dls.service => .PKGBUILD/fastapi-dls.service (100%) diff --git a/PKGBUILD b/.PKGBUILD/PKGBUILD similarity index 91% rename from PKGBUILD rename to .PKGBUILD/PKGBUILD index a70b36e..3a2fac0 100644 --- a/PKGBUILD +++ b/.PKGBUILD/PKGBUILD @@ -11,7 +11,7 @@ license=('MIT') depends=('python' 'python-jose' 'python-starlette' 'python-httpx' 'python-fastapi' 'python-dotenv' 'python-dateutil' 'python-sqlalchemy' 'python-pycryptodome' 'uvicorn' 'python-markdown' 'openssl') provider=("$pkgname") install="$pkgname.install" -source=('git+https://git.collinwebdesigns.de/oscar.krause/fastapi-dls.git#commit=3d5203dae054020e6f56e5f457fac1fbacc6f05d' # https://gitea.publichub.eu/oscar.krause/fastapi-dls.git +source=('git+file:///builds/oscar.krause/fastapi-dls' # https://gitea.publichub.eu/oscar.krause/fastapi-dls.git "$pkgname.default" "$pkgname.service") sha256sums=('SKIP' diff --git a/fastapi-dls.default b/.PKGBUILD/fastapi-dls.default similarity index 100% rename from fastapi-dls.default rename to .PKGBUILD/fastapi-dls.default diff --git a/fastapi-dls.install b/.PKGBUILD/fastapi-dls.install similarity index 100% rename from fastapi-dls.install rename to .PKGBUILD/fastapi-dls.install diff --git a/fastapi-dls.service b/.PKGBUILD/fastapi-dls.service similarity index 100% rename from fastapi-dls.service rename to .PKGBUILD/fastapi-dls.service diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8ffad3e..ebf8150 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -20,7 +20,6 @@ build:apt: stage: build before_script: - apt-get update -qq && apt-get install -qq -y build-essential - - chmod 0755 -R . # create build directory for .deb sources - mkdir build # copy install instructions @@ -48,15 +47,23 @@ build:pamac: - if: $CI_COMMIT_BRANCH == "archlinux-makepkg" before_script: - pacman -Syu --noconfirm git + # "makepkg" don't likes root user - useradd --no-create-home --shell=/bin/false build && usermod -L build - 'echo "build ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers' - 'echo "root ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers' - chown -R build:build . + # move .PKGBUILD contents to root directory + - mv .PKGBUILD/* . script: + - pwd # download dependencies - source PKGBUILD && pacman -Syu --noconfirm --needed --asdeps "${makedepends[@]}" "${depends[@]}" # build - sudo -u build makepkg -s + artifacts: + expire_in: 1 week + paths: + - "*.pkg.tar.zst" test: image: python:3.10-slim-bullseye From eddf9217e5aab8411a136b5dba7bbf27cbc504b7 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 21:52:19 +0100 Subject: [PATCH 24/62] refactorings --- .gitlab-ci.yml | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f7abf00..f0bb885 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -40,7 +40,7 @@ build:apt: paths: - build/build.deb -build:pamac: +build:pacman: image: archlinux:base-devel stage: build rules: @@ -117,6 +117,11 @@ test:ubuntu: extends: .test:linux image: ubuntu:22.10 +test:archlinux: + image: archlinux:base + script: + - echo "Todo" + deploy:docker: stage: deploy rules: @@ -186,3 +191,28 @@ deploy:apt: # using generic-package-registry until debian-registry is GA # https://docs.gitlab.com/ee/user/packages/generic_packages/index.html#publish-a-generic-package-by-using-cicd - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${EXPORT_NAME} "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${PACKAGE_NAME}/${PACKAGE_VERSION}/${EXPORT_NAME}"' + +deploy:pacman: + image: archlinux:base-devel + stage: deploy + rules: + #- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + - changes: + - .PKGBUILD/**/* + - app/**/* + needs: + - job: build:pacman + artifacts: true + script: + - source .PKGBUILD/PKGBUILD + # fastapi-dls-1.0-1-any.pkg.tar.zst + - BUILD_NAME=${pkgname}-${pkgver}-${pkgrel}-any.pkg.tar.zst + - PACKAGE_NAME=${pkgname} + - PACKAGE_VERSION=${pkgver} + - PACKAGE_ARCH=any + - EXPORT_NAME=${BUILD_NAME} + - 'echo "PACKAGE_NAME: ${PACKAGE_NAME}"' + - 'echo "PACKAGE_VERSION: ${PACKAGE_VERSION}"' + - 'echo "PACKAGE_ARCH: ${PACKAGE_ARCH}"' + - 'echo "EXPORT_NAME: ${EXPORT_NAME}"' + - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${EXPORT_NAME} "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${PACKAGE_NAME}/${PACKAGE_VERSION}/${EXPORT_NAME}"' From 478dc04787f9427238f4560c709b5515ff3bf584 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 21:53:11 +0100 Subject: [PATCH 25/62] testing "deploy:pacman" job --- .gitlab-ci.yml | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f0bb885..b4b696c 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,8 +43,6 @@ build:apt: build:pacman: image: archlinux:base-devel stage: build - rules: - - if: $CI_COMMIT_BRANCH == "archlinux-makepkg" before_script: - pacman -Syu --noconfirm git # "makepkg" don't likes root user @@ -195,11 +193,11 @@ deploy:apt: deploy:pacman: image: archlinux:base-devel stage: deploy - rules: - #- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - - changes: - - .PKGBUILD/**/* - - app/**/* +# rules: +# - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH +# - changes: +# - .PKGBUILD/**/* +# - app/**/* needs: - job: build:pacman artifacts: true From b5ed098093335aab55e549475ec1999967f81a47 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 21:59:48 +0100 Subject: [PATCH 26/62] fixed debian install scripts permissions --- .gitlab-ci.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b4b696c..c86ee07 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,6 +24,7 @@ build:apt: - mkdir build # copy install instructions - cp -r .DEBIAN build/DEBIAN + - chown -R 0775 build/DEBIAN # copy app into "/usr/share/fastapi-dls" as "/usr/share/fastapi-dls/app" & copy README.md and version.env - mkdir -p build/usr/share/fastapi-dls - cp -r app build/usr/share/fastapi-dls From 3c4fb35498889fedf50b699362c7090dea655450 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 22:01:20 +0100 Subject: [PATCH 27/62] pacman - test version x.y.z instead of x.y --- .PKGBUILD/PKGBUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.PKGBUILD/PKGBUILD b/.PKGBUILD/PKGBUILD index 3a2fac0..1a4655a 100644 --- a/.PKGBUILD/PKGBUILD +++ b/.PKGBUILD/PKGBUILD @@ -2,7 +2,7 @@ # Maintainer: Oscar Krause pkgname=fastapi-dls -pkgver=1.0 +pkgver=1.0.0 pkgrel=1 pkgdesc='NVIDIA DLS server implementation with FastAPI' arch=('any') From 21e61796ff9f39d934121f91e43661e63420d8fc Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Wed, 28 Dec 2022 22:02:12 +0100 Subject: [PATCH 28/62] fixes --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c86ee07..478bf55 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -24,7 +24,7 @@ build:apt: - mkdir build # copy install instructions - cp -r .DEBIAN build/DEBIAN - - chown -R 0775 build/DEBIAN + - chmod -R 0775 build/DEBIAN # copy app into "/usr/share/fastapi-dls" as "/usr/share/fastapi-dls/app" & copy README.md and version.env - mkdir -p build/usr/share/fastapi-dls - cp -r app build/usr/share/fastapi-dls From 6978ba4873defa9353b9786baa129a9ff6b4a910 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 07:09:39 +0100 Subject: [PATCH 29/62] orm.py - timestamps are not updated in database --- app/orm.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/app/orm.py b/app/orm.py index 697c720..dc38e37 100644 --- a/app/orm.py +++ b/app/orm.py @@ -28,7 +28,7 @@ class Origin(Base): @staticmethod def create_or_update(engine: Engine, origin: "Origin"): - session = sessionmaker(autocommit=True, autoflush=True, bind=engine)() + session = sessionmaker(bind=engine)() entity = session.query(Origin).filter(Origin.origin_ref == origin.origin_ref).first() print(entity) if entity is None: @@ -41,6 +41,7 @@ class Origin(Base): os_version=origin.os_version, ) session.execute(update(Origin).where(Origin.origin_ref == origin.origin_ref).values(**values)) + session.commit() session.flush() session.close() @@ -65,7 +66,7 @@ class Lease(Base): @staticmethod def create_or_update(engine: Engine, lease: "Lease"): - session = sessionmaker(autocommit=True, autoflush=True, bind=engine)() + session = sessionmaker(bind=engine)() entity = session.query(Lease).filter(and_(Lease.origin_ref == lease.origin_ref, Lease.lease_ref == lease.lease_ref)).first() if entity is None: if lease.lease_updated is None: @@ -74,34 +75,37 @@ class Lease(Base): else: values = dict(lease_expires=lease.lease_expires, lease_updated=lease.lease_updated) session.execute(update(Lease).where(and_(Lease.origin_ref == lease.origin_ref, Lease.lease_ref == lease.lease_ref)).values(**values)) + session.commit() session.flush() session.close() @staticmethod def find_by_origin_ref(engine: Engine, origin_ref: str) -> ["Lease"]: - session = sessionmaker(autocommit=True, autoflush=True, bind=engine)() + session = sessionmaker(bind=engine)() entities = session.query(Lease).filter(Lease.origin_ref == origin_ref).all() session.close() return entities @staticmethod def find_by_origin_ref_and_lease_ref(engine: Engine, origin_ref: str, lease_ref: str) -> "Lease": - session = sessionmaker(autocommit=True, autoflush=True, bind=engine)() + session = sessionmaker(bind=engine)() entity = session.query(Lease).filter(and_(Lease.origin_ref == origin_ref, Lease.lease_ref == lease_ref)).first() session.close() return entity @staticmethod def renew(engine: Engine, lease: "Lease", lease_expires: datetime.datetime, lease_updated: datetime.datetime): - session = sessionmaker(autocommit=True, autoflush=True, bind=engine)() + session = sessionmaker(bind=engine)() values = dict(lease_expires=lease.lease_expires, lease_updated=lease.lease_updated) session.execute(update(Lease).where(and_(Lease.origin_ref == lease.origin_ref, Lease.lease_ref == lease.lease_ref)).values(**values)) + session.commit() session.close() @staticmethod def cleanup(engine: Engine, origin_ref: str) -> int: - session = sessionmaker(autocommit=True, autoflush=True, bind=engine)() + session = sessionmaker(bind=engine)() deletions = session.query(Lease).filter(Lease.origin_ref == origin_ref).delete() + session.commit() session.close() return deletions @@ -113,4 +117,5 @@ def init(engine: Engine): for table in tables: if not db.dialect.has_table(engine.connect(), table.__tablename__): session.execute(str(table.create_statement(engine))) + session.commit() session.close() From 7abfb9684114a20b0a76b371058dbb5cda7c47f7 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 07:17:51 +0100 Subject: [PATCH 30/62] README.md - added archlinux section --- README.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/README.md b/README.md index 38fd4a6..6e06e8b 100644 --- a/README.md +++ b/README.md @@ -217,6 +217,21 @@ apt-get install -f --fix-missing Start with `systemctl start fastapi-dls.service` and enable autostart with `systemctl enable fastapi-dls.service`. +## ArchLinux (using `pacman`) + +Packages are available here: + +- [GitLab-Registry](https://git.collinwebdesigns.de/oscar.krause/fastapi-dls/-/packages) + +```shell +pacman -Sy +FILENAME=/opt/fastapi-dls.pkg.tar.zst +url -o $FILENAME +pacman -U --noconfirm fastapi-dls.pkg.tar.zst +``` + +Start with `systemctl start fastapi-dls.service` and enable autostart with `systemctl enable fastapi-dls.service`. + ## Let's Encrypt Certificate If you're using installation via docker, you can use `traefik`. Please refer to their documentation. From aa76ba565036170de8f8802a74eb09a81f3bebb9 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 07:32:12 +0100 Subject: [PATCH 31/62] .gitlab-ci.yml improvements --- .gitlab-ci.yml | 38 ++++++++++++++++++++++++++++---------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 478bf55..4ca8a08 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -16,9 +16,14 @@ build:docker: - docker push ${CI_REGISTRY}/${CI_PROJECT_PATH}/${CI_BUILD_REF_NAME}:${CI_BUILD_REF} build:apt: - image: debian:bookworm-slim # just to get "python3-jose" working + image: debian:bookworm-slim + interruptible: true stage: build + rules: + - if: $CI_COMMIT_BRANCH before_script: + - echo "COMMIT=${CI_COMMIT_SHA}" >> version.env + # install build dependencies - apt-get update -qq && apt-get install -qq -y build-essential # create build directory for .deb sources - mkdir build @@ -43,10 +48,15 @@ build:apt: build:pacman: image: archlinux:base-devel + interruptible: true stage: build + rules: + - if: $CI_COMMIT_BRANCH before_script: + - echo "COMMIT=${CI_COMMIT_SHA}" >> version.env + # install build dependencies - pacman -Syu --noconfirm git - # "makepkg" don't likes root user + # create a build-user because "makepkg" don't like root user - useradd --no-create-home --shell=/bin/false build && usermod -L build - 'echo "build ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers' - 'echo "root ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers' @@ -67,6 +77,9 @@ build:pacman: test: image: python:3.10-slim-bullseye stage: test + rules: + - if: $CI_COMMIT_BRANCH + - if: $CI_PIPELINE_SOURCE == "merge_request_event" variables: DATABASE: sqlite:///../app/db.sqlite before_script: @@ -87,13 +100,14 @@ test: variables: DEBIAN_FRONTEND: noninteractive before_script: - - apt-get update -qq && apt-get install -qq -y jq + - apt-get update -qq && apt-get install -qq -y jq curl script: # test installation - apt-get install -q -y ./build/build.deb --fix-missing # copy example config from GitLab-CI-Variables #- cat ${EXAMPLE_CONFIG} > /etc/fastapi-dls/env # start service in background + - cd /usr/share/fastapi-dls/app - uvicorn --host 127.0.0.1 --port 443 --app-dir /usr/share/fastapi-dls/app --ssl-keyfile /etc/fastapi-dls/webserver.key @@ -118,8 +132,12 @@ test:ubuntu: test:archlinux: image: archlinux:base + needs: + - job: build:pacman + artifacts: true script: - - echo "Todo" + - pacman -Sy + - pacman -U --noconfirm fastapi-dls-*.pkg.tar.zs deploy:docker: stage: deploy @@ -152,7 +170,7 @@ deploy:apt: image: debian:bookworm-slim stage: deploy rules: - #- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - changes: - .DEBIAN/**/* - app/**/* @@ -194,11 +212,11 @@ deploy:apt: deploy:pacman: image: archlinux:base-devel stage: deploy -# rules: -# - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH -# - changes: -# - .PKGBUILD/**/* -# - app/**/* + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + # - changes: + # - .PKGBUILD/**/* + # - app/**/* needs: - job: build:pacman artifacts: true From a6ac58d12ce8434db75ecc0f72d2ec52605c833b Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 07:37:17 +0100 Subject: [PATCH 32/62] fixes --- .gitlab-ci.yml | 2 +- app/main.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 4ca8a08..eaa0c35 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -137,7 +137,7 @@ test:archlinux: artifacts: true script: - pacman -Sy - - pacman -U --noconfirm fastapi-dls-*.pkg.tar.zs + - pacman -U --noconfirm *.pkg.tar.zs deploy:docker: stage: deploy diff --git a/app/main.py b/app/main.py index 4eb1d4e..e92c70c 100644 --- a/app/main.py +++ b/app/main.py @@ -20,7 +20,7 @@ from starlette.responses import StreamingResponse, JSONResponse, HTMLResponse from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker -from app.util import load_key, load_file +from util import load_key, load_file from orm import Origin, Lease, init as db_init logger = logging.getLogger() From d73221afb7ebd23e8fe206bc8a4da1f3493aca04 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 07:40:43 +0100 Subject: [PATCH 33/62] bump version to 1.0 --- .DEBIAN/control | 2 +- .PKGBUILD/PKGBUILD | 2 +- version.env | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.DEBIAN/control b/.DEBIAN/control index 01db5e9..d5054a8 100644 --- a/.DEBIAN/control +++ b/.DEBIAN/control @@ -1,5 +1,5 @@ Package: fastapi-dls -Version: 1.0.0 +Version: 1.0 Architecture: all Maintainer: Oscar Krause oscar.krause@collinwebdesigns.de Depends: python3, python3-fastapi, python3-uvicorn, python3-dotenv, python3-dateutil, python3-jose, python3-sqlalchemy, python3-pycryptodome, python3-markdown, uvicorn, openssl diff --git a/.PKGBUILD/PKGBUILD b/.PKGBUILD/PKGBUILD index 1a4655a..3a2fac0 100644 --- a/.PKGBUILD/PKGBUILD +++ b/.PKGBUILD/PKGBUILD @@ -2,7 +2,7 @@ # Maintainer: Oscar Krause pkgname=fastapi-dls -pkgver=1.0.0 +pkgver=1.0 pkgrel=1 pkgdesc='NVIDIA DLS server implementation with FastAPI' arch=('any') diff --git a/version.env b/version.env index 624bade..d53e27c 100644 --- a/version.env +++ b/version.env @@ -1 +1 @@ -VERSION=1.0.0 +VERSION=1.0 From 76f732adb636c86e15fc99fc98c90b0d2ac8074c Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 07:43:16 +0100 Subject: [PATCH 34/62] .gitlab-ci.yml - fixed test:debian --- .gitlab-ci.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index eaa0c35..6445bd4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -104,14 +104,16 @@ test: script: # test installation - apt-get install -q -y ./build/build.deb --fix-missing + - openssl req -x509 -newkey rsa:2048 -nodes -out /etc/fastapi-dls/webserver.crt -keyout /etc/fastapi-dls/webserver.key -days 7 -subj "/C=DE/O=GitLab-CI/OU=Test/CN=localhost" # copy example config from GitLab-CI-Variables #- cat ${EXAMPLE_CONFIG} > /etc/fastapi-dls/env # start service in background - cd /usr/share/fastapi-dls/app - - uvicorn --host 127.0.0.1 --port 443 + - uvicorn main:app + --host 127.0.0.1 --port 443 --app-dir /usr/share/fastapi-dls/app --ssl-keyfile /etc/fastapi-dls/webserver.key - --ssl-certfile /opt/fastapi-dls/webserver.crt + --ssl-certfile /etc/fastapi-dls/webserver.crt --proxy-headers & - FASTAPI_DLS_PID=$! - echo "Started service with pid $FASTAPI_DLS_PID" @@ -132,6 +134,10 @@ test:ubuntu: test:archlinux: image: archlinux:base + rules: + - changes: + - .PKGBUILD/**/* + - app/**/* needs: - job: build:pacman artifacts: true @@ -171,9 +177,6 @@ deploy:apt: stage: deploy rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - - changes: - - .DEBIAN/**/* - - app/**/* needs: - job: build:apt artifacts: true @@ -212,14 +215,11 @@ deploy:apt: deploy:pacman: image: archlinux:base-devel stage: deploy - rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - # - changes: - # - .PKGBUILD/**/* - # - app/**/* needs: - job: build:pacman artifacts: true + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH script: - source .PKGBUILD/PKGBUILD # fastapi-dls-1.0-1-any.pkg.tar.zst From 5c1d291fac8fe818c76aeca99f64d73befb5e902 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 08:00:34 +0100 Subject: [PATCH 35/62] .gitlab-ci.yml improvements --- .gitlab-ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 6445bd4..cc50ffd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -94,6 +94,10 @@ test: .test:linux: stage: test + rules: + - changes: + - .DEBIAN/**/* + - app/**/* needs: - job: build:apt artifacts: true From 913da290f1ede26fb3098f2f61a5a60d64bec00e Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 08:48:34 +0100 Subject: [PATCH 36/62] PKGBUILD - fixed missing util.py --- .PKGBUILD/PKGBUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/.PKGBUILD/PKGBUILD b/.PKGBUILD/PKGBUILD index 3a2fac0..f3e1a70 100644 --- a/.PKGBUILD/PKGBUILD +++ b/.PKGBUILD/PKGBUILD @@ -37,6 +37,7 @@ package() { sed -i "s/join(dirname(__file__), 'cert\//join('\/var\/lib\/$pkgname', 'cert\//g" "$srcdir/$pkgname/app/main.py" install -Dm755 "$srcdir/$pkgname/app/main.py" "$pkgdir/opt/$pkgname/main.py" install -Dm755 "$srcdir/$pkgname/app/orm.py" "$pkgdir/opt/$pkgname/orm.py" + install -Dm755 "$srcdir/$pkgname/app/util.py" "$pkgdir/opt/$pkgname/util.py" install -Dm644 "$srcdir/$pkgname.default" "$pkgdir/etc/default/$pkgname" install -Dm644 "$srcdir/$pkgname.service" "$pkgdir/usr/lib/systemd/system/$pkgname.service" } From 6b2e6bf392f76e0d52aed511f03a16c6862459b4 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 09:00:52 +0100 Subject: [PATCH 37/62] added optional query parameter to '/-/origins' and '/-/leases' for linked leases/origin --- README.md | 12 ++++++++++-- app/main.py | 19 +++++++++++++++---- app/orm.py | 18 ++++++++++++++++++ 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6e06e8b..06f5691 100644 --- a/README.md +++ b/README.md @@ -25,14 +25,22 @@ Status endpoint, used for *healthcheck*. Shows also current version and commit h OpenAPI specifications rendered from `GET /openapi.json`. -### `GET /-/origins` +### `GET /-/origins?leases=false` List registered origins. -### `GET /-/leases` +| Query Parameter | Default | Usage | +|-----------------|---------|--------------------------------------| +| `leases` | `false` | Include referenced leases per origin | + +### `GET /-/leases?origin=false` List current leases. +| Query Parameter | Default | Usage | +|-----------------|---------|-------------------------------------| +| `origin` | `false` | Include referenced origin per lease | + ### `GET /client-token` Generate client token, (see [installation](#installation)). diff --git a/app/main.py b/app/main.py index e92c70c..646feaf 100644 --- a/app/main.py +++ b/app/main.py @@ -77,17 +77,28 @@ async def status(request: Request): @app.get('/-/origins') -async def _origins(request: Request): +async def _origins(request: Request, leases: bool = False): session = sessionmaker(bind=db)() - response = list(map(lambda x: jsonable_encoder(x), session.query(Origin).all())) + response = [] + for origin in session.query(Origin).all(): + x = origin.serialize() + if leases: + x['leases'] = list(map(lambda _: _.serialize(), Lease.find_by_origin_ref(db, origin.origin_ref))) + response.append(x) session.close() return JSONResponse(response) @app.get('/-/leases') -async def _leases(request: Request): +async def _leases(request: Request, origin: bool = False): session = sessionmaker(bind=db)() - response = list(map(lambda x: jsonable_encoder(x), session.query(Lease).all())) + response = [] + for lease in session.query(Lease).all(): + x = lease.serialize() + if origin: + # assume that each lease has a valid origin record + x['origin'] = session.query(Origin).filter(Origin.origin_ref == lease.origin_ref).first().serialize() + response.append(x) session.close() return JSONResponse(response) diff --git a/app/orm.py b/app/orm.py index dc38e37..c451b29 100644 --- a/app/orm.py +++ b/app/orm.py @@ -21,6 +21,15 @@ class Origin(Base): def __repr__(self): return f'Origin(origin_ref={self.origin_ref}, hostname={self.hostname})' + def serialize(self) -> dict: + return { + 'origin_ref': self.origin_ref, + 'hostname': self.hostname, + 'guest_driver_version': self.guest_driver_version, + 'os_platform': self.os_platform, + 'os_version': self.os_version, + } + @staticmethod def create_statement(engine: Engine): from sqlalchemy.schema import CreateTable @@ -59,6 +68,15 @@ class Lease(Base): def __repr__(self): return f'Lease(origin_ref={self.origin_ref}, lease_ref={self.lease_ref}, expires={self.lease_expires})' + def serialize(self) -> dict: + return { + 'lease_ref': self.lease_ref, + 'origin_ref': self.origin_ref, + 'lease_created': self.lease_created.isoformat(), + 'lease_expires': self.lease_expires.isoformat(), + 'lease_updated': self.lease_updated.isoformat(), + } + @staticmethod def create_statement(engine: Engine): from sqlalchemy.schema import CreateTable From d86948aee275fe1cc81b529f040e0bcf967b2720 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 09:01:36 +0100 Subject: [PATCH 38/62] added some comments --- app/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/main.py b/app/main.py index 646feaf..95b8baa 100644 --- a/app/main.py +++ b/app/main.py @@ -117,7 +117,7 @@ async def client_token(): "nbf": timegm(cur_time.timetuple()), "exp": timegm(exp_time.timetuple()), "update_mode": "ABSOLUTE", - "scope_ref_list": [str(uuid4())], + "scope_ref_list": [str(uuid4())], # this is our LEASE_REF "fulfillment_class_ref_list": [], "service_instance_configuration": { "nls_service_instance_ref": INSTANCE_REF, From 07de2401d7339bd6cfb45c9fcb27c69512313fd6 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 09:06:41 +0100 Subject: [PATCH 39/62] REAMDE.md - added shout out to @samicrusader --- CODEOWNERS | 2 ++ README.md | 2 ++ 2 files changed, 4 insertions(+) create mode 100755 CODEOWNERS diff --git a/CODEOWNERS b/CODEOWNERS new file mode 100755 index 0000000..a08572f --- /dev/null +++ b/CODEOWNERS @@ -0,0 +1,2 @@ +* @oscar.krause +.PKGBUILD/ @samicrusader diff --git a/README.md b/README.md index 06f5691..17c031a 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,8 @@ Start with `systemctl start fastapi-dls.service` and enable autostart with `syst ## ArchLinux (using `pacman`) +**Shout out to `samicrusader` who created build file for ArchLinux!** + Packages are available here: - [GitLab-Registry](https://git.collinwebdesigns.de/oscar.krause/fastapi-dls/-/packages) From d57b494779ead1070ccf0093361f6ff14607bc8b Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 09:12:30 +0100 Subject: [PATCH 40/62] CODEOWNERS --- CODEOWNERS | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CODEOWNERS b/CODEOWNERS index a08572f..dd20f95 100755 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,2 +1,3 @@ -* @oscar.krause +!.PKGBUILD/ @oscar.krause + .PKGBUILD/ @samicrusader From e6790588ef5f098918f91aa6cabab95b51e43c4b Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 09:12:56 +0100 Subject: [PATCH 41/62] Revert "CODEOWNERS" This reverts commit d57b494779ead1070ccf0093361f6ff14607bc8b. --- CODEOWNERS | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index dd20f95..a08572f 100755 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,3 +1,2 @@ -!.PKGBUILD/ @oscar.krause - +* @oscar.krause .PKGBUILD/ @samicrusader From 001b70b89cf1320a8fb6bbe6381aded337939778 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 09:15:12 +0100 Subject: [PATCH 42/62] README.md - added credits --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index 17c031a..3c05ed8 100644 --- a/README.md +++ b/README.md @@ -400,3 +400,11 @@ Dec 20 17:53:34 ubuntu-grid-server nvidia-gridd[10354]: License acquired success ``` + + +# Credits + +Thanks to vGPU community and all who uses this project and report bugs. + +Special thanks to @samicrusader who created build file for ArchLinux. + From a7cb6a7756014ffa187e93d39696e618555d11f2 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 09:15:33 +0100 Subject: [PATCH 43/62] PKGBUILD - include version file --- .PKGBUILD/PKGBUILD | 1 + 1 file changed, 1 insertion(+) diff --git a/.PKGBUILD/PKGBUILD b/.PKGBUILD/PKGBUILD index f3e1a70..d3659b7 100644 --- a/.PKGBUILD/PKGBUILD +++ b/.PKGBUILD/PKGBUILD @@ -32,6 +32,7 @@ package() { install -d "$pkgdir/var/lib/$pkgname/cert" cp -r "$srcdir/$pkgname/doc"/* "$pkgdir/usr/share/doc/$pkgname/" install -Dm644 "$srcdir/$pkgname/README.md" "$pkgdir/usr/share/doc/$pkgname/README.md" + install -Dm644 "$srcdir/$pkgname/version.env" "$pkgdir/usr/share/doc/$pkgname/version.env" sed -i "s/README.md/\/usr\/share\/doc\/$pkgname\/README.md/g" "$srcdir/$pkgname/app/main.py" sed -i "s/join(dirname(__file__), 'cert\//join('\/var\/lib\/$pkgname', 'cert\//g" "$srcdir/$pkgname/app/main.py" From 1a50e2820239173247db65f481a1e8268f9413cf Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 09:15:51 +0100 Subject: [PATCH 44/62] main.py - removed unused import --- app/main.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/main.py b/app/main.py index 95b8baa..540aace 100644 --- a/app/main.py +++ b/app/main.py @@ -8,7 +8,6 @@ from os import getenv as env from dotenv import load_dotenv from fastapi import FastAPI, HTTPException from fastapi.requests import Request -from fastapi.encoders import jsonable_encoder import json from datetime import datetime from dateutil.relativedelta import relativedelta From 922dc9f5a7a4f4a3204d865fb9e413b18d9ba6ad Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 09:40:36 +0100 Subject: [PATCH 45/62] refactored database structure and created migration script --- app/main.py | 4 ++-- app/orm.py | 35 +++++++++++++++++++++++++---------- 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/app/main.py b/app/main.py index 540aace..a50ed45 100644 --- a/app/main.py +++ b/app/main.py @@ -20,7 +20,7 @@ from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker from util import load_key, load_file -from orm import Origin, Lease, init as db_init +from orm import Origin, Lease, init as db_init, migrate logger = logging.getLogger() load_dotenv('../version.env') @@ -29,7 +29,7 @@ VERSION, COMMIT, DEBUG = env('VERSION', 'unknown'), env('COMMIT', 'unknown'), bo app = FastAPI(title='FastAPI-DLS', description='Minimal Delegated License Service (DLS).', version=VERSION) db = create_engine(str(env('DATABASE', 'sqlite:///db.sqlite'))) -db_init(db) +db_init(db), migrate(db) DLS_URL = str(env('DLS_URL', 'localhost')) DLS_PORT = int(env('DLS_PORT', '443')) diff --git a/app/orm.py b/app/orm.py index c451b29..aa3ba47 100644 --- a/app/orm.py +++ b/app/orm.py @@ -1,6 +1,6 @@ import datetime -from sqlalchemy import Column, VARCHAR, CHAR, ForeignKey, DATETIME, UniqueConstraint, update, and_, delete, inspect +from sqlalchemy import Column, VARCHAR, CHAR, ForeignKey, DATETIME, update, and_, inspect from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.engine import Engine from sqlalchemy.orm import sessionmaker @@ -43,13 +43,13 @@ class Origin(Base): if entity is None: session.add(origin) else: - values = dict( + x = dict( hostname=origin.hostname, guest_driver_version=origin.guest_driver_version, os_platform=origin.os_platform, - os_version=origin.os_version, + os_version=origin.os_version ) - session.execute(update(Origin).where(Origin.origin_ref == origin.origin_ref).values(**values)) + session.execute(update(Origin).where(Origin.origin_ref == origin.origin_ref).values(**x)) session.commit() session.flush() session.close() @@ -58,9 +58,9 @@ class Origin(Base): class Lease(Base): __tablename__ = "lease" - origin_ref = Column(CHAR(length=36), ForeignKey(Origin.origin_ref), primary_key=True, nullable=False, index=True) # uuid4 lease_ref = Column(CHAR(length=36), primary_key=True, nullable=False, index=True) # uuid4 + origin_ref = Column(CHAR(length=36), ForeignKey(Origin.origin_ref), nullable=False, index=True) # uuid4 lease_created = Column(DATETIME(), nullable=False) lease_expires = Column(DATETIME(), nullable=False) lease_updated = Column(DATETIME(), nullable=False) @@ -85,14 +85,14 @@ class Lease(Base): @staticmethod def create_or_update(engine: Engine, lease: "Lease"): session = sessionmaker(bind=engine)() - entity = session.query(Lease).filter(and_(Lease.origin_ref == lease.origin_ref, Lease.lease_ref == lease.lease_ref)).first() + entity = session.query(Lease).filter(Lease.lease_ref == lease.lease_ref).first() if entity is None: if lease.lease_updated is None: lease.lease_updated = lease.lease_created session.add(lease) else: - values = dict(lease_expires=lease.lease_expires, lease_updated=lease.lease_updated) - session.execute(update(Lease).where(and_(Lease.origin_ref == lease.origin_ref, Lease.lease_ref == lease.lease_ref)).values(**values)) + x = dict(origin_ref=lease.origin_ref, lease_expires=lease.lease_expires, lease_updated=lease.lease_updated) + session.execute(update(Lease).where(Lease.lease_ref == lease.lease_ref).values(**x)) session.commit() session.flush() session.close() @@ -114,8 +114,8 @@ class Lease(Base): @staticmethod def renew(engine: Engine, lease: "Lease", lease_expires: datetime.datetime, lease_updated: datetime.datetime): session = sessionmaker(bind=engine)() - values = dict(lease_expires=lease.lease_expires, lease_updated=lease.lease_updated) - session.execute(update(Lease).where(and_(Lease.origin_ref == lease.origin_ref, Lease.lease_ref == lease.lease_ref)).values(**values)) + x = dict(lease_expires=lease.lease_expires, lease_updated=lease.lease_updated) + session.execute(update(Lease).where(and_(Lease.origin_ref == lease.origin_ref, Lease.lease_ref == lease.lease_ref)).values(**x)) session.commit() session.close() @@ -137,3 +137,18 @@ def init(engine: Engine): session.execute(str(table.create_statement(engine))) session.commit() session.close() + + +def migrate(engine: Engine): + db = inspect(engine) + + def upgrade_1_0_to_1_1(): + x = db.dialect.get_columns(engine.connect(), Lease.__tablename__) + x = next(_ for _ in x if _['name'] == 'origin_ref') + if x['primary_key'] > 0: + print('Found old database schema with "origin_ref" as primary-key in "lease" table. Dropping table!') + print(' Your leases are recreated on next renewal!') + print(' If an error message appears on the client, you can ignore it.') + Lease.__table__.drop(bind=engine) + + upgrade_1_0_to_1_1() From 2b7fed338116dfc9aa8ce2207df80b9ef56f1b25 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 09:57:37 +0100 Subject: [PATCH 46/62] created endpoints to delete origins and to delete a lease --- README.md | 8 ++++++++ app/main.py | 15 ++++++++++++++- app/orm.py | 21 ++++++++++++++++++++- 3 files changed, 42 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3c05ed8..be9cc41 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,10 @@ List registered origins. |-----------------|---------|--------------------------------------| | `leases` | `false` | Include referenced leases per origin | +### `DELETE /-/origins` + +Deletes all origins and their leases. + ### `GET /-/leases?origin=false` List current leases. @@ -41,6 +45,10 @@ List current leases. |-----------------|---------|-------------------------------------| | `origin` | `false` | Include referenced origin per lease | +### `DELETE /-/lease/{lease_ref}` + +Deletes an lease. + ### `GET /client-token` Generate client token, (see [installation](#installation)). diff --git a/app/main.py b/app/main.py index a50ed45..586c0c1 100644 --- a/app/main.py +++ b/app/main.py @@ -15,7 +15,7 @@ from calendar import timegm from jose import jws, jwk, jwt from jose.constants import ALGORITHMS from starlette.middleware.cors import CORSMiddleware -from starlette.responses import StreamingResponse, JSONResponse, HTMLResponse +from starlette.responses import StreamingResponse, JSONResponse, HTMLResponse, Response from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker @@ -88,6 +88,12 @@ async def _origins(request: Request, leases: bool = False): return JSONResponse(response) +@app.delete('/-/origins') +async def _origins_delete(request: Request): + Origin.delete(db) + return Response(status_code=201) + + @app.get('/-/leases') async def _leases(request: Request, origin: bool = False): session = sessionmaker(bind=db)() @@ -102,6 +108,13 @@ async def _leases(request: Request, origin: bool = False): return JSONResponse(response) +@app.delete('/-/lease/{lease_ref}') +async def _lease_delete(request: Request, lease_ref: str): + if Lease.delete(db, lease_ref) == 1: + return Response(status_code=201) + raise HTTPException(status_code=404, detail='lease not found') + + # venv/lib/python3.9/site-packages/nls_core_service_instance/service_instance_token_manager.py @app.get('/client-token') async def client_token(): diff --git a/app/orm.py b/app/orm.py index aa3ba47..77cd8fc 100644 --- a/app/orm.py +++ b/app/orm.py @@ -54,13 +54,24 @@ class Origin(Base): session.flush() session.close() + @staticmethod + def delete(engine: Engine, origins: ["Origin"] = None) -> int: + session = sessionmaker(bind=engine)() + if origins is None: + deletions = session.query(Origin).delete() + else: + deletions = session.query(Origin).filter(Origin.origin_ref in origins).delete() + session.commit() + session.close() + return deletions + class Lease(Base): __tablename__ = "lease" lease_ref = Column(CHAR(length=36), primary_key=True, nullable=False, index=True) # uuid4 - origin_ref = Column(CHAR(length=36), ForeignKey(Origin.origin_ref), nullable=False, index=True) # uuid4 + origin_ref = Column(CHAR(length=36), ForeignKey(Origin.origin_ref, ondelete='CASCADE'), nullable=False, index=True) # uuid4 lease_created = Column(DATETIME(), nullable=False) lease_expires = Column(DATETIME(), nullable=False) lease_updated = Column(DATETIME(), nullable=False) @@ -127,6 +138,14 @@ class Lease(Base): session.close() return deletions + @staticmethod + def delete(engine: Engine, lease_ref: str) -> int: + session = sessionmaker(bind=engine)() + deletions = session.query(Lease).filter(Lease.lease_ref == lease_ref).delete() + session.commit() + session.close() + return deletions + def init(engine: Engine): tables = [Origin, Lease] From ed1b55f5f1ab3f273c4d0dd5b31d982cb6ffbd8b Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 10:12:31 +0100 Subject: [PATCH 47/62] created a simple management ui --- README.md | 4 ++++ app/main.py | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/README.md b/README.md index be9cc41..f7af25d 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,10 @@ Status endpoint, used for *healthcheck*. Shows also current version and commit h OpenAPI specifications rendered from `GET /openapi.json`. +### `GET /-/manage` + +Shows a very basic UI to delete origins or leases. + ### `GET /-/origins?leases=false` List registered origins. diff --git a/app/main.py b/app/main.py index 586c0c1..2bcb4c3 100644 --- a/app/main.py +++ b/app/main.py @@ -75,6 +75,40 @@ async def status(request: Request): return JSONResponse({'status': 'up', 'version': VERSION, 'commit': COMMIT, 'debug': DEBUG}) +@app.get('/-/manage') +async def _manage(request: Request): + response = ''' + + + + FastAPI-DLS Management + + + + + + + + + ''' + return HTMLResponse(response) + + @app.get('/-/origins') async def _origins(request: Request, leases: bool = False): session = sessionmaker(bind=db)() From a09fc5f2ad912ad2cf5b97a3fb62500d158ee714 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 10:31:25 +0100 Subject: [PATCH 48/62] added some new endpoints and links in readme --- .DEBIAN/postinst | 2 +- .gitlab-ci.yml | 2 +- Dockerfile | 2 +- README.md | 21 ++++++++++++++------- app/main.py | 24 +++++++++++++++++------- 5 files changed, 34 insertions(+), 17 deletions(-) diff --git a/.DEBIAN/postinst b/.DEBIAN/postinst index 2311b35..60e5dcb 100644 --- a/.DEBIAN/postinst +++ b/.DEBIAN/postinst @@ -75,7 +75,7 @@ if [[ -f $CONFIG_DIR/webserver.key ]]; then if [ -x "$(command -v curl)" ]; then echo "> Testing API ..." source $CONFIG_DIR/env - curl --insecure -X GET https://$DLS_URL:$DLS_PORT/status + curl --insecure -X GET https://$DLS_URL:$DLS_PORT/-/health else echo "> Testing API failed, curl not available. Please test manually!" fi diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index cc50ffd..a137dee 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -122,7 +122,7 @@ test: - FASTAPI_DLS_PID=$! - echo "Started service with pid $FASTAPI_DLS_PID" # testing service - - if [ "`curl --insecure -s https://127.0.0.1/status | jq .status`" != "up" ]; then echo "Success"; else "Error"; fi + - if [ "`curl --insecure -s https://127.0.0.1/-/health | jq .status`" != "up" ]; then echo "Success"; else "Error"; fi # cleanup - kill $FASTAPI_DLS_PID - apt-get purge -qq -y fastapi-dls diff --git a/Dockerfile b/Dockerfile index 5819ef5..6ffaee6 100644 --- a/Dockerfile +++ b/Dockerfile @@ -14,5 +14,5 @@ COPY app /app COPY version.env /version.env COPY README.md /README.md -HEALTHCHECK --start-period=30s --interval=10s --timeout=5s --retries=3 CMD curl --insecure --fail https://localhost/status || exit 1 +HEALTHCHECK --start-period=30s --interval=10s --timeout=5s --retries=3 CMD curl --insecure --fail https://localhost/-/health || exit 1 CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "443", "--app-dir", "/app", "--proxy-headers", "--ssl-keyfile", "/app/cert/webserver.key", "--ssl-certfile", "/app/cert/webserver.crt"] diff --git a/README.md b/README.md index f7af25d..92377fd 100644 --- a/README.md +++ b/README.md @@ -13,19 +13,27 @@ Only the clients need a connection to this service on configured port. ## Endpoints -### `GET /` +### [`GET /`](/) -HTML rendered README.md. +Redirect to `/-/readme`. -### `GET /status` +### [`GET /status`](/status) (deprecated: use `/-/health`) Status endpoint, used for *healthcheck*. Shows also current version and commit hash. -### `GET /docs` +### [`GET /-/health`](/-/health) -OpenAPI specifications rendered from `GET /openapi.json`. +Status endpoint, used for *healthcheck*. Shows also current version and commit hash. -### `GET /-/manage` +### [`GET /-/readme`](/-/readme) + +HTML rendered README.md. + +### [`GET /-/docs`](/-/docs), [`GET /-/redocs`](/-/redocs) + +OpenAPI specifications rendered from `GET /-/openapi.json`. + +### [`GET /-/manage`](/-/manage) Shows a very basic UI to delete origins or leases. @@ -413,7 +421,6 @@ Dec 20 17:53:34 ubuntu-grid-server nvidia-gridd[10354]: License acquired success - # Credits Thanks to vGPU community and all who uses this project and report bugs. diff --git a/app/main.py b/app/main.py index 2bcb4c3..8dc55ae 100644 --- a/app/main.py +++ b/app/main.py @@ -63,19 +63,29 @@ def get_token(request: Request) -> dict: return jwt.decode(token=token, key=jwt_decode_key, algorithms=ALGORITHMS.RS256, options={'verify_aud': False}) -@app.get('/') +@app.get('/', summary='* Index') async def index(): + return RedirectResponse('/-/readme') + + +@app.get('/status', summary='* Status', description='Returns current service status, version (incl. git-commit) and some variables.', deprecated=True) +async def status(request: Request): + return JSONResponse({'status': 'up', 'version': VERSION, 'commit': COMMIT, 'debug': DEBUG}) + + +@app.get('/-/health', summary='* Health') +async def _health(request: Request): + return JSONResponse({'status': 'up', 'version': VERSION, 'commit': COMMIT, 'debug': DEBUG}) + + +@app.get('/-/readme', summary='* Readme') +async def _readme(): from markdown import markdown content = load_file('../README.md').decode('utf-8') return HTMLResponse(markdown(text=content, extensions=['tables', 'fenced_code', 'md_in_html', 'nl2br', 'toc'])) -@app.get('/status') -async def status(request: Request): - return JSONResponse({'status': 'up', 'version': VERSION, 'commit': COMMIT, 'debug': DEBUG}) - - -@app.get('/-/manage') +@app.get('/-/manage', summary='* Management UI') async def _manage(request: Request): response = ''' From 8b9c7d688b059f68dbfb1933157d36ed76b37e1d Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 10:35:15 +0100 Subject: [PATCH 49/62] added some docs to custom endpoints --- app/main.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/app/main.py b/app/main.py index 8dc55ae..8c30ad9 100644 --- a/app/main.py +++ b/app/main.py @@ -15,7 +15,7 @@ from calendar import timegm from jose import jws, jwk, jwt from jose.constants import ALGORITHMS from starlette.middleware.cors import CORSMiddleware -from starlette.responses import StreamingResponse, JSONResponse, HTMLResponse, Response +from starlette.responses import StreamingResponse, JSONResponse, HTMLResponse, Response, RedirectResponse from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker @@ -27,7 +27,8 @@ load_dotenv('../version.env') VERSION, COMMIT, DEBUG = env('VERSION', 'unknown'), env('COMMIT', 'unknown'), bool(env('DEBUG', False)) -app = FastAPI(title='FastAPI-DLS', description='Minimal Delegated License Service (DLS).', version=VERSION) +config = dict(openapi_url='/-/openapi.json', docs_url='/-/docs', redoc_url='/-/redoc') +app = FastAPI(title='FastAPI-DLS', description='Minimal Delegated License Service (DLS).', version=VERSION, **config) db = create_engine(str(env('DATABASE', 'sqlite:///db.sqlite'))) db_init(db), migrate(db) @@ -119,7 +120,7 @@ async def _manage(request: Request): return HTMLResponse(response) -@app.get('/-/origins') +@app.get('/-/origins', summary='* Origins') async def _origins(request: Request, leases: bool = False): session = sessionmaker(bind=db)() response = [] @@ -132,13 +133,13 @@ async def _origins(request: Request, leases: bool = False): return JSONResponse(response) -@app.delete('/-/origins') +@app.delete('/-/origins', summary='* Origins') async def _origins_delete(request: Request): Origin.delete(db) return Response(status_code=201) -@app.get('/-/leases') +@app.get('/-/leases', summary='* Leases') async def _leases(request: Request, origin: bool = False): session = sessionmaker(bind=db)() response = [] @@ -152,7 +153,7 @@ async def _leases(request: Request, origin: bool = False): return JSONResponse(response) -@app.delete('/-/lease/{lease_ref}') +@app.delete('/-/lease/{lease_ref}', summary='* Lease') async def _lease_delete(request: Request, lease_ref: str): if Lease.delete(db, lease_ref) == 1: return Response(status_code=201) @@ -160,7 +161,7 @@ async def _lease_delete(request: Request, lease_ref: str): # venv/lib/python3.9/site-packages/nls_core_service_instance/service_instance_token_manager.py -@app.get('/client-token') +@app.get('/client-token', summary='* Client-Token') async def client_token(): cur_time = datetime.utcnow() exp_time = cur_time + relativedelta(years=12) From 1b2da802cb6af98a912cdb90b5965e74604d07fc Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 10:37:47 +0100 Subject: [PATCH 50/62] added tests for new endpoints --- test/main.py | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/test/main.py b/test/main.py index 34903db..364c5b0 100644 --- a/test/main.py +++ b/test/main.py @@ -44,11 +44,43 @@ def test_status(): assert response.json()['status'] == 'up' +def test_health(): + response = client.get('/-/health') + assert response.status_code == 200 + assert response.json()['status'] == 'up' + + +def test_readme(): + response = client.get('/-/readme') + assert response.status_code == 200 + + +def test_manage(): + response = client.get('/-/manage') + assert response.status_code == 200 + + def test_client_token(): response = client.get('/client-token') assert response.status_code == 200 +def test_origins(): + pass + + +def test_origins_delete(): + pass + + +def test_leases(): + pass + + +def test_lease_delete(): + pass + + def test_auth_v1_origin(): payload = { "registration_pending": False, From a59b720f3f33f2ccdf240fdc32933551bf340f85 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 10:40:34 +0100 Subject: [PATCH 51/62] fixes --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index a137dee..fb33db3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -147,7 +147,7 @@ test:archlinux: artifacts: true script: - pacman -Sy - - pacman -U --noconfirm *.pkg.tar.zs + - pacman -U --noconfirm *.pkg.tar.zst deploy:docker: stage: deploy From 47312f65d99db298b508445fc71a26205f19e7b9 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 10:44:39 +0100 Subject: [PATCH 52/62] .gitlab-ci.yml improved --- .gitlab-ci.yml | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fb33db3..c3cc797 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -149,14 +149,15 @@ test:archlinux: - pacman -Sy - pacman -U --noconfirm *.pkg.tar.zst -deploy:docker: - stage: deploy +.deploy: rules: - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - - changes: - - Dockerfile - - requirements.txt - - app/**/* + - if: $CI_COMMIT_TAG + when: never + +deploy:docker: + extends: .deploy + stage: deploy before_script: - echo "COMMIT=${CI_COMMIT_SHA}" >> version.env - source version.env @@ -177,10 +178,9 @@ deploy:docker: deploy:apt: # doc: https://git.collinwebdesigns.de/help/user/packages/debian_repository/index.md#install-a-package + extends: .deploy image: debian:bookworm-slim stage: deploy - rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH needs: - job: build:apt artifacts: true @@ -217,13 +217,12 @@ deploy:apt: - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${EXPORT_NAME} "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${PACKAGE_NAME}/${PACKAGE_VERSION}/${EXPORT_NAME}"' deploy:pacman: + extends: .deploy image: archlinux:base-devel stage: deploy needs: - job: build:pacman artifacts: true - rules: - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH script: - source .PKGBUILD/PKGBUILD # fastapi-dls-1.0-1-any.pkg.tar.zst From 85e2ef69303d26bc4001295234ce37c3b7816d8f Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 10:49:14 +0100 Subject: [PATCH 53/62] use version variable in DEBIAN/control --- .DEBIAN/control | 2 +- .gitlab-ci.yml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/.DEBIAN/control b/.DEBIAN/control index d5054a8..1bab5e2 100644 --- a/.DEBIAN/control +++ b/.DEBIAN/control @@ -1,5 +1,5 @@ Package: fastapi-dls -Version: 1.0 +Version: 0.0 Architecture: all Maintainer: Oscar Krause oscar.krause@collinwebdesigns.de Depends: python3, python3-fastapi, python3-uvicorn, python3-dotenv, python3-dateutil, python3-jose, python3-sqlalchemy, python3-pycryptodome, python3-markdown, uvicorn, openssl diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index c3cc797..44b320f 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -23,6 +23,7 @@ build:apt: - if: $CI_COMMIT_BRANCH before_script: - echo "COMMIT=${CI_COMMIT_SHA}" >> version.env + - source version.env # install build dependencies - apt-get update -qq && apt-get install -qq -y build-essential # create build directory for .deb sources @@ -40,7 +41,9 @@ build:apt: # cd into "build/" - cd build/ script: + - sed -i -E 's/(Version\:\s)0.0/\1'"$VERSION"'/g' DEBIAN/control - dpkg -b . build.deb + - dpkg -I build.deb artifacts: expire_in: 1 week paths: From ff02c77afebeb1eb20d2aea404c5850b2b583bf9 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 12:12:26 +0100 Subject: [PATCH 54/62] use version variable in PKGBUILD --- .PKGBUILD/PKGBUILD | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.PKGBUILD/PKGBUILD b/.PKGBUILD/PKGBUILD index d3659b7..3ff4a67 100644 --- a/.PKGBUILD/PKGBUILD +++ b/.PKGBUILD/PKGBUILD @@ -2,7 +2,7 @@ # Maintainer: Oscar Krause pkgname=fastapi-dls -pkgver=1.0 +pkgver=0.0 pkgrel=1 pkgdesc='NVIDIA DLS server implementation with FastAPI' arch=('any') @@ -18,6 +18,11 @@ sha256sums=('SKIP' 'd8b2216b67a2f8f35ad6f07c825839794f7c34456a72caadd9fc110810348d90' '10cb98d64f8bf37b11a60510793c187cc664e63c895d1205781c21fa2e703f32') +pkgver() { + source $srcdir/$pkgname/version.env + echo ${VERSION} +} + check() { cd "$srcdir/$pkgname/test" mkdir "$srcdir/$pkgname/app/cert" From ca6942becc01ae73341dcc4e73f615c88c12421f Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 12:15:05 +0100 Subject: [PATCH 55/62] added some comments --- .gitlab-ci.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 44b320f..3dfd23e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -41,7 +41,9 @@ build:apt: # cd into "build/" - cd build/ script: + # set version based on value in "$VERSION" (which is set above from version.env) - sed -i -E 's/(Version\:\s)0.0/\1'"$VERSION"'/g' DEBIAN/control + # build - dpkg -b . build.deb - dpkg -I build.deb artifacts: From 26d6d1feeb63acbe981a771e127772f5815c8751 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 12:19:49 +0100 Subject: [PATCH 56/62] updated variables descriptions --- .DEBIAN/postinst | 19 +++++++++++++++++++ .PKGBUILD/fastapi-dls.default | 2 +- README.md | 24 ++++++++++++------------ 3 files changed, 32 insertions(+), 13 deletions(-) diff --git a/.DEBIAN/postinst b/.DEBIAN/postinst index 60e5dcb..f0d9bdc 100644 --- a/.DEBIAN/postinst +++ b/.DEBIAN/postinst @@ -41,10 +41,29 @@ if [[ ! -f $CONFIG_DIR/env ]]; then echo "> Writing initial config ..." touch $CONFIG_DIR/env cat <$CONFIG_DIR/env +# Toggle debug mode +#DEBUG=false + +# Where the client can find the DLS server DLS_URL=127.0.0.1 DLS_PORT=443 + +# CORS configuration +## comma separated list without spaces +#CORS_ORIGINS="https://$DLS_URL:$DLS_PORT" + +# Lease expiration in days LEASE_EXPIRE_DAYS=90 + +# Database location +## https://docs.sqlalchemy.org/en/14/core/engines.html DATABASE=sqlite:///$CONFIG_DIR/db.sqlite + +# UUIDs for identifying the instance +#SITE_KEY_XID="00000000-0000-0000-0000-000000000000" +#INSTANCE_REF="00000000-0000-0000-0000-000000000000" + +# Site-wide signing keys INSTANCE_KEY_RSA=$CONFIG_DIR/instance.private.pem INSTANCE_KEY_PUB=$CONFIG_DIR/instance.public.pem diff --git a/.PKGBUILD/fastapi-dls.default b/.PKGBUILD/fastapi-dls.default index 079679b..0add216 100644 --- a/.PKGBUILD/fastapi-dls.default +++ b/.PKGBUILD/fastapi-dls.default @@ -11,7 +11,7 @@ CORS_ORIGINS="https://$DLS_URL:$DLS_PORT" LEASE_EXPIRE_DAYS=90 # Database location -## See https://dataset.readthedocs.io/en/latest/quickstart.html for details +## https://docs.sqlalchemy.org/en/14/core/engines.html DATABASE="sqlite:////var/lib/fastapi-dls/db.sqlite" # UUIDs for identifying the instance diff --git a/README.md b/README.md index 92377fd..c9e072a 100644 --- a/README.md +++ b/README.md @@ -280,18 +280,18 @@ After first success you have to replace `--issue` with `--renew`. # Configuration -| Variable | Default | Usage | -|---------------------|----------------------------------------|---------------------------------------------------------------------------------------| -| `DEBUG` | `false` | Toggles `fastapi` debug mode | -| `DLS_URL` | `localhost` | Used in client-token to tell guest driver where dls instance is reachable | -| `DLS_PORT` | `443` | Used in client-token to tell guest driver where dls instance is reachable | -| `LEASE_EXPIRE_DAYS` | `90` | Lease time in days | -| `DATABASE` | `sqlite:///db.sqlite` | See [official dataset docs](https://dataset.readthedocs.io/en/latest/quickstart.html) | -| `CORS_ORIGINS` | `https://{DLS_URL}` | Sets `Access-Control-Allow-Origin` header (comma separated string) | -| `SITE_KEY_XID` | `00000000-0000-0000-0000-000000000000` | Site identification uuid | -| `INSTANCE_REF` | `00000000-0000-0000-0000-000000000000` | Instance identification uuid | -| `INSTANCE_KEY_RSA` | `/cert/instance.private.pem` | Site-wide private RSA key for singing JWTs | -| `INSTANCE_KEY_PUB` | `/cert/instance.public.pem` | Site-wide public key | +| Variable | Default | Usage | +|---------------------|----------------------------------------|-------------------------------------------------------------------------------------| +| `DEBUG` | `false` | Toggles `fastapi` debug mode | +| `DLS_URL` | `localhost` | Used in client-token to tell guest driver where dls instance is reachable | +| `DLS_PORT` | `443` | Used in client-token to tell guest driver where dls instance is reachable | +| `LEASE_EXPIRE_DAYS` | `90` | Lease time in days | +| `DATABASE` | `sqlite:///db.sqlite` | See [official SQLAlchemy docs](https://docs.sqlalchemy.org/en/14/core/engines.html) | +| `CORS_ORIGINS` | `https://{DLS_URL}` | Sets `Access-Control-Allow-Origin` header (comma separated string) | +| `SITE_KEY_XID` | `00000000-0000-0000-0000-000000000000` | Site identification uuid | +| `INSTANCE_REF` | `00000000-0000-0000-0000-000000000000` | Instance identification uuid | +| `INSTANCE_KEY_RSA` | `/cert/instance.private.pem` | Site-wide private RSA key for singing JWTs | +| `INSTANCE_KEY_PUB` | `/cert/instance.public.pem` | Site-wide public key | # Setup (Client) From 5f87e65034f8c1c7df956da006545dd26df60951 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 12:19:56 +0100 Subject: [PATCH 57/62] bump version to 1.1 --- version.env | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.env b/version.env index d53e27c..c350bf1 100644 --- a/version.env +++ b/version.env @@ -1 +1 @@ -VERSION=1.0 +VERSION=1.1 From 51183f6845fe5defb58d4db5275af4f948a65a52 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 12:21:41 +0100 Subject: [PATCH 58/62] updated hashes --- .PKGBUILD/PKGBUILD | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.PKGBUILD/PKGBUILD b/.PKGBUILD/PKGBUILD index 3ff4a67..f8fb48e 100644 --- a/.PKGBUILD/PKGBUILD +++ b/.PKGBUILD/PKGBUILD @@ -15,7 +15,7 @@ source=('git+file:///builds/oscar.krause/fastapi-dls' # https://gitea.publichub. "$pkgname.default" "$pkgname.service") sha256sums=('SKIP' - 'd8b2216b67a2f8f35ad6f07c825839794f7c34456a72caadd9fc110810348d90' + '4c07e9b627853bd4f3a398371912fc72302dac33f43e4cb7e9b79746cc9c9136' '10cb98d64f8bf37b11a60510793c187cc664e63c895d1205781c21fa2e703f32') pkgver() { From 0c3a38b84eb3c35c9d541af5f03bdf41daee17aa Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 12:26:05 +0100 Subject: [PATCH 59/62] .gitlab-ci.yml - fixed MR pipeline --- .gitlab-ci.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3dfd23e..e02ebce 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,7 +6,8 @@ build:docker: interruptible: true stage: build rules: - - if: $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH + - if: $CI_COMMIT_BRANCH && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' tags: [ docker ] before_script: - echo "COMMIT=${CI_COMMIT_SHA}" >> version.env # COMMIT=`git rev-parse HEAD` @@ -21,6 +22,7 @@ build:apt: stage: build rules: - if: $CI_COMMIT_BRANCH + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' before_script: - echo "COMMIT=${CI_COMMIT_SHA}" >> version.env - source version.env @@ -57,6 +59,7 @@ build:pacman: stage: build rules: - if: $CI_COMMIT_BRANCH + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' before_script: - echo "COMMIT=${CI_COMMIT_SHA}" >> version.env # install build dependencies From 0983426f30078a3281ea773c84fd6af4ee8e3b65 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 12:30:23 +0100 Subject: [PATCH 60/62] .gitlab-ci.yml improvements --- .gitlab-ci.yml | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e02ebce..fc582aa 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -7,6 +7,9 @@ build:docker: stage: build rules: - if: $CI_COMMIT_BRANCH && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH + changes: + - app/**/* + - Dockerfile - if: $CI_PIPELINE_SOURCE == 'merge_request_event' tags: [ docker ] before_script: @@ -21,7 +24,11 @@ build:apt: interruptible: true stage: build rules: - - if: $CI_COMMIT_BRANCH + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + - if: $CI_COMMIT_BRANCH && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH + changes: + - app/**/* + - .DEBIAN/**/* - if: $CI_PIPELINE_SOURCE == 'merge_request_event' before_script: - echo "COMMIT=${CI_COMMIT_SHA}" >> version.env @@ -58,7 +65,11 @@ build:pacman: interruptible: true stage: build rules: - - if: $CI_COMMIT_BRANCH + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + - if: $CI_COMMIT_BRANCH && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH + changes: + - app/**/* + - .PKGBUILD/**/* - if: $CI_PIPELINE_SOURCE == 'merge_request_event' before_script: - echo "COMMIT=${CI_COMMIT_SHA}" >> version.env @@ -103,9 +114,11 @@ test: .test:linux: stage: test rules: - - changes: - - .DEBIAN/**/* + - if: $CI_COMMIT_BRANCH && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH + changes: - app/**/* + - .DEBIAN/**/* + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' needs: - job: build:apt artifacts: true @@ -147,9 +160,11 @@ test:ubuntu: test:archlinux: image: archlinux:base rules: - - changes: - - .PKGBUILD/**/* + - if: $CI_COMMIT_BRANCH && $CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH + changes: - app/**/* + - .PKGBUILD/**/* + - if: $CI_PIPELINE_SOURCE == 'merge_request_event' needs: - job: build:pacman artifacts: true @@ -166,6 +181,8 @@ test:archlinux: deploy:docker: extends: .deploy stage: deploy + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH before_script: - echo "COMMIT=${CI_COMMIT_SHA}" >> version.env - source version.env @@ -189,6 +206,8 @@ deploy:apt: extends: .deploy image: debian:bookworm-slim stage: deploy + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH needs: - job: build:apt artifacts: true @@ -228,6 +247,8 @@ deploy:pacman: extends: .deploy image: archlinux:base-devel stage: deploy + rules: + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH needs: - job: build:pacman artifacts: true From 13ec45e7627ecc5ff0866e23d0890ab12f84a6f0 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 12:34:25 +0100 Subject: [PATCH 61/62] orm.py - added init call after dropping table by migration --- app/orm.py | 1 + 1 file changed, 1 insertion(+) diff --git a/app/orm.py b/app/orm.py index 77cd8fc..62a9fb1 100644 --- a/app/orm.py +++ b/app/orm.py @@ -169,5 +169,6 @@ def migrate(engine: Engine): print(' Your leases are recreated on next renewal!') print(' If an error message appears on the client, you can ignore it.') Lease.__table__.drop(bind=engine) + init(engine) upgrade_1_0_to_1_1() From 00f7c50e4eda9bcef9ffecb59cece2a781338463 Mon Sep 17 00:00:00 2001 From: Oscar Krause Date: Thu, 29 Dec 2022 12:47:51 +0100 Subject: [PATCH 62/62] .gitlab-ci.yml - added release job --- .gitlab-ci.yml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index fc582aa..290c647 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -265,3 +265,26 @@ deploy:pacman: - 'echo "PACKAGE_ARCH: ${PACKAGE_ARCH}"' - 'echo "EXPORT_NAME: ${EXPORT_NAME}"' - 'curl --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${EXPORT_NAME} "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/generic/${PACKAGE_NAME}/${PACKAGE_VERSION}/${EXPORT_NAME}"' + +release: + image: registry.gitlab.com/gitlab-org/release-cli:latest + stage: .post + rules: + - if: $CI_COMMIT_TAG + when: never + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH + before_script: + - source version.env + script: + - echo "Running release-job for $VERSION" + release: + name: $CI_PROJECT_TITLE $version + description: Release of $CI_PROJECT_TITLE version $VERSION + tag_name: $VERSION + ref: $CI_COMMIT_SHA + assets: + links: + - name: 'Package Registry' + url: 'https://git.collinwebdesigns.de/oscar.krause/fastapi-dls/-/packages' + - name: 'Container Registry' + url: 'https://git.collinwebdesigns.de/oscar.krause/fastapi-dls/container_registry/40'