Add manual rescan control
This commit is contained in:
parent
d92b0f6b0e
commit
dc021d307b
9 changed files with 66 additions and 20 deletions
|
|
@ -370,7 +370,7 @@ const docTemplate = `{
|
|||
},
|
||||
"/rescan": {
|
||||
"get": {
|
||||
"description": "Manually trigger rescan",
|
||||
"description": "Manually trigger rescan and wait until the DB is updated",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -363,7 +363,7 @@
|
|||
},
|
||||
"/rescan": {
|
||||
"get": {
|
||||
"description": "Manually trigger rescan",
|
||||
"description": "Manually trigger rescan and wait until the DB is updated",
|
||||
"produces": [
|
||||
"application/json"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -345,7 +345,7 @@ paths:
|
|||
- network
|
||||
/rescan:
|
||||
get:
|
||||
description: Manually trigger rescan
|
||||
description: Manually trigger rescan and wait until the DB is updated
|
||||
produces:
|
||||
- application/json
|
||||
responses:
|
||||
|
|
|
|||
|
|
@ -25,14 +25,14 @@ func getVersion(c *gin.Context) {
|
|||
|
||||
// triggerRescan godoc
|
||||
// @Summary Rescan all interfaces now
|
||||
// @Description Manually trigger rescan
|
||||
// @Description Manually trigger rescan and wait until the DB is updated
|
||||
// @Tags system
|
||||
// @Produce json
|
||||
// @Success 200 {string} string "OK"
|
||||
// @Router /rescan [get]
|
||||
func triggerRescan(c *gin.Context) {
|
||||
routines.ScanRestart()
|
||||
c.Status(http.StatusOK)
|
||||
routines.ScanNow()
|
||||
c.IndentedJSON(http.StatusOK, "OK")
|
||||
}
|
||||
|
||||
// getConfig godoc
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package routines
|
|||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/aceberg/WatchYourLAN/internal/arp"
|
||||
|
|
@ -15,9 +16,21 @@ import (
|
|||
"github.com/aceberg/WatchYourLAN/internal/prometheus"
|
||||
)
|
||||
|
||||
var scanMu sync.Mutex
|
||||
|
||||
// ScanNow runs one scan immediately and waits until DB state is updated.
|
||||
func ScanNow() {
|
||||
scanMu.Lock()
|
||||
defer scanMu.Unlock()
|
||||
|
||||
foundHosts := arp.Scan(conf.AppConfig.Ifaces, conf.AppConfig.ArpArgs, conf.AppConfig.ArpStrs)
|
||||
foundHosts = check.EnrichHosts(foundHosts)
|
||||
|
||||
compareHosts(newFoundHostIndex(foundHosts))
|
||||
}
|
||||
|
||||
func startScan(quit chan bool) {
|
||||
var lastDate, nowDate, plusDate time.Time
|
||||
var foundHosts []models.Host
|
||||
|
||||
for {
|
||||
select {
|
||||
|
|
@ -29,15 +42,16 @@ func startScan(quit chan bool) {
|
|||
|
||||
if nowDate.After(plusDate) {
|
||||
|
||||
foundHosts = arp.Scan(conf.AppConfig.Ifaces, conf.AppConfig.ArpArgs, conf.AppConfig.ArpStrs)
|
||||
foundHosts = check.EnrichHosts(foundHosts)
|
||||
|
||||
compareHosts(newFoundHostIndex(foundHosts))
|
||||
ScanNow()
|
||||
|
||||
lastDate = time.Now()
|
||||
}
|
||||
|
||||
time.Sleep(time.Duration(1) * time.Minute)
|
||||
select {
|
||||
case <-quit:
|
||||
return
|
||||
case <-time.After(time.Duration(1) * time.Minute):
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,11 +1,12 @@
|
|||
import { Show } from "solid-js";
|
||||
import { Show, createSignal } from "solid-js";
|
||||
import { editNames, selectedIDs, setEditNames } from "../../functions/exports";
|
||||
import Filter from "../Filter";
|
||||
import Search from "../Search";
|
||||
import { getHosts } from "../../functions/atstart";
|
||||
import { apiDelHost } from "../../functions/api";
|
||||
import { apiDelHost, apiRescan } from "../../functions/api";
|
||||
|
||||
function CardHead() {
|
||||
const [rescanning, setRescanning] = createSignal(false);
|
||||
|
||||
const handleEditNames = (toggle: boolean) => {
|
||||
if (!toggle) {
|
||||
|
|
@ -24,6 +25,20 @@ function CardHead() {
|
|||
window.location.href = '/';
|
||||
};
|
||||
|
||||
const handleRescan = async () => {
|
||||
if (rescanning()) {
|
||||
return;
|
||||
}
|
||||
|
||||
setRescanning(true);
|
||||
try {
|
||||
await apiRescan();
|
||||
await getHosts();
|
||||
} finally {
|
||||
setRescanning(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div class="row">
|
||||
<div class="col-md mt-1 mb-1">
|
||||
|
|
@ -33,7 +48,18 @@ function CardHead() {
|
|||
</div>
|
||||
<div class="col-md mt-1 mb-1">
|
||||
<div class="d-flex justify-content-between">
|
||||
<Search></Search>
|
||||
<div class="d-flex gap-2">
|
||||
<Search></Search>
|
||||
<button
|
||||
class="btn btn-outline-primary"
|
||||
title="Rescan now"
|
||||
onClick={handleRescan}
|
||||
disabled={rescanning()}
|
||||
style="width: 2.5rem;"
|
||||
>
|
||||
<i class={rescanning() ? "spinner-border spinner-border-sm" : "bi bi-arrow-clockwise"}></i>
|
||||
</button>
|
||||
</div>
|
||||
<Show
|
||||
when={editNames()}
|
||||
fallback={<button class="btn btn-outline-primary" title="Toggle edit" onClick={[handleEditNames, true]}>Edit</button>}
|
||||
|
|
|
|||
|
|
@ -29,6 +29,12 @@ export const apiTestNotify = async () => {
|
|||
await fetch(url);
|
||||
};
|
||||
|
||||
export const apiRescan = async () => {
|
||||
|
||||
const url = apiPath+'/api/rescan';
|
||||
await fetch(url);
|
||||
};
|
||||
|
||||
export const apiEditHost = async (id:number, name:string, known:string) => {
|
||||
|
||||
const url = apiPath+'/api/edit/'+id+'/'+name+'/'+known;
|
||||
|
|
@ -81,4 +87,4 @@ export const apiWOL = async (mac:string) => {
|
|||
const res = await (await fetch(url)).json();
|
||||
|
||||
return res;
|
||||
};
|
||||
};
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ export function runAtStart() {
|
|||
export async function getHosts() {
|
||||
const hosts = await apiGetAllHosts();
|
||||
|
||||
if (hosts !== null && hosts.length > 0) {
|
||||
if (hosts !== null) {
|
||||
setAllHosts(hosts);
|
||||
setBkpHosts(hosts);
|
||||
|
||||
|
|
@ -36,4 +36,4 @@ function listIfaces() {
|
|||
}
|
||||
|
||||
setIfaces(ifaces);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue