mirror of
https://github.com/donaldzou/WGDashboard.git
synced 2025-12-14 15:36:18 +00:00
Compare commits
15 Commits
v4.3.0.2
...
docker-qui
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c4d037047f | ||
|
|
6fee7da633 | ||
|
|
2e8d2fe400 | ||
|
|
da3c34c250 | ||
|
|
d864d12793 | ||
|
|
36390a4d71 | ||
|
|
5db2baf1dc | ||
|
|
dc10da607d | ||
|
|
9b4abf19fa | ||
|
|
bf823e6cf8 | ||
|
|
880c94b8a3 | ||
|
|
656eba3a57 | ||
|
|
4154a27f4d | ||
|
|
785d0d6b06 | ||
|
|
9af2983a7b |
8
.github/workflows/codeql-analyze.yaml
vendored
8
.github/workflows/codeql-analyze.yaml
vendored
@@ -39,11 +39,11 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v6
|
||||||
|
|
||||||
# Initializes the CodeQL tools for scanning.
|
# Initializes the CodeQL tools for scanning.
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v3
|
uses: github/codeql-action/init@v4
|
||||||
with:
|
with:
|
||||||
languages: ${{ matrix.language }}
|
languages: ${{ matrix.language }}
|
||||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||||
@@ -54,7 +54,7 @@ jobs:
|
|||||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||||
# If this step fails, then you should remove it and run the build manually (see below)
|
# If this step fails, then you should remove it and run the build manually (see below)
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v3
|
uses: github/codeql-action/autobuild@v4
|
||||||
|
|
||||||
# ℹ️ Command-line programs to run using the OS shell.
|
# ℹ️ Command-line programs to run using the OS shell.
|
||||||
# 📚 https://git.io/JvXDl
|
# 📚 https://git.io/JvXDl
|
||||||
@@ -68,4 +68,4 @@ jobs:
|
|||||||
# make release
|
# make release
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v3
|
uses: github/codeql-action/analyze@v4
|
||||||
|
|||||||
106
.github/workflows/docker-debug.yml
vendored
Normal file
106
.github/workflows/docker-debug.yml
vendored
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
name: MANUAL Docker workflow for debugging
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
env:
|
||||||
|
DOCKERHUB_PREFIX: docker.io
|
||||||
|
GITHUB_CONTAINER_PREFIX: ghcr.io
|
||||||
|
DOCKER_IMAGE: WGDashboard
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker_build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
packages: write
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
steps:
|
||||||
|
- name: Checkout repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Log in to Docker Hub
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.DOCKERHUB_PREFIX }}
|
||||||
|
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Log in to GitHub Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.GITHUB_CONTAINER_PREFIX }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
with:
|
||||||
|
platforms: linux/amd64
|
||||||
|
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v3
|
||||||
|
|
||||||
|
- name: Extract Docker metadata from environment
|
||||||
|
id: meta
|
||||||
|
uses: docker/metadata-action@v5
|
||||||
|
with:
|
||||||
|
images: |
|
||||||
|
${{ env.DOCKERHUB_PREFIX }}/donaldzou/${{ env.DOCKER_IMAGE }}
|
||||||
|
${{ env.GITHUB_CONTAINER_PREFIX }}/${{ github.repository_owner }}/${{ env.DOCKER_IMAGE }}
|
||||||
|
tags: |
|
||||||
|
type=ref,event=branch
|
||||||
|
type=ref,event=tag
|
||||||
|
type=sha,format=short,prefix=
|
||||||
|
|
||||||
|
- name: Build and export Docker image
|
||||||
|
uses: docker/build-push-action@v6
|
||||||
|
with:
|
||||||
|
context: .
|
||||||
|
file: ./docker/Dockerfile
|
||||||
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
|
tags: ${{ steps.meta.outputs.tags }}
|
||||||
|
labels: ${{ steps.meta.outputs.labels }}
|
||||||
|
platforms: linux/amd64
|
||||||
|
|
||||||
|
docker_scan:
|
||||||
|
if: ${{ github.event_name != 'pull_request' }}
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
needs: docker_build
|
||||||
|
steps:
|
||||||
|
- name: Log in to Docker Hub
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.DOCKERHUB_PREFIX }}
|
||||||
|
username: ${{ secrets.DOCKER_HUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
|
||||||
|
|
||||||
|
- name: Log in to GitHub Container Registry
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: ${{ env.GITHUB_CONTAINER_PREFIX }}
|
||||||
|
username: ${{ github.actor }}
|
||||||
|
password: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Docker Scout CVEs
|
||||||
|
uses: docker/scout-action@v1
|
||||||
|
with:
|
||||||
|
command: cves
|
||||||
|
image: ${{ env.GITHUB_CONTAINER_PREFIX }}/${{ github.repository_owner }}/${{ env.DOCKER_IMAGE }}:main
|
||||||
|
only-severities: critical,high
|
||||||
|
only-fixed: true
|
||||||
|
write-comment: true
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
exit-code: true
|
||||||
|
|
||||||
|
- name: Docker Scout Compare
|
||||||
|
uses: docker/scout-action@v1
|
||||||
|
with:
|
||||||
|
command: compare
|
||||||
|
# Set to Github for maximum compat
|
||||||
|
image: ${{ env.GITHUB_CONTAINER_PREFIX }}/${{ github.repository_owner }}/${{ env.DOCKER_IMAGE }}:main
|
||||||
|
to: ${{ env.GITHUB_CONTAINER_PREFIX }}/${{ github.repository_owner }}/${{ env.DOCKER_IMAGE }}:latest
|
||||||
|
only-severities: critical,high
|
||||||
|
ignore-unchanged: true
|
||||||
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
@@ -76,7 +76,7 @@ RUN apk add --no-cache \
|
|||||||
# Copy the requirements file into the build layer.
|
# Copy the requirements file into the build layer.
|
||||||
COPY ./src/requirements.txt /opt/wgdashboard/src
|
COPY ./src/requirements.txt /opt/wgdashboard/src
|
||||||
RUN if [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \
|
RUN if [ "$TARGETPLATFORM" = "linux/arm/v7" ]; then \
|
||||||
sed -i "s|psycopg\[binary\]==3.2.13|psycopg\[c\]==3.2.13|" /opt/wgdashboard/src/requirements.txt; \
|
sed -i 's|psycopg\[binary\]|psycopg[c]|' /opt/wgdashboard/src/requirements.txt; \
|
||||||
fi; \
|
fi; \
|
||||||
cat /opt/wgdashboard/src/requirements.txt
|
cat /opt/wgdashboard/src/requirements.txt
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
config_file="/data/wg-dashboard.ini"
|
config_file="/data/wg-dashboard.ini"
|
||||||
|
runtime_pid=""
|
||||||
|
|
||||||
trap 'stop_service' SIGTERM
|
trap 'stop_service' SIGTERM
|
||||||
|
|
||||||
# Hash password with bcrypt
|
# Hash password with bcrypt
|
||||||
hash_password() {
|
hash_password() {
|
||||||
python3 -c "import bcrypt; print(bcrypt.hashpw('$1'.encode(), bcrypt.gensalt(12)).decode())"
|
${WGDASH}/src/venv/bin/python3 -c "import bcrypt; print(bcrypt.hashpw('$1'.encode(), bcrypt.gensalt(12)).decode())"
|
||||||
}
|
}
|
||||||
|
|
||||||
# Function to set or update section/key/value in the INI file
|
# Function to set or update section/key/value in the INI file
|
||||||
@@ -22,7 +23,7 @@ set_ini() {
|
|||||||
if grep -q "^[[:space:]]*${key}[[:space:]]*=" "$config_file"; then
|
if grep -q "^[[:space:]]*${key}[[:space:]]*=" "$config_file"; then
|
||||||
current_value=$(grep "^[[:space:]]*${key}[[:space:]]*=" "$config_file" | cut -d= -f2- | xargs)
|
current_value=$(grep "^[[:space:]]*${key}[[:space:]]*=" "$config_file" | cut -d= -f2- | xargs)
|
||||||
|
|
||||||
# Don't display actual value if it's a password field
|
# Dont display actual value if it's a password field
|
||||||
if [[ "$key" == *"password"* ]]; then
|
if [[ "$key" == *"password"* ]]; then
|
||||||
if [ "$current_value" = "$value" ]; then
|
if [ "$current_value" = "$value" ]; then
|
||||||
echo "- $key is already set correctly (value hidden)"
|
echo "- $key is already set correctly (value hidden)"
|
||||||
@@ -52,10 +53,35 @@ set_ini() {
|
|||||||
|
|
||||||
stop_service() {
|
stop_service() {
|
||||||
echo "[WGDashboard] Stopping WGDashboard..."
|
echo "[WGDashboard] Stopping WGDashboard..."
|
||||||
/bin/bash ./wgd.sh stop
|
kill $runtime_pid
|
||||||
exit 0
|
exit 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
grab_pid() {
|
||||||
|
max_rounds="10"
|
||||||
|
round="0"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
round=$((round + 1))
|
||||||
|
|
||||||
|
if [[ -f ${WGDASH}/src/gunicorn.pid ]]; then
|
||||||
|
runtime_pid=$(cat ${WGDASH}/src/gunicorn.pid)
|
||||||
|
|
||||||
|
echo "Running as PID: ${runtime_pid}"
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $round -eq $max_rounds ]]; then
|
||||||
|
echo "Reached breaking point!"
|
||||||
|
return 1
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
sleep 0.5s
|
||||||
|
done
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
echo "------------------------- START ----------------------------"
|
echo "------------------------- START ----------------------------"
|
||||||
echo "Starting the WGDashboard Docker container."
|
echo "Starting the WGDashboard Docker container."
|
||||||
|
|
||||||
@@ -189,25 +215,60 @@ start_and_monitor() {
|
|||||||
|
|
||||||
# Actually starting WGDashboard
|
# Actually starting WGDashboard
|
||||||
echo "Starting WGDashboard directly with Gunicorn..."
|
echo "Starting WGDashboard directly with Gunicorn..."
|
||||||
/opt/wgdashboard/src/venv/bin/python3 ./venv/bin/gunicorn --config ./gunicorn.conf.py
|
|
||||||
|
[[ ! -d ${WGDASH}/src/log ]] && mkdir ${WGDASH}/src/log
|
||||||
|
${WGDASH}/src/venv/bin/gunicorn --config ${WGDASH}/src/gunicorn.conf.py
|
||||||
|
|
||||||
|
if [ $? -ne 0 ]; then
|
||||||
|
echo "Loading WGDashboard failed... Look above for details."
|
||||||
|
fi
|
||||||
|
|
||||||
# Wait a second before continuing, to give the python program some time to get ready.
|
# Wait a second before continuing, to give the python program some time to get ready.
|
||||||
sleep 1
|
|
||||||
echo -e "\nEnsuring container continuation."
|
echo -e "\nEnsuring container continuation."
|
||||||
|
|
||||||
# Find and monitor log file
|
max_rounds="10"
|
||||||
local logdir="${WGDASH}/src/log"
|
round="0"
|
||||||
latestErrLog=$(find "$logdir" -name "error_*.log" -type f -print | sort -r | head -n 1)
|
|
||||||
|
|
||||||
# Only tail the logs if they are found
|
# Hang in there for 10s for Gunicorn to get ready
|
||||||
if [ -n "$latestErrLog" ]; then
|
while true; do
|
||||||
tail -f "$latestErrLog" &
|
round=$((round + 1))
|
||||||
# Wait for the tail process to end.
|
latest_error=$(ls -t ${WGDASH}/src/log/error_*.log 2> /dev/null | head -n 1)
|
||||||
wait $!
|
|
||||||
else
|
if [[ $round -eq $max_rounds ]]; then
|
||||||
echo "No log files found to tail. Something went wrong, exiting..."
|
echo "Reached breaking point!"
|
||||||
|
break
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -z $latest_error ]]; then
|
||||||
|
echo -e "Logs not yet present! Retrying in 1 second!"
|
||||||
|
sleep 1s
|
||||||
|
|
||||||
|
else
|
||||||
|
break
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -z $latest_error ]]; then
|
||||||
|
echo -e "No error logs founds... Please investigate.\nExiting in 3 minutes..."
|
||||||
|
sleep 180s
|
||||||
exit 1
|
exit 1
|
||||||
|
|
||||||
|
else
|
||||||
|
tail -f "$latest_error" &
|
||||||
|
tail_pid=$!
|
||||||
|
|
||||||
|
echo "Grabbing PID..."
|
||||||
|
grab_pid &
|
||||||
|
|
||||||
|
wait $tail_pid
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo "The blocking command has been broken! Script will exit in 3 minutes... Investigate!"
|
||||||
|
sleep 180s
|
||||||
|
exit 1
|
||||||
}
|
}
|
||||||
|
|
||||||
# Main execution flow
|
# Main execution flow
|
||||||
|
|||||||
@@ -23,4 +23,4 @@ pythonpath = "., ./modules"
|
|||||||
|
|
||||||
print(f"[Gunicorn] WGDashboard w/ Gunicorn will be running on {bind}", flush=True)
|
print(f"[Gunicorn] WGDashboard w/ Gunicorn will be running on {bind}", flush=True)
|
||||||
print(f"[Gunicorn] Access log file is at {accesslog}", flush=True)
|
print(f"[Gunicorn] Access log file is at {accesslog}", flush=True)
|
||||||
print(f"[Gunicorn] Error log file is at {errorlog}", flush=True)
|
print(f"[Gunicorn] Error log file is at {errorlog}", flush=True)
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ requests==2.32.5
|
|||||||
tcconfig==0.30.1
|
tcconfig==0.30.1
|
||||||
sqlalchemy==2.0.44
|
sqlalchemy==2.0.44
|
||||||
sqlalchemy_utils==0.42.0
|
sqlalchemy_utils==0.42.0
|
||||||
psycopg[binary]==3.2.13
|
psycopg[binary]==3.3.2
|
||||||
PyMySQL==1.1.2
|
PyMySQL==1.1.2
|
||||||
tzlocal==5.3.1
|
tzlocal==5.3.1
|
||||||
python-jose==3.5.0
|
python-jose==3.5.0
|
||||||
pydantic==2.12.4
|
pydantic==2.12.5
|
||||||
|
|||||||
1143
src/static/app/package-lock.json
generated
1143
src/static/app/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "app",
|
"name": "app",
|
||||||
"version": "4.3.0.2",
|
"version": "4.3.0.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"module": "es2022",
|
"module": "es2022",
|
||||||
@@ -12,11 +12,11 @@
|
|||||||
"preview": "vite preview"
|
"preview": "vite preview"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@volar/language-server": "2.4.23",
|
"@volar/language-server": "2.4.26",
|
||||||
"@vue/language-server": "3.1.3",
|
"@vue/language-server": "3.1.8",
|
||||||
"@vuepic/vue-datepicker": "^12.0.1",
|
"@vuepic/vue-datepicker": "^12.1.0",
|
||||||
"@vueuse/core": "^14.0.0",
|
"@vueuse/core": "^14.0.0",
|
||||||
"@vueuse/shared": "^14.0.0",
|
"@vueuse/shared": "^14.1.0",
|
||||||
"animate.css": "^4.1.1",
|
"animate.css": "^4.1.1",
|
||||||
"bootstrap": "^5.3.2",
|
"bootstrap": "^5.3.2",
|
||||||
"bootstrap-icons": "^1.11.3",
|
"bootstrap-icons": "^1.11.3",
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
"fuse.js": "^7.0.0",
|
"fuse.js": "^7.0.0",
|
||||||
"i": "^0.3.7",
|
"i": "^0.3.7",
|
||||||
"is-cidr": "^6.0.1",
|
"is-cidr": "^6.0.1",
|
||||||
"npm": "^11.6.2",
|
"npm": "^11.6.4",
|
||||||
"ol": "^10.7.0",
|
"ol": "^10.7.0",
|
||||||
"pinia": "^3.0.3",
|
"pinia": "^3.0.3",
|
||||||
"pinia-plugin-persistedstate": "^4.7.1",
|
"pinia-plugin-persistedstate": "^4.7.1",
|
||||||
|
|||||||
Reference in New Issue
Block a user