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": {
|
"/rescan": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "Manually trigger rescan",
|
"description": "Manually trigger rescan and wait until the DB is updated",
|
||||||
"produces": [
|
"produces": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -363,7 +363,7 @@
|
||||||
},
|
},
|
||||||
"/rescan": {
|
"/rescan": {
|
||||||
"get": {
|
"get": {
|
||||||
"description": "Manually trigger rescan",
|
"description": "Manually trigger rescan and wait until the DB is updated",
|
||||||
"produces": [
|
"produces": [
|
||||||
"application/json"
|
"application/json"
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -345,7 +345,7 @@ paths:
|
||||||
- network
|
- network
|
||||||
/rescan:
|
/rescan:
|
||||||
get:
|
get:
|
||||||
description: Manually trigger rescan
|
description: Manually trigger rescan and wait until the DB is updated
|
||||||
produces:
|
produces:
|
||||||
- application/json
|
- application/json
|
||||||
responses:
|
responses:
|
||||||
|
|
|
||||||
|
|
@ -25,14 +25,14 @@ func getVersion(c *gin.Context) {
|
||||||
|
|
||||||
// triggerRescan godoc
|
// triggerRescan godoc
|
||||||
// @Summary Rescan all interfaces now
|
// @Summary Rescan all interfaces now
|
||||||
// @Description Manually trigger rescan
|
// @Description Manually trigger rescan and wait until the DB is updated
|
||||||
// @Tags system
|
// @Tags system
|
||||||
// @Produce json
|
// @Produce json
|
||||||
// @Success 200 {string} string "OK"
|
// @Success 200 {string} string "OK"
|
||||||
// @Router /rescan [get]
|
// @Router /rescan [get]
|
||||||
func triggerRescan(c *gin.Context) {
|
func triggerRescan(c *gin.Context) {
|
||||||
routines.ScanRestart()
|
routines.ScanNow()
|
||||||
c.Status(http.StatusOK)
|
c.IndentedJSON(http.StatusOK, "OK")
|
||||||
}
|
}
|
||||||
|
|
||||||
// getConfig godoc
|
// getConfig godoc
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package routines
|
||||||
import (
|
import (
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/aceberg/WatchYourLAN/internal/arp"
|
"github.com/aceberg/WatchYourLAN/internal/arp"
|
||||||
|
|
@ -15,9 +16,21 @@ import (
|
||||||
"github.com/aceberg/WatchYourLAN/internal/prometheus"
|
"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) {
|
func startScan(quit chan bool) {
|
||||||
var lastDate, nowDate, plusDate time.Time
|
var lastDate, nowDate, plusDate time.Time
|
||||||
var foundHosts []models.Host
|
|
||||||
|
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
|
@ -29,15 +42,16 @@ func startScan(quit chan bool) {
|
||||||
|
|
||||||
if nowDate.After(plusDate) {
|
if nowDate.After(plusDate) {
|
||||||
|
|
||||||
foundHosts = arp.Scan(conf.AppConfig.Ifaces, conf.AppConfig.ArpArgs, conf.AppConfig.ArpStrs)
|
ScanNow()
|
||||||
foundHosts = check.EnrichHosts(foundHosts)
|
|
||||||
|
|
||||||
compareHosts(newFoundHostIndex(foundHosts))
|
|
||||||
|
|
||||||
lastDate = time.Now()
|
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 { editNames, selectedIDs, setEditNames } from "../../functions/exports";
|
||||||
import Filter from "../Filter";
|
import Filter from "../Filter";
|
||||||
import Search from "../Search";
|
import Search from "../Search";
|
||||||
import { getHosts } from "../../functions/atstart";
|
import { getHosts } from "../../functions/atstart";
|
||||||
import { apiDelHost } from "../../functions/api";
|
import { apiDelHost, apiRescan } from "../../functions/api";
|
||||||
|
|
||||||
function CardHead() {
|
function CardHead() {
|
||||||
|
const [rescanning, setRescanning] = createSignal(false);
|
||||||
|
|
||||||
const handleEditNames = (toggle: boolean) => {
|
const handleEditNames = (toggle: boolean) => {
|
||||||
if (!toggle) {
|
if (!toggle) {
|
||||||
|
|
@ -24,6 +25,20 @@ function CardHead() {
|
||||||
window.location.href = '/';
|
window.location.href = '/';
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleRescan = async () => {
|
||||||
|
if (rescanning()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setRescanning(true);
|
||||||
|
try {
|
||||||
|
await apiRescan();
|
||||||
|
await getHosts();
|
||||||
|
} finally {
|
||||||
|
setRescanning(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md mt-1 mb-1">
|
<div class="col-md mt-1 mb-1">
|
||||||
|
|
@ -33,7 +48,18 @@ function CardHead() {
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md mt-1 mb-1">
|
<div class="col-md mt-1 mb-1">
|
||||||
<div class="d-flex justify-content-between">
|
<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
|
<Show
|
||||||
when={editNames()}
|
when={editNames()}
|
||||||
fallback={<button class="btn btn-outline-primary" title="Toggle edit" onClick={[handleEditNames, true]}>Edit</button>}
|
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);
|
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) => {
|
export const apiEditHost = async (id:number, name:string, known:string) => {
|
||||||
|
|
||||||
const url = apiPath+'/api/edit/'+id+'/'+name+'/'+known;
|
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();
|
const res = await (await fetch(url)).json();
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ export function runAtStart() {
|
||||||
export async function getHosts() {
|
export async function getHosts() {
|
||||||
const hosts = await apiGetAllHosts();
|
const hosts = await apiGetAllHosts();
|
||||||
|
|
||||||
if (hosts !== null && hosts.length > 0) {
|
if (hosts !== null) {
|
||||||
setAllHosts(hosts);
|
setAllHosts(hosts);
|
||||||
setBkpHosts(hosts);
|
setBkpHosts(hosts);
|
||||||
|
|
||||||
|
|
@ -36,4 +36,4 @@ function listIfaces() {
|
||||||
}
|
}
|
||||||
|
|
||||||
setIfaces(ifaces);
|
setIfaces(ifaces);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue