mirror of
https://github.com/mynodebtc/mynode.git
synced 2024-12-25 22:18:07 +00:00
Add Watchtower Page
This commit is contained in:
parent
30110f1994
commit
75ee479249
|
@ -36,30 +36,6 @@ Additional myNode guides would be helpful for users attempting to use various to
|
|||
|
||||
GitHub: https://github.com/mynodebtc/mynodebtc.github.io
|
||||
|
||||
## Add Page to Manage Lightning Watchtower
|
||||
|
||||
Known active efforts: none
|
||||
|
||||
Payout: 250k sats
|
||||
|
||||
Users that want to use watchtower will likely prefer more detailed information available via the myNode UI. Watchtower integration is currently limited to enabling and disabling watchtower functionality along with viewing the watchtower URI.
|
||||
|
||||
The watchtower config for tor is already setup and should be ready to use.
|
||||
|
||||
Acceptance Criteria:
|
||||
- New link on Lightning page going to watchtower-specific page
|
||||
- New watchtower page
|
||||
- View watchtower clients, status, and details (lncli wtclient [towers, tower, stats, policy, ...])
|
||||
- Add new tower (lncli wtclient add ...)
|
||||
- Remove tower (lncli wtclient remove ...)
|
||||
- Should work if testnet is enabled
|
||||
|
||||
Helpful links:
|
||||
|
||||
https://github.com/lightningnetwork/lnd/blob/master/docs/watchtower.md
|
||||
|
||||
https://github.com/openoms/lightning-node-management/blob/master/advanced-tools/watchtower.md
|
||||
|
||||
|
||||
# Claimed Bounties
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import re
|
|||
import datetime
|
||||
import urllib
|
||||
import random
|
||||
import base64
|
||||
from device_info import *
|
||||
from threading import Timer
|
||||
from utilities import *
|
||||
|
@ -28,7 +29,10 @@ lightning_wallet_balance = None
|
|||
lightning_transactions = None
|
||||
lightning_payments = None
|
||||
lightning_invoices = None
|
||||
lightning_watchtower_server_info = None
|
||||
lightning_watchtower_server_info = {}
|
||||
lightning_watchtower_client_towers = {}
|
||||
lightning_watchtower_client_stats = {}
|
||||
lightning_watchtower_client_policy = {}
|
||||
lightning_desync_count = 0
|
||||
lightning_update_count = 0
|
||||
|
||||
|
@ -38,6 +42,19 @@ TLS_CERT_FILE = "/mnt/hdd/mynode/lnd/tls.cert"
|
|||
LND_REST_PORT = "10080"
|
||||
|
||||
# Functions
|
||||
def run_lncli_command(cmd):
|
||||
try:
|
||||
base = "lncli "
|
||||
base += "--lnddir=/mnt/hdd/mynode/lnd "
|
||||
if is_testnet_enabled():
|
||||
base += "--network=testnet "
|
||||
cmd = cmd.replace("lncli ", base)
|
||||
output = subprocess.check_output(cmd, shell=True)
|
||||
return output
|
||||
except Exception as e:
|
||||
log_message("ERROR in run_lncli_command: {}".format(str(e)))
|
||||
return None
|
||||
|
||||
def update_lightning_info():
|
||||
global lightning_info
|
||||
global lightning_peers
|
||||
|
@ -48,6 +65,9 @@ def update_lightning_info():
|
|||
global lightning_payments
|
||||
global lightning_invoices
|
||||
global lightning_watchtower_server_info
|
||||
global lightning_watchtower_client_towers
|
||||
global lightning_watchtower_client_stats
|
||||
global lightning_watchtower_client_policy
|
||||
global lightning_desync_count
|
||||
global lightning_update_count
|
||||
global lnd_ready
|
||||
|
@ -88,6 +108,18 @@ def update_lightning_info():
|
|||
lightning_wallet_balance = lnd_get("/balance/blockchain")
|
||||
if is_watchtower_enabled():
|
||||
lightning_watchtower_server_info = lnd_get_v2("/watchtower/server")
|
||||
towers = lnd_get_v2("/watchtower/client?include_sessions=1")
|
||||
tower_details = []
|
||||
if towers != None and "towers" in towers:
|
||||
for tower in towers["towers"]:
|
||||
if "pubkey" in tower and tower["active_session_candidate"]:
|
||||
pubkey_decoded = base64.b64decode(tower['pubkey'])
|
||||
pubkey_b16 = to_string(base64.b16encode( pubkey_decoded )).lower()
|
||||
tower["pubkey_b16"] = pubkey_b16
|
||||
tower_details.append(tower)
|
||||
lightning_watchtower_client_towers = tower_details
|
||||
lightning_watchtower_client_stats = lnd_get_v2("/watchtower/client/stats")
|
||||
lightning_watchtower_client_policy = lnd_get_v2("/watchtower/client/policy")
|
||||
|
||||
# Poll slower (make sure we gather data early)
|
||||
if lightning_update_count < 30 or lightning_update_count % 2 == 0:
|
||||
|
@ -367,7 +399,46 @@ def get_lightning_payments_and_invoices():
|
|||
|
||||
def get_lightning_watchtower_server_info():
|
||||
global lightning_watchtower_server_info
|
||||
return copy.deepcopy(lightning_watchtower_server_info)
|
||||
server_info = copy.deepcopy(lightning_watchtower_server_info)
|
||||
server_info["watchtower_server_uri"] = "..."
|
||||
|
||||
if server_info != None:
|
||||
try:
|
||||
if "uris" in server_info and len(server_info['uris']) > 0:
|
||||
first_uri = True
|
||||
text = ""
|
||||
for uri in server_info['uris']:
|
||||
if first_uri:
|
||||
first_uri = False
|
||||
else:
|
||||
text += "<br/>"
|
||||
text += uri
|
||||
server_info["watchtower_server_uri"] = text
|
||||
elif "pubkey" in server_info or "listeners" in server_info:
|
||||
server_info["watchtower_server_uri"] = ""
|
||||
if "pubkey" in server_info:
|
||||
server_info["watchtower_server_uri"] += server_info["pubkey"]
|
||||
#if "listeners":
|
||||
# server_info["watchtower_server_uri"] += "listeners: " + watchtower_server_info["listeners"][0]
|
||||
except:
|
||||
return server_info
|
||||
|
||||
return server_info
|
||||
|
||||
def get_lightning_watchtower_client_towers():
|
||||
global lightning_watchtower_client_towers
|
||||
towers = copy.deepcopy(lightning_watchtower_client_towers)
|
||||
return towers
|
||||
|
||||
def get_lightning_watchtower_client_stats():
|
||||
global lightning_watchtower_client_stats
|
||||
stats = copy.deepcopy(lightning_watchtower_client_stats)
|
||||
return stats
|
||||
|
||||
def get_lightning_watchtower_client_policy():
|
||||
global lightning_watchtower_client_policy
|
||||
policy = copy.deepcopy(lightning_watchtower_client_policy)
|
||||
return policy
|
||||
|
||||
def is_lnd_ready():
|
||||
global lnd_ready
|
||||
|
@ -606,15 +677,13 @@ def get_lnd_alias_file_data():
|
|||
return "ERROR"
|
||||
|
||||
def is_watchtower_enabled():
|
||||
if os.path.isfile("/mnt/hdd/mynode/settings/.watchtower_enabled"):
|
||||
return True
|
||||
return False
|
||||
return settings_file_exists("watchtower_enabled")
|
||||
|
||||
def enable_watchtower():
|
||||
touch("/mnt/hdd/mynode/settings/.watchtower_enabled")
|
||||
create_settings_file("watchtower_enabled")
|
||||
|
||||
def disable_watchtower():
|
||||
delete_file("/mnt/hdd/mynode/settings/.watchtower_enabled")
|
||||
delete_settings_file("watchtower_enabled")
|
||||
|
||||
# Only call from www process which has data
|
||||
def update_lightning_json_cache():
|
||||
|
|
|
@ -164,23 +164,6 @@ def page_lnd():
|
|||
payments = get_lightning_payments()
|
||||
invoices = get_lightning_invoices()
|
||||
|
||||
watchtower_server_info = get_lightning_watchtower_server_info()
|
||||
watchtower_text= "..."
|
||||
if watchtower_server_info != None:
|
||||
try:
|
||||
if "uris" in watchtower_server_info and len(watchtower_server_info['uris']) > 0:
|
||||
watchtower_text = watchtower_server_info['uris'][0]
|
||||
elif "pubkey" in watchtower_server_info or "listeners" in watchtower_server_info:
|
||||
watchtower_text = ""
|
||||
if "pubkey" in watchtower_server_info:
|
||||
watchtower_text += watchtower_server_info["pubkey"]
|
||||
#if "listeners":
|
||||
# watchtower_text += "listeners: " + watchtower_server_info["listeners"][0]
|
||||
else:
|
||||
watchtower_text = "missing info"
|
||||
except:
|
||||
watchtower_text = "error"
|
||||
|
||||
except Exception as e:
|
||||
templateData = {
|
||||
"title": "myNode Lightning Status",
|
||||
|
@ -225,7 +208,6 @@ def page_lnd():
|
|||
"channel_pending": format_sat_amount(balance_info["channel_pending"]),
|
||||
"wallet_balance": format_sat_amount(balance_info["wallet_balance"]),
|
||||
"wallet_pending": format_sat_amount(balance_info["wallet_pending"]),
|
||||
"watchtower_text": Markup(watchtower_text),
|
||||
"peers": peers,
|
||||
"channels": channels,
|
||||
"transactions": transactions,
|
||||
|
@ -537,7 +519,7 @@ def lnd_config_page():
|
|||
}
|
||||
return render_template('lnd_config.html', **templateData)
|
||||
|
||||
@mynode_lnd.route("/lnd/set_watchtower_enabled")
|
||||
@mynode_lnd.route("/lnd/watchtower/set_watchtower_enabled")
|
||||
def lnd_set_watchtower_enabled_page():
|
||||
check_logged_in()
|
||||
|
||||
|
@ -549,7 +531,68 @@ def lnd_set_watchtower_enabled_page():
|
|||
restart_lnd()
|
||||
|
||||
flash("Watchtower settings updated!", category="message")
|
||||
return redirect(url_for(".page_lnd"))
|
||||
return redirect(url_for(".page_lnd_watchtower"))
|
||||
|
||||
@mynode_lnd.route("/lnd/watchtower")
|
||||
def page_lnd_watchtower():
|
||||
check_logged_in()
|
||||
|
||||
watchtower_server_info = get_lightning_watchtower_server_info()
|
||||
watchtower_client_towers = get_lightning_watchtower_client_towers()
|
||||
watchtower_client_stats = get_lightning_watchtower_client_stats()
|
||||
watchtower_client_policy = get_lightning_watchtower_client_policy()
|
||||
|
||||
templateData = {
|
||||
"title": "myNode Lightning Watchtower",
|
||||
"watchtower_server_enabled": is_watchtower_enabled(),
|
||||
"watchtower_server_uri": Markup(watchtower_server_info["watchtower_server_uri"]),
|
||||
"watchtower_client_towers": watchtower_client_towers,
|
||||
"watchtower_client_stats": watchtower_client_stats,
|
||||
"watchtower_client_policy": watchtower_client_policy,
|
||||
"header": "Lightning Watchtower",
|
||||
"ui_settings": read_ui_settings()
|
||||
}
|
||||
return render_template('lnd_watchtower.html', **templateData)
|
||||
|
||||
@mynode_lnd.route("/lnd/watchtower/add_tower", methods=["POST"])
|
||||
def page_lnd_watchtower_add_tower():
|
||||
check_logged_in()
|
||||
|
||||
if request.form.get("new_tower"):
|
||||
cmd = "lncli wtclient add {}".format(request.form.get("new_tower"))
|
||||
r = run_lncli_command(cmd)
|
||||
if r == None:
|
||||
flash("Error adding tower!", category="error")
|
||||
return redirect(url_for(".page_lnd_watchtower"))
|
||||
else:
|
||||
flash("Error adding tower - missing tower", category="error")
|
||||
return redirect(url_for(".page_lnd_watchtower"))
|
||||
|
||||
# Update Lightning Info
|
||||
update_lightning_info()
|
||||
|
||||
flash("Tower added!", category="message")
|
||||
return redirect(url_for(".page_lnd_watchtower"))
|
||||
|
||||
@mynode_lnd.route("/lnd/watchtower/remove_tower", methods=["GET"])
|
||||
def page_lnd_watchtower_remove_tower():
|
||||
check_logged_in()
|
||||
|
||||
if request.args.get("tower"):
|
||||
cmd = "lncli wtclient remove {}".format(request.args.get("tower"))
|
||||
r = run_lncli_command(cmd)
|
||||
if r == None:
|
||||
flash("Error removing tower!", category="error")
|
||||
return redirect(url_for(".page_lnd_watchtower"))
|
||||
else:
|
||||
flash("Error removing tower - missing tower", category="error")
|
||||
return redirect(url_for(".page_lnd_watchtower"))
|
||||
|
||||
# Update Lightning Info
|
||||
update_lightning_info()
|
||||
|
||||
flash("Tower removed!", category="message")
|
||||
return redirect(url_for(".page_lnd_watchtower"))
|
||||
|
||||
##############################################
|
||||
## LND API Calls
|
||||
|
|
|
@ -16,11 +16,14 @@ def get_latest_price():
|
|||
|
||||
def get_price_diff_24hrs():
|
||||
global price_data
|
||||
latest = get_latest_price()
|
||||
if len(price_data) > 0:
|
||||
old = price_data[0]["price"]
|
||||
if latest != "N/A" and old != "N/A":
|
||||
return latest - old
|
||||
try:
|
||||
latest = get_latest_price()
|
||||
if len(price_data) > 0:
|
||||
old = price_data[0]["price"]
|
||||
if latest != "N/A" and old != "N/A":
|
||||
return latest - old
|
||||
except Exception as e:
|
||||
log_message("ERROR get_price_diff_24hrs: {}".format(str(e)))
|
||||
return 0.0
|
||||
|
||||
def get_price_up_down_flat_24hrs():
|
||||
|
|
|
@ -107,21 +107,6 @@
|
|||
$("#copy_lit_password").show();
|
||||
}
|
||||
|
||||
$('#watchtower_enabled_checkbox').change(function () {
|
||||
$("#watchtower_enabled_save").show();
|
||||
});
|
||||
$("#watchtower_enabled_save").on("click", function() {
|
||||
enabled=$('#watchtower_enabled_checkbox').is(":checked")
|
||||
if (enabled)
|
||||
{
|
||||
window.location.href='/lnd/set_watchtower_enabled?enabled=1'
|
||||
}
|
||||
else
|
||||
{
|
||||
window.location.href='/lnd/set_watchtower_enabled?enabled=0'
|
||||
}
|
||||
});
|
||||
|
||||
function show_deposit_address(addr) {
|
||||
$("#lnd_deposit_address_text").html( addr );
|
||||
$("#lnd_deposit_address_qrcode").attr("src", "/api/get_qr_code_image?url="+addr);
|
||||
|
@ -257,14 +242,14 @@
|
|||
{% endif %}
|
||||
{% if wallet_exists %}
|
||||
<tr>
|
||||
<th>TLS Certification</th>
|
||||
<th>TLS Certificate</th>
|
||||
<td>
|
||||
<a class="ui-button ui-widget ui-corner-all mynode_button_small" style="width: 100px;" href="/lnd/tls.cert">download</a>
|
||||
<a class="ui-button ui-widget ui-corner-all mynode_button_small" style="width: 100px;" href="/lnd/regen_tls_cert">regenerate</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Macaroon Download</th>
|
||||
<th>Macaroons</th>
|
||||
<td>
|
||||
<a class="ui-button ui-widget ui-corner-all mynode_button_small" id="admin_macaroon" href="/lnd/admin.macaroon">admin</a>
|
||||
<a class="ui-button ui-widget ui-corner-all mynode_button_small" id="readonly_macaroon" href="/lnd/readonly.macaroon">readonly</a>
|
||||
|
@ -280,14 +265,9 @@
|
|||
</tr>
|
||||
{% endif %}
|
||||
<tr>
|
||||
<th>Watchtower Server</th>
|
||||
<th>Watchtower</th>
|
||||
<td>
|
||||
<label class="switch">
|
||||
<input type="checkbox" id="watchtower_enabled_checkbox" {% if watchtower_enabled %}checked{% endif %}>
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
<br/>
|
||||
<button id="watchtower_enabled_save" style="display: none; margin-top: 5px;" class="ui-button ui-widget ui-corner-all settings_button_small">Save</button>
|
||||
<a class="ui-button ui-widget ui-corner-all mynode_button_small" style="width: 100px;" href="/lnd/watchtower">open</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
|
@ -304,10 +284,12 @@
|
|||
{{alias}}
|
||||
</td>
|
||||
</tr>
|
||||
<!--
|
||||
<tr>
|
||||
<th>Ports (gRPC/REST)</th>
|
||||
<td>10009 / 10080</td>
|
||||
</tr>
|
||||
-->
|
||||
{% endif %}
|
||||
</table>
|
||||
</div>
|
||||
|
@ -348,16 +330,6 @@
|
|||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if wallet_logged_in and watchtower_enabled %}
|
||||
<!-- URI Tile / Row -->
|
||||
<div class="app_tile_row">
|
||||
<div class="info_tile">
|
||||
<div class="info_tile_header">Watchtower Server Pubkey/URI</div>
|
||||
<div class="info_tile_contents" style="font-size: 12px;">{{watchtower_text}}</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if wallet_exists and not wallet_logged_in %}
|
||||
<!-- Status Tile / Row (should be only shown short term) -->
|
||||
<div class="app_tile_row">
|
||||
|
|
209
rootfs/standard/var/www/mynode/templates/lnd_watchtower.html
Normal file
209
rootfs/standard/var/www/mynode/templates/lnd_watchtower.html
Normal file
|
@ -0,0 +1,209 @@
|
|||
<!DOCTYPE html lang="en">
|
||||
<head>
|
||||
<title>{{ title }}</title>
|
||||
{% include 'includes/head.html' %}
|
||||
|
||||
{% if refresh_rate is defined and refresh_rate is not none %}
|
||||
<meta http-equiv="refresh" content="{{ refresh_rate }}">
|
||||
{% endif %}
|
||||
|
||||
<script>
|
||||
function remove_tower(tower) {
|
||||
if ( confirm("Are you sure you want to remove tower "+tower+"?") ) {
|
||||
window.location = location.protocol+'//'+location.hostname+"/lnd/watchtower/remove_tower?tower="+tower
|
||||
}
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
|
||||
$('#watchtower_server_enabled_checkbox').change(function () {
|
||||
$("#watchtower_server_enabled_save").show();
|
||||
});
|
||||
$("#watchtower_server_enabled_save").on("click", function() {
|
||||
enabled=$('#watchtower_server_enabled_checkbox').is(":checked")
|
||||
if (enabled)
|
||||
{
|
||||
window.location.href='/lnd/watchtower/set_watchtower_enabled?enabled=1'
|
||||
}
|
||||
else
|
||||
{
|
||||
window.location.href='/lnd/watchtower/set_watchtower_enabled?enabled=0'
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{% include 'includes/logo_header.html' %}
|
||||
<div class="mynode_back_div">
|
||||
<a class="ui-button ui-widget ui-corner-all mynode_back" href="/"><span class="ui-icon ui-icon-home"></span>home </a>
|
||||
<a class="ui-button ui-widget ui-corner-all mynode_back" href="/lnd"><span class="ui-icon ui-icon-arrowthick-1-w"></span>back </a>
|
||||
</div>
|
||||
|
||||
{% include 'includes/message_display.html' %}
|
||||
|
||||
<div class="main_header">Watchtower Server</div>
|
||||
<br/>
|
||||
|
||||
<div class="app_tile_row">
|
||||
<div class="info_tile">
|
||||
<div class="info_tile_header">Status</div>
|
||||
<div class="info_tile_contents">
|
||||
<table class="info_table">
|
||||
<tr>
|
||||
<th>Enabled</th>
|
||||
<td>
|
||||
<label class="switch">
|
||||
<input type="checkbox" id="watchtower_server_enabled_checkbox" {% if watchtower_server_enabled %}checked{% endif %}>
|
||||
<span class="slider round"></span>
|
||||
</label>
|
||||
<br/>
|
||||
<button id="watchtower_server_enabled_save" style="display: none; margin-top: 5px;" class="ui-button ui-widget ui-corner-all settings_button_small">Save</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if watchtower_server_enabled %}
|
||||
<div class="app_tile_row">
|
||||
<div class="info_tile">
|
||||
<div class="info_tile_header">URI / Pubkey</div>
|
||||
<div class="info_tile_contents" style="font-size: 12px;">
|
||||
{{ watchtower_server_uri }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
|
||||
<br/>
|
||||
<div class="main_header">Watchtower Client</div>
|
||||
<br/>
|
||||
|
||||
<div class="app_tile_row">
|
||||
<div class="info_tile">
|
||||
<div class="info_tile_header">Status</div>
|
||||
<div class="info_tile_contents">
|
||||
Enabled
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app_tile_row">
|
||||
<div class="info_tile">
|
||||
<div class="info_tile_header">Active Towers</div>
|
||||
<div class="info_tile_contents">
|
||||
{% if watchtower_client_towers and watchtower_client_towers|length > 0%}
|
||||
<table class="info_table" style="font-size: 12px;" cellpadding=5>
|
||||
<tr>
|
||||
<th><b>URI(s)</b></th>
|
||||
<th><b>Sessions</b></th>
|
||||
<th> </th>
|
||||
</tr>
|
||||
{% for tower in watchtower_client_towers %}
|
||||
<!--
|
||||
{'pubkey': 'A7MWka/imgKNHBo2swdaVXMRBcOopDqzvMIO+rNN7DZI',
|
||||
'addresses': ['553e5qijayrejjtmzabwibaesge6lb34jegkn7fwvfcszl35a3uj24id.onion:9911'],
|
||||
'active_session_candidate': False,
|
||||
'num_sessions': 2,
|
||||
'sessions':
|
||||
[{'num_backups': 58,
|
||||
'num_pending_backups': 0,
|
||||
'max_backups': 1024,
|
||||
'sweep_sat_per_byte': 10,
|
||||
'sweep_sat_per_vbyte': 10},
|
||||
{'num_backups': 0,
|
||||
'num_pending_backups': 0,
|
||||
'max_backups': 1024,
|
||||
'sweep_sat_per_byte': 10,
|
||||
'sweep_sat_per_vbyte': 10}],
|
||||
'pubkey_b16': b'03B31691AFE29A028D1C1A36B3075A55731105C3A8A43AB3BCC20EFAB34DEC3648'}
|
||||
-->
|
||||
<tr>
|
||||
<td>
|
||||
<small>
|
||||
{% set first = True %}
|
||||
{% for addr in tower.addresses %}
|
||||
{% if first %} {% set first = False %} {% else %} <br/> {% endif %}
|
||||
{{tower.pubkey_b16}}@{{addr}}
|
||||
{% endfor %}
|
||||
</small>
|
||||
</td>
|
||||
<td>{{tower.num_sessions}}</td>
|
||||
<td><button onclick="remove_tower('{{tower.pubkey_b16}}')" class="ui-button ui-widget ui-corner-all mynode_button_small red"><span class="ui-icon ui-icon-trash"></span></button></td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
No active client towers
|
||||
{% endif %}
|
||||
|
||||
<br/><br/>
|
||||
<form action="/lnd/watchtower/add_tower" method="post">
|
||||
<input type="text" id="new_tower" name="new_tower" class="text ui-widget-content ui-corner-all" size="100" style="font-size: 14px;" placeholder="pubkey@address:9911"/>
|
||||
<input type="submit" class="ui-button ui-widget ui-corner-all mynode_button_small" value="Add">
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app_tile_row">
|
||||
<div class="info_tile">
|
||||
<div class="info_tile_header">Stats</div>
|
||||
<div class="info_tile_contents">
|
||||
<table class="info_table">
|
||||
<tr>
|
||||
<th>Backups</th>
|
||||
<td>{{watchtower_client_stats.num_backups}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Pending Backups</th>
|
||||
<td>{{watchtower_client_stats.num_pending_backups}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Failed Updates</th>
|
||||
<td>{{watchtower_client_stats.num_failed_backups}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Sessions Acquired</th>
|
||||
<td>{{watchtower_client_stats.num_sessions_acquired}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Sessions Exhausted</th>
|
||||
<td>{{watchtower_client_stats.num_sessions_exhausted}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="app_tile_row">
|
||||
<div class="info_tile">
|
||||
<div class="info_tile_header">Policy</div>
|
||||
<div class="info_tile_contents">
|
||||
<table class="info_table">
|
||||
<tr>
|
||||
<th>Max Updates</th>
|
||||
<td>{{watchtower_client_policy.max_updates}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Sweep sat/byte</th>
|
||||
<td>{{watchtower_client_policy.sweep_sat_per_byte}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Sweep sat/vbyte</th>
|
||||
<td>{{watchtower_client_policy.sweep_sat_per_vbyte}}</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% include 'includes/footer.html' %}
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in New Issue
Block a user