mirror of
				https://git.collinwebdesigns.de/oscar.krause/fastapi-dls.git
				synced 2025-11-04 06:30:21 +01:00 
			
		
		
		
	Merge branch 'debian' into 'dev'
Debian See merge request oscar.krause/fastapi-dls!11
This commit is contained in:
		
							
								
								
									
										102
									
								
								.gitlab-ci.yml
									
									
									
									
									
								
							
							
						
						
									
										102
									
								
								.gitlab-ci.yml
									
									
									
									
									
								
							@@ -1,7 +1,34 @@
 | 
			
		||||
cache:
 | 
			
		||||
  key: one-key-to-rule-them-all
 | 
			
		||||
 | 
			
		||||
build:
 | 
			
		||||
build:debian:
 | 
			
		||||
  # debian:bullseye-slim
 | 
			
		||||
  image: debian:bookworm-slim  # just to get "python3-jose" working
 | 
			
		||||
  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
 | 
			
		||||
    - cp -r DEBIAN build/
 | 
			
		||||
    # 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
 | 
			
		||||
    - cp README.md version.env build/usr/share/fastapi-dls
 | 
			
		||||
    # create conf file
 | 
			
		||||
    - mkdir -p build/etc/fastapi-dls
 | 
			
		||||
    - touch build/etc/fastapi-dls/env
 | 
			
		||||
    # cd into "build/"
 | 
			
		||||
    - cd build/
 | 
			
		||||
  script:
 | 
			
		||||
    - dpkg -b . build.deb
 | 
			
		||||
  artifacts:
 | 
			
		||||
    expire_in: 1 week
 | 
			
		||||
    paths:
 | 
			
		||||
      - build/build.deb
 | 
			
		||||
 | 
			
		||||
build:docker:
 | 
			
		||||
  image: docker:dind
 | 
			
		||||
  interruptible: true
 | 
			
		||||
  stage: build
 | 
			
		||||
@@ -30,7 +57,37 @@ test:
 | 
			
		||||
  script:
 | 
			
		||||
    - pytest main.py
 | 
			
		||||
 | 
			
		||||
deploy:
 | 
			
		||||
test:debian:
 | 
			
		||||
  image: debian:bookworm-slim
 | 
			
		||||
  stage: test
 | 
			
		||||
  variables:
 | 
			
		||||
    DEBIAN_FRONTEND: noninteractive
 | 
			
		||||
  needs:
 | 
			
		||||
    - job: build:debian
 | 
			
		||||
      artifacts: true
 | 
			
		||||
  before_script:
 | 
			
		||||
    - apt-get update -qq && apt-get install -qq -y jq
 | 
			
		||||
  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
 | 
			
		||||
    - uvicorn --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
 | 
			
		||||
      --proxy-headers &
 | 
			
		||||
    - 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
 | 
			
		||||
    # cleanup
 | 
			
		||||
    - kill $FASTAPI_DLS_PID
 | 
			
		||||
    - apt-get purge -qq -y fastapi-dls
 | 
			
		||||
    - apt-get autoremove -qq -y && apt-get clean -qq
 | 
			
		||||
 | 
			
		||||
deploy:docker:
 | 
			
		||||
  stage: deploy
 | 
			
		||||
  rules:
 | 
			
		||||
    - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
 | 
			
		||||
@@ -51,3 +108,44 @@ deploy:
 | 
			
		||||
    - docker build . --tag $PUBLIC_REGISTRY_USER/${CI_PROJECT_NAME}:latest
 | 
			
		||||
    - docker push $PUBLIC_REGISTRY_USER/${CI_PROJECT_NAME}:${VERSION}
 | 
			
		||||
    - docker push $PUBLIC_REGISTRY_USER/${CI_PROJECT_NAME}:latest
 | 
			
		||||
 | 
			
		||||
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 == "debian"  # $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
 | 
			
		||||
  needs:
 | 
			
		||||
    - job: build:debian
 | 
			
		||||
      artifacts: true
 | 
			
		||||
  before_script:
 | 
			
		||||
    - apt-get update -qq && apt-get install -qq -y curl lsb-release
 | 
			
		||||
    # create distribution initial
 | 
			
		||||
    - CODENAME=`lsb_release -cs`
 | 
			
		||||
    # create repo if not exists
 | 
			
		||||
    - 'if [ "`curl -s -o /dev/null -w "%{http_code}" --header "JOB-TOKEN: $CI_JOB_TOKEN" -s ${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/debian_distributions/${CODENAME}/key.asc`" != "200" ]; then curl --request POST --header "JOB-TOKEN: $CI_JOB_TOKEN" "${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/debian_distributions?codename=${CODENAME}"; fi'
 | 
			
		||||
  script:
 | 
			
		||||
    # Naming format: <name>_<version>-<release>_<arch>.deb
 | 
			
		||||
    # Version is the version number of the app being packaged
 | 
			
		||||
    # Release number is the version number of the *packaging* itself.
 | 
			
		||||
    # The release number might increment if the package maintainer
 | 
			
		||||
    # updated the packaging, while the version number of the application
 | 
			
		||||
    # being packaged did not change.
 | 
			
		||||
    - BUILD_NAME=build/build.deb  # inherited by build-stage
 | 
			
		||||
    - PACKAGE_NAME=`dpkg -I ${BUILD_NAME} | grep "Package:" | awk '{ print $2 }'`
 | 
			
		||||
    - PACKAGE_VERSION=`dpkg -I ${BUILD_NAME} | grep "Version:" | awk '{ print $2 }'`
 | 
			
		||||
    - PACKAGE_ARCH=amd64
 | 
			
		||||
    #- EXPORT_NAME="${PACKAGE_NAME}_${PACKAGE_VERSION}-0_${PACKAGE_ARCH}.deb"
 | 
			
		||||
    - EXPORT_NAME="${PACKAGE_NAME}_${PACKAGE_VERSION}_${PACKAGE_ARCH}.deb"
 | 
			
		||||
    - mv ${BUILD_NAME} ${EXPORT_NAME}
 | 
			
		||||
    - 'echo "PACKAGE_NAME:    ${PACKAGE_NAME}"'
 | 
			
		||||
    - 'echo "PACKAGE_VERSION: ${PACKAGE_VERSION}"'
 | 
			
		||||
    - 'echo "PACKAGE_ARCH:    ${PACKAGE_ARCH}"'
 | 
			
		||||
    - 'echo "EXPORT_NAME:     ${EXPORT_NAME}"'
 | 
			
		||||
    # https://docs.gitlab.com/14.3/ee/user/packages/debian_repository/index.html
 | 
			
		||||
    - URL="${CI_API_V4_URL}/projects/${CI_PROJECT_ID}/packages/debian/${EXPORT_NAME}"
 | 
			
		||||
    - 'echo "URL:             ${URL}"'
 | 
			
		||||
    #- 'curl --request PUT --header "JOB-TOKEN: $CI_JOB_TOKEN" --upload-file ${EXPORT_NAME} ${URL}'
 | 
			
		||||
    # 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}"'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										1
									
								
								DEBIAN/conffiles
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								DEBIAN/conffiles
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1 @@
 | 
			
		||||
/etc/fastapi-dls/env
 | 
			
		||||
							
								
								
									
										9
									
								
								DEBIAN/control
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								DEBIAN/control
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
Package: fastapi-dls
 | 
			
		||||
Version: 0.6.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
 | 
			
		||||
Recommends: curl
 | 
			
		||||
Installed-Size: 10240
 | 
			
		||||
Homepage: https://git.collinwebdesigns.de/oscar.krause/fastapi-dls
 | 
			
		||||
Description: Minimal Delegated License Service (DLS).
 | 
			
		||||
							
								
								
									
										101
									
								
								DEBIAN/postinst
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								DEBIAN/postinst
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,101 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
WORKING_DIR=/usr/share/fastapi-dls
 | 
			
		||||
CONFIG_DIR=/etc/fastapi-dls
 | 
			
		||||
 | 
			
		||||
echo "> Create config directory ..."
 | 
			
		||||
mkdir -p $CONFIG_DIR
 | 
			
		||||
 | 
			
		||||
echo "> Install service ..."
 | 
			
		||||
cat <<EOF >/etc/systemd/system/fastapi-dls.service
 | 
			
		||||
[Unit]
 | 
			
		||||
Description=Service for fastapi-dls
 | 
			
		||||
After=network.target
 | 
			
		||||
 | 
			
		||||
[Service]
 | 
			
		||||
User=www-data
 | 
			
		||||
Group=www-data
 | 
			
		||||
AmbientCapabilities=CAP_NET_BIND_SERVICE
 | 
			
		||||
WorkingDirectory=$WORKING_DIR/app
 | 
			
		||||
EnvironmentFile=$CONFIG_DIR/env
 | 
			
		||||
ExecStart=uvicorn main:app \\
 | 
			
		||||
  --env-file /etc/fastapi-dls/env \\
 | 
			
		||||
  --host \$DLS_URL --port \$DLS_PORT \\
 | 
			
		||||
  --app-dir $WORKING_DIR/app \\
 | 
			
		||||
  --ssl-keyfile /etc/fastapi-dls/webserver.key \\
 | 
			
		||||
  --ssl-certfile /etc/fastapi-dls/webserver.crt \\
 | 
			
		||||
  --proxy-headers
 | 
			
		||||
Restart=always
 | 
			
		||||
KillSignal=SIGQUIT
 | 
			
		||||
Type=simple
 | 
			
		||||
NotifyAccess=all
 | 
			
		||||
 | 
			
		||||
[Install]
 | 
			
		||||
WantedBy=multi-user.target
 | 
			
		||||
 | 
			
		||||
EOF
 | 
			
		||||
 | 
			
		||||
systemctl daemon-reload
 | 
			
		||||
 | 
			
		||||
if [[ ! -f $CONFIG_DIR/env ]]; then
 | 
			
		||||
  echo "> Writing initial config ..."
 | 
			
		||||
  touch $CONFIG_DIR/env
 | 
			
		||||
  cat <<EOF >$CONFIG_DIR/env
 | 
			
		||||
DLS_URL=127.0.0.1
 | 
			
		||||
DLS_PORT=443
 | 
			
		||||
LEASE_EXPIRE_DAYS=90
 | 
			
		||||
DATABASE=sqlite:///$CONFIG_DIR/db.sqlite
 | 
			
		||||
INSTANCE_KEY_RSA=$CONFIG_DIR/instance.private.pem
 | 
			
		||||
INSTANCE_KEY_PUB=$CONFIG_DIR/instance.public.pem
 | 
			
		||||
 | 
			
		||||
EOF
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
echo "> Create dls-instance keypair ..."
 | 
			
		||||
openssl genrsa -out $CONFIG_DIR/instance.private.pem 2048
 | 
			
		||||
openssl rsa -in $CONFIG_DIR/instance.private.pem -outform PEM -pubout -out $CONFIG_DIR/instance.public.pem
 | 
			
		||||
 | 
			
		||||
while true; do
 | 
			
		||||
  read -p "> Do you wish to create self-signed webserver certificate? [Y/n]" yn
 | 
			
		||||
  yn=${yn:-y} # ${parameter:-word} If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted.
 | 
			
		||||
  case $yn in
 | 
			
		||||
  [Yy]*)
 | 
			
		||||
    openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout $CONFIG_DIR/webserver.key -out $CONFIG_DIR/webserver.crt
 | 
			
		||||
    break
 | 
			
		||||
    ;;
 | 
			
		||||
  [Nn]*) break ;;
 | 
			
		||||
  *) echo "Please answer [y] or [n]." ;;
 | 
			
		||||
  esac
 | 
			
		||||
done
 | 
			
		||||
 | 
			
		||||
if [[ -f $CONFIG_DIR/webserver.key ]]; then
 | 
			
		||||
  echo "> Starting service ..."
 | 
			
		||||
  systemctl start fastapi-dls.service
 | 
			
		||||
 | 
			
		||||
  if [ -x "$(command -v curl)" ]; then
 | 
			
		||||
    echo "> Testing API ..."
 | 
			
		||||
    source $CONFIG_DIR/env
 | 
			
		||||
    curl --insecure -X GET https://$DLS_URL:$DLS_PORT/status
 | 
			
		||||
  else
 | 
			
		||||
    echo "> Testing API failed, curl not available. Please test manually!"
 | 
			
		||||
  fi
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
chown -R www-data:www-data $CONFIG_DIR
 | 
			
		||||
chown -R www-data:www-data $WORKING_DIR
 | 
			
		||||
 | 
			
		||||
cat <<EOF
 | 
			
		||||
 | 
			
		||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
#    fastapi-dls is now installed.                                            #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
#    Service should be up and running.                                        #
 | 
			
		||||
#      Webservice is listen to https://localhost                              #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
#    Configuration is stored in ${CONFIG_DIR}/env                             #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
#                                                                             #
 | 
			
		||||
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
 | 
			
		||||
 | 
			
		||||
EOF
 | 
			
		||||
							
								
								
									
										8
									
								
								DEBIAN/postrm
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										8
									
								
								DEBIAN/postrm
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,8 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
if [[ -f /etc/systemd/system/fastapi-dls.service ]]; then
 | 
			
		||||
  echo "> Removing service file."
 | 
			
		||||
  rm /etc/systemd/system/fastapi-dls.service
 | 
			
		||||
fi
 | 
			
		||||
 | 
			
		||||
# todo
 | 
			
		||||
							
								
								
									
										5
									
								
								DEBIAN/prerm
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										5
									
								
								DEBIAN/prerm
									
									
									
									
									
										Executable file
									
								
							@@ -0,0 +1,5 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
 | 
			
		||||
echo -e "> Starting uninstallation of 'fastapi-dls'!"
 | 
			
		||||
 | 
			
		||||
# todo
 | 
			
		||||
							
								
								
									
										24
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										24
									
								
								README.md
									
									
									
									
									
								
							@@ -192,7 +192,29 @@ EOF
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Now you have to run `systemctl daemon-reload`. After that you can start service
 | 
			
		||||
with `systemctl start fastapi-dls.service`.
 | 
			
		||||
with `systemctl start fastapi-dls.service` and enable autostart with `systemctl enable fastapi-dls.service`.
 | 
			
		||||
 | 
			
		||||
## Debian/Ubuntu (using `dpkg`)
 | 
			
		||||
 | 
			
		||||
Packages are available here:
 | 
			
		||||
 | 
			
		||||
- [GitLab-Registry](https://git.collinwebdesigns.de/oscar.krause/fastapi-dls/-/packages/63)
 | 
			
		||||
 | 
			
		||||
Successful tested with:
 | 
			
		||||
- Debian 12 (Bookworm)
 | 
			
		||||
- Ubuntu 22.10 (Kinetic Kudu)
 | 
			
		||||
 | 
			
		||||
**Run this on your server instance**
 | 
			
		||||
 | 
			
		||||
```shell
 | 
			
		||||
apt-get update
 | 
			
		||||
FILENAME=/opt/fastapi-dls.deb
 | 
			
		||||
wget -O $FILENAME https://git.collinwebdesigns.de/oscar.krause/fastapi-dls/-/package_files/148/download
 | 
			
		||||
dpkg -i $FILENAME
 | 
			
		||||
apt-get install -f --fix-missing
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
Start with `systemctl start fastapi-dls.service` and enable autostart with `systemctl enable fastapi-dls.service`.
 | 
			
		||||
 | 
			
		||||
## Let's Encrypt Certificate
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										10
									
								
								app/main.py
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								app/main.py
									
									
									
									
									
								
							@@ -19,8 +19,14 @@ from starlette.middleware.cors import CORSMiddleware
 | 
			
		||||
from starlette.responses import StreamingResponse, JSONResponse, HTMLResponse
 | 
			
		||||
from sqlalchemy import create_engine
 | 
			
		||||
from sqlalchemy.orm import sessionmaker
 | 
			
		||||
from Crypto.PublicKey import RSA
 | 
			
		||||
from Crypto.PublicKey.RSA import RsaKey
 | 
			
		||||
 | 
			
		||||
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 orm import Origin, Lease, init as db_init
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user