mirror of
https://github.com/iFargle/headscale-webui.git
synced 2026-03-16 09:15:39 +01:00
Final update for v0.3.0 - Add error checks before page loads
This commit is contained in:
2
Jenkinsfile
vendored
2
Jenkinsfile
vendored
@@ -5,7 +5,7 @@ pipeline {
|
||||
label 'linux-x64'
|
||||
}
|
||||
environment {
|
||||
APP_VERSION = 'v0.2.5'
|
||||
APP_VERSION = 'v0.3.0'
|
||||
BUILD_DATE = ''
|
||||
}
|
||||
options {
|
||||
|
||||
@@ -29,11 +29,9 @@ Allows you to do the following:
|
||||
3. BASE_PATH - This will be the path your server is served on. Because the Windows Tailscale GUI expects <HS_SERVER/admin>, I usually put this as "/admin"
|
||||
4. KEY - Your encryption key to store your headscale API key on disk. Generate a new one with "openssl rand -base64 32". Do not forget the quotations around the key when entering.
|
||||
2. You will also need to change the volumes:
|
||||
1. /data - Where your encryption key will reside. Can be anywhere
|
||||
1. /data - Where your encryption key will reside. Can be anywhere writable by UID 1000
|
||||
2. /etc/headscale/ - This is your Headscale configuration file.
|
||||
3. Update the build context location to the directory with the Dockerfile.
|
||||
1. Example: If Dockerfile is in /home/username/headscale-webui, your context will be:
|
||||
* context: /home/username/headscale-webui/
|
||||
3. Make sure the host path for /data is readable and writable to UID 1000, otherwise writing the key to disk will fail.
|
||||
|
||||
## Traefik example with SSL:
|
||||
* docker-compose labels:
|
||||
|
||||
@@ -9,5 +9,5 @@ services:
|
||||
- BASE_PATH="/admin" # Default, can be anything you want. Tailscale's Windows app expects "HS_SERVER/admin"
|
||||
- KEY="YourKeyBetweenQuotes" # Generate with "openssl rand -base64 32"
|
||||
volumes:
|
||||
- ./volume:/data # Headscale-WebUI's storage
|
||||
- ./volume:/data # Headscale-WebUI's storage. Make sure ./volume is readable by UID 1000 (chown 1000:1000 ./volume)
|
||||
- ./headscale/config/:/etc/headscale/:ro # Headscale's config storage location. Used to read your Headscale config.
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/bin/sh
|
||||
. /app/.venv/bin/activate
|
||||
chown -R 1000:1000 /data
|
||||
exec "$@"
|
||||
11
helper.py
11
helper.py
@@ -117,7 +117,6 @@ def startup_checks():
|
||||
|
||||
# Return an error message if things fail.
|
||||
# Return a formatted error message for EACH fail.
|
||||
# Otherwise, return "Pass"
|
||||
checks_passed = True
|
||||
|
||||
# Check 1: See if the Headscale server is reachable:
|
||||
@@ -134,7 +133,7 @@ def startup_checks():
|
||||
if os.access('/data/', os.W_OK): data_writable = True
|
||||
else: checks_passed = False
|
||||
|
||||
# Check 4/5: See if /data/key.txt exists and is rw:
|
||||
# Check 4/5/6: See if /data/key.txt exists and is rw:
|
||||
file_readable = False
|
||||
file_writable = False
|
||||
file_exists = False
|
||||
@@ -145,7 +144,7 @@ def startup_checks():
|
||||
if os.access('/data/key.txt', os.W_OK): file_writable = True
|
||||
else: checks_passed = False
|
||||
|
||||
if checks_passed: return "Pass"
|
||||
if checks_passed: return True
|
||||
|
||||
messageHTML = ""
|
||||
# Generate the message:
|
||||
@@ -159,7 +158,7 @@ def startup_checks():
|
||||
messageHTML += format_error_message("Error", "Headscale unreachable", message)
|
||||
if not data_writable:
|
||||
message = """
|
||||
<p>/data/ is not writable. Please ensure your
|
||||
<p>/data is not writable. Please ensure your
|
||||
permissions are correct. /data mount should be writable
|
||||
by UID/GID 1000:1000.</p>
|
||||
"""
|
||||
@@ -167,14 +166,14 @@ def startup_checks():
|
||||
messageHTML += format_error_message("Error", "/data not writable", message)
|
||||
if not data_readable:
|
||||
message = """
|
||||
<p>/data/ is not readable. Please ensure your
|
||||
<p>/data is not readable. Please ensure your
|
||||
permissions are correct. /data mount should be readable
|
||||
by UID/GID 1000:1000.</p>
|
||||
"""
|
||||
|
||||
messageHTML += format_error_message("Error", "/data not readable", message)
|
||||
|
||||
if file_exists:
|
||||
if file_exists: # If it doesn't exist, we assume the user hasn't created it yet. Just redirect to the settings page to enter an API Key
|
||||
if not file_writable:
|
||||
message = """
|
||||
<p>/data/key.txt is not writable. Please ensure your
|
||||
|
||||
@@ -48,7 +48,7 @@ def overview_page():
|
||||
# If the API key fails, redirect to the settings page:
|
||||
if not helper.key_test(): return redirect(BASE_PATH+url_for('settings_page'))
|
||||
# General error checks. See the function for more info:
|
||||
if helper.startup_checks() != "Pass": return redirect(BASE_PATH+url_for('error_page'))
|
||||
if not helper.startup_checks(): return redirect(BASE_PATH+url_for('error_page'))
|
||||
|
||||
return render_template('overview.html',
|
||||
render_page = renderer.render_overview(),
|
||||
@@ -62,7 +62,7 @@ def machines_page():
|
||||
# If the API key fails, redirect to the settings page:
|
||||
if not helper.key_test(): return redirect(BASE_PATH+url_for('settings_page'))
|
||||
# General error checks. See the function for more info:
|
||||
if helper.startup_checks() != "Pass": return redirect(BASE_PATH+url_for('error_page'))
|
||||
if not helper.startup_checks(): return redirect(BASE_PATH+url_for('error_page'))
|
||||
|
||||
cards = renderer.render_machines_cards()
|
||||
return render_template('machines.html',
|
||||
@@ -78,7 +78,7 @@ def users_page():
|
||||
# If the API key fails, redirect to the settings page:
|
||||
if not helper.key_test(): return redirect(BASE_PATH+url_for('settings_page'))
|
||||
# General error checks. See the function for more info:
|
||||
if helper.startup_checks() != "Pass": return redirect(BASE_PATH+url_for('error_page'))
|
||||
if not helper.startup_checks(): return redirect(BASE_PATH+url_for('error_page'))
|
||||
|
||||
cards = renderer.render_users_cards()
|
||||
return render_template('users.html',
|
||||
@@ -92,7 +92,7 @@ def users_page():
|
||||
@app.route('/settings', methods=('GET', 'POST'))
|
||||
def settings_page():
|
||||
# General error checks. See the function for more info:
|
||||
if helper.startup_checks() != "Pass": return redirect(BASE_PATH+url_for('error_page'))
|
||||
if not helper.startup_checks(): return redirect(BASE_PATH+url_for('error_page'))
|
||||
url = headscale.get_url()
|
||||
api_key = headscale.get_api_key()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user