1
0
mirror of https://github.com/donaldzou/WGDashboard.git synced 2024-11-06 16:00:28 +01:00

Fixed Gunicorn issue, continue on Peer Schedule Job

This commit is contained in:
Donald Zou 2024-06-19 17:09:58 +08:00
parent 9baefec541
commit 6c529a6908
6 changed files with 127 additions and 62 deletions

View File

@ -1546,29 +1546,30 @@ def gunicornConfig():
return app_ip, app_port return app_ip, app_port
def runGunicorn(): # def runGunicorn():
sqldb = sqlite3.connect(os.path.join(CONFIGURATION_PATH, 'db', 'wgdashboard.db'), check_same_thread=False) # sqldb = sqlite3.connect(os.path.join(CONFIGURATION_PATH, 'db', 'wgdashboard.db'), check_same_thread=False)
sqldb.row_factory = sqlite3.Row # sqldb.row_factory = sqlite3.Row
cursor = sqldb.cursor() # cursor = sqldb.cursor()
_, app_ip = DashboardConfig.GetConfig("Server", "app_ip") # _, app_ip = DashboardConfig.GetConfig("Server", "app_ip")
_, app_port = DashboardConfig.GetConfig("Server", "app_port") # _, app_port = DashboardConfig.GetConfig("Server", "app_port")
WireguardConfigurations = _getConfigurationList() # WireguardConfigurations = _getConfigurationList()
bgThread = threading.Thread(target=backGroundThread) # bgThread = threading.Thread(target=backGroundThread)
bgThread.daemon = True # bgThread.daemon = True
bgThread.start() # bgThread.start()
return app # return app
sqldb = sqlite3.connect(os.path.join(CONFIGURATION_PATH, 'db', 'wgdashboard.db'), check_same_thread=False)
sqldb.row_factory = sqlite3.Row
cursor = sqldb.cursor()
_, app_ip = DashboardConfig.GetConfig("Server", "app_ip")
_, app_port = DashboardConfig.GetConfig("Server", "app_port")
_, WG_CONF_PATH = DashboardConfig.GetConfig("Server", "wg_conf_path")
WireguardConfigurations = _getConfigurationList()
bgThread = threading.Thread(target=backGroundThread)
bgThread.daemon = True
bgThread.start()
if __name__ == "__main__": if __name__ == "__main__":
sqldb = sqlite3.connect(os.path.join(CONFIGURATION_PATH, 'db', 'wgdashboard.db'), check_same_thread=False)
sqldb.row_factory = sqlite3.Row
cursor = sqldb.cursor()
_, app_ip = DashboardConfig.GetConfig("Server", "app_ip")
_, app_port = DashboardConfig.GetConfig("Server", "app_port")
_, WG_CONF_PATH = DashboardConfig.GetConfig("Server", "wg_conf_path")
WireguardConfigurations = _getConfigurationList()
bgThread = threading.Thread(target=backGroundThread)
bgThread.daemon = True
bgThread.start()
app.run(host=app_ip, debug=True, port=app_port) app.run(host=app_ip, debug=True, port=app_port)

View File

@ -4,8 +4,8 @@ import dashboard
app_host, app_port = dashboard.gunicornConfig() app_host, app_port = dashboard.gunicornConfig()
worker_class = 'gthread' worker_class = 'gthread'
workers = multiprocessing.cpu_count() * 2 + 1 workers = 4
threads = 2 threads = 2
bind = f"{app_host}:{app_port}" bind = f"{app_host}:{app_port}"
daemon = True daemon = True
pidfile = './gunicorn.pid' pidfile = './gunicorn.pid'

View File

@ -16,19 +16,26 @@ export default {
Field: [ Field: [
{ {
display: "Total Received", display: "Total Received",
value: "total_receive" value: "total_receive",
unit: "GB",
type: 'number'
}, },
{ {
display: "Total Sent", display: "Total Sent",
value: "total_sent" value: "total_sent",
unit: "GB",
type: 'number'
}, },
{ {
display: "Total Data", display: "Total Data",
value: "total_data" value: "total_data",
unit: "GB",
type: 'number'
}, },
{ {
display: "Date", display: "Date",
value: "date" value: "date",
type: 'date'
} }
], ],
Operator: [ Operator: [
@ -62,8 +69,7 @@ export default {
}, },
} }
}, }
} }
</script> </script>
@ -78,22 +84,15 @@ export default {
<button type="button" class="btn-close ms-auto" @click="this.$emit('close')"></button> <button type="button" class="btn-close ms-auto" @click="this.$emit('close')"></button>
</div> </div>
<div class="card-body px-4 pb-4 pt-0"> <div class="card-body px-4 pb-4 pt-0">
<div class="d-flex"> <!-- <div class="d-flex gap-2 mb-3">-->
<small class="text-muted"> <!-- <small>{{selectedPeer.name ? selectedPeer.name : "Untitled Peer"}}</small>-->
Name <!-- <small class="ms-auto"><samp>{{this.selectedPeer.id}}</samp></small>-->
</small> <!-- </div>-->
<small class="ms-auto">{{selectedPeer.name ? selectedPeer.name : "Untitled Peer"}}</small>
</div>
<div class="mb-4 d-flex">
<small class="text-muted">
Public Key
</small>
<small class="ms-auto"><samp>{{this.selectedPeer.id}}</samp></small>
</div>
<SchedulePeerJob <SchedulePeerJob
:dropdowns="this.dropdowns" :dropdowns="this.dropdowns"
:job="job" v-for="job in this.selectedPeer.jobs"> :pjob="job" v-for="job in this.selectedPeer.jobs">
</SchedulePeerJob> </SchedulePeerJob>
</div> </div>
</div> </div>

View File

@ -6,6 +6,7 @@ export default {
props: { props: {
options: Array, options: Array,
data: String, data: String,
edit: false
}, },
mounted() { mounted() {
console.log(this.options) console.log(this.options)
@ -19,8 +20,8 @@ export default {
</script> </script>
<template> <template>
<div class="dropdown"> <div class="dropdown scheduleDropdown">
<button class="btn btn-sm btn-outline-primary rounded-3" type="button" data-bs-toggle="dropdown" aria-expanded="false"> <button class="btn btn-sm btn-outline-primary rounded-3" :class="{disabled: !edit}" type="button" data-bs-toggle="dropdown" aria-expanded="false">
<samp>{{this.currentSelection.display}}</samp> <samp>{{this.currentSelection.display}}</samp>
</button> </button>
<ul class="dropdown-menu rounded-3 shadow" style="font-size: 0.875rem; width: 200px"> <ul class="dropdown-menu rounded-3 shadow" style="font-size: 0.875rem; width: 200px">
@ -35,5 +36,8 @@ export default {
</template> </template>
<style scoped> <style scoped>
.btn.disabled{
opacity: 1;
background-color: rgba(13, 110, 253, 0.09);
}
</style> </style>

View File

@ -6,8 +6,44 @@ export default {
components: {ScheduleDropdown}, components: {ScheduleDropdown},
props: { props: {
dropdowns: Array[Object], dropdowns: Array[Object],
job: Object pjob: Object
} },
data(){
return {
job: Object,
inputType: undefined,
edit: false
}
},
beforeMount() {
this.job = JSON.parse(JSON.stringify(this.pjob))
},
methods: {
save(){
if (this.job.Field && this.job.Operator && this.job.Action && this.job.Value){
if (this.job.Field === 'date'){
this.job.Value = new Date(this.job.Value).getTime();
}
}else{
this.alert();
}
},
alert(){
let animation = "animate__flash";
let dropdowns = this.$el.querySelectorAll(".scheduleDropdown");
let inputs = this.$el.querySelectorAll("input");
dropdowns.forEach(x => x.classList.add("animate__animated", animation))
inputs.forEach(x => x.classList.add("animate__animated", animation))
setTimeout(() => {
dropdowns.forEach(x => x.classList.remove("animate__animated", animation))
inputs.forEach(x => x.classList.remove("animate__animated", animation))
}, 2000)
},
reset(){
this.job = JSON.parse(JSON.stringify(this.pjob));
this.edit = false;
}
},
} }
</script> </script>
@ -16,47 +52,71 @@ export default {
<div class="card-header bg-transparent text-muted border-0"> <div class="card-header bg-transparent text-muted border-0">
<small class="d-flex"> <small class="d-flex">
<strong class="me-auto">Job ID</strong> <strong class="me-auto">Job ID</strong>
{{this.job.JobID}} <samp>{{this.job.JobID}}</samp>
</small> </small>
</div> </div>
<div class="card-body pt-1"> <div class="card-body pt-1" style="font-family: var(--bs-font-monospace)">
<div class="d-flex gap-3 align-items-center mb-2"> <div class="d-flex gap-3 align-items-center mb-2">
<samp> <samp>
if if
</samp> </samp>
<ScheduleDropdown <ScheduleDropdown
:edit="edit"
:options="this.dropdowns.Field" :options="this.dropdowns.Field"
:data="this.job.Field" :data="this.job.Field"
@update="(value) => this.job.Field = value" @update="(value) => {this.job.Field = value}"
></ScheduleDropdown> ></ScheduleDropdown>
<samp> <samp>
is is
</samp> </samp>
<ScheduleDropdown <ScheduleDropdown
:edit="edit"
:options="this.dropdowns.Operator" :options="this.dropdowns.Operator"
:data="this.job.Operator" :data="this.job.Operator"
@update="(value) => this.job.Operator = value" @update="(value) => this.job.Operator = value"
></ScheduleDropdown> ></ScheduleDropdown>
<input class="form-control form-control-sm form-control-dark rounded-3 flex-grow-1" style="width: auto"> <input class="form-control form-control-sm form-control-dark rounded-3 flex-grow-1"
:disabled="!edit"
type="datetime-local"
v-if="this.job.Field === 'date'"
v-model="this.job.Value"
style="width: auto">
<input class="form-control form-control-sm form-control-dark rounded-3 flex-grow-1"
:disabled="!edit"
v-else
v-model="this.job.Value"
style="width: auto">
<samp> <samp>
{ {{this.dropdowns.Field.find(x => x.value === this.job.Field).unit}} {
</samp> </samp>
</div> </div>
<div class="px-5 d-flex gap-3 align-items-center"> <div class="px-5 d-flex gap-3 align-items-center">
<samp> <samp>execute</samp>
execute
</samp>
<ScheduleDropdown <ScheduleDropdown
:edit="edit"
:options="this.dropdowns.Action" :options="this.dropdowns.Action"
:data="this.job.Action" :data="this.job.Action"
@update="(value) => this.job.Action = value" @update="(value) => this.job.Action = value"
></ScheduleDropdown> ></ScheduleDropdown>
<samp> <samp>;</samp>
;
</samp>
</div> </div>
<div> <div class="d-flex gap-3">
<samp>}</samp> <samp>}</samp>
<div class="ms-auto d-flex gap-3" v-if="!this.edit">
<a role="button"
class="ms-auto text-decoration-none"
@click="this.edit = true">[E] Edit</a>
<a role="button"
class=" text-danger text-decoration-none">[D] Delete</a>
</div>
<div class="ms-auto d-flex gap-3" v-else>
<a role="button"
class="text-secondary text-decoration-none"
@click="this.reset()">[C] Cancel</a>
<a role="button"
class="text-primary ms-auto text-decoration-none"
@click="this.save()">[S] Save</a>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,6 +1,6 @@
#!/bin/bash #!/bin/bash
# wgd.sh - Copyright(C) 2021 Donald Zou [https://github.com/donaldzou] # wgd.sh - Copyright(C) 2024 Donald Zou [https://github.com/donaldzou]
# Under Apache-2.0 License # Under Apache-2.0 License
app_name="dashboard.py" app_name="dashboard.py"
app_official_name="WGDashboard" app_official_name="WGDashboard"
@ -102,7 +102,8 @@ gunicorn_start () {
export PATH=$PATH:/usr/local/bin:$HOME/.local/bin export PATH=$PATH:/usr/local/bin:$HOME/.local/bin
fi fi
gunicorn --access-logfile log/access_"$d".log \ gunicorn --access-logfile log/access_"$d".log \
--error-logfile log/error_"$d".log 'dashboard:runGunicorn()' --log-level 'debug' --capture-output \
--error-logfile log/error_"$d".log 'dashboard:app'
printf "| Log files is under log/ |\n" printf "| Log files is under log/ |\n"
printf "%s\n" "$dashes" printf "%s\n" "$dashes"
} }