generated from sendnrw/template_golang
gpupdate eingebaut
This commit is contained in:
108
main.go
108
main.go
@@ -17,6 +17,7 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/shirou/gopsutil/v3/cpu"
|
"github.com/shirou/gopsutil/v3/cpu"
|
||||||
@@ -710,13 +711,24 @@ var page = template.Must(template.New("index").Parse(`<!doctype html>
|
|||||||
<h2><div class="v stereo" id="hostname2"></div></h2>
|
<h2><div class="v stereo" id="hostname2"></div></h2>
|
||||||
<div class="grid">
|
<div class="grid">
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="k">Host</div>
|
<div class="k">Host</div>
|
||||||
<div class="row"><div>Hostname</div><div class="v stereo" id="hostname"></div></div>
|
<div class="row"><div>Hostname</div><div class="v stereo" id="hostname"></div></div>
|
||||||
<div class="row"><div>User</div><div class="v mono" id="username"></div></div>
|
<div class="row"><div>User</div><div class="v mono" id="username"></div></div>
|
||||||
<div class="row"><div>Uptime</div><div class="v" id="uptime"></div></div>
|
<div class="row"><div>Uptime</div><div class="v" id="uptime"></div></div>
|
||||||
<div class="row"><div>Boot</div><div class="v" id="boottime"></div></div>
|
<div class="row"><div>Boot</div><div class="v" id="boottime"></div></div>
|
||||||
<div class="row"><div>Arch</div><div class="v mono" id="arch"></div></div>
|
<div class="row"><div>Arch</div><div class="v mono" id="arch"></div></div>
|
||||||
</div>
|
|
||||||
|
<div class="row" style="margin-top:8px;">
|
||||||
|
<div>Aktionen</div>
|
||||||
|
<div>
|
||||||
|
<button id="btnGpupdate" class="pill2" style="cursor:pointer;">gpupdate /force</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div></div>
|
||||||
|
<div class="mono" id="gpupdateResult" style="font-size:12px;color:var(--muted);white-space:pre-wrap;"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
<div class="k">OS</div>
|
<div class="k">OS</div>
|
||||||
@@ -885,6 +897,29 @@ document.addEventListener('DOMContentLoaded', ()=>{
|
|||||||
renderApps(filtered);
|
renderApps(filtered);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const btnGp = document.getElementById('btnGpupdate');
|
||||||
|
const resGp = document.getElementById('gpupdateResult');
|
||||||
|
if (btnGp && resGp) {
|
||||||
|
btnGp.addEventListener('click', async ()=>{
|
||||||
|
resGp.textContent = 'gpupdate /force wird gestartet …';
|
||||||
|
try {
|
||||||
|
const r = await fetch('/api/gpupdate', { method: 'POST' });
|
||||||
|
if (!r.ok) {
|
||||||
|
resGp.textContent = 'Fehler: HTTP ' + r.status + ' ' + r.statusText;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const j = await r.json();
|
||||||
|
if (j.ok) {
|
||||||
|
resGp.textContent = 'gpupdate /force ausgeführt (ExitCode ' + (j.exit_code ?? 0) + ').';
|
||||||
|
} else {
|
||||||
|
resGp.textContent = 'Fehler bei gpupdate (ExitCode ' + (j.exit_code ?? -1) + '): ' + (j.error || '');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
resGp.textContent = 'Request-Fehler: ' + e;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
@@ -919,6 +954,7 @@ func runHTTP(ctx context.Context) error {
|
|||||||
mux.HandleFunc("/api/apps", appsHandler)
|
mux.HandleFunc("/api/apps", appsHandler)
|
||||||
mux.HandleFunc("/api/summary", apiHandler)
|
mux.HandleFunc("/api/summary", apiHandler)
|
||||||
mux.HandleFunc("/api/devices", devicesHandler)
|
mux.HandleFunc("/api/devices", devicesHandler)
|
||||||
|
mux.HandleFunc("/api/gpupdate", gpupdateHandler)
|
||||||
|
|
||||||
mux.HandleFunc("/api/notify", notifyFromServerHandler)
|
mux.HandleFunc("/api/notify", notifyFromServerHandler)
|
||||||
mux.HandleFunc("/api/notifications", notificationsForAgentHandler)
|
mux.HandleFunc("/api/notifications", notificationsForAgentHandler)
|
||||||
@@ -1079,3 +1115,61 @@ func getWinNetProfiles() (map[int]string, error) {
|
|||||||
res[single.InterfaceIndex] = normalizeCat(single.NetworkCategory)
|
res[single.InterfaceIndex] = normalizeCat(single.NetworkCategory)
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type GPUpdateResponse struct {
|
||||||
|
OK bool `json:"ok"`
|
||||||
|
ExitCode int `json:"exit_code"`
|
||||||
|
Stdout string `json:"stdout"`
|
||||||
|
Stderr string `json:"stderr"`
|
||||||
|
Error string `json:"error,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func gpupdateHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Method != http.MethodPost {
|
||||||
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// nur lokale Aufrufe zulassen
|
||||||
|
host, _, _ := net.SplitHostPort(r.RemoteAddr)
|
||||||
|
if host != "127.0.0.1" && host != "::1" {
|
||||||
|
http.Error(w, "forbidden", http.StatusForbidden)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx, cancel := context.WithTimeout(r.Context(), 2*time.Minute)
|
||||||
|
defer cancel()
|
||||||
|
|
||||||
|
cmd := exec.CommandContext(ctx, "cmd", "/C", "gpupdate", "/force")
|
||||||
|
out, err := cmd.CombinedOutput()
|
||||||
|
|
||||||
|
resp := GPUpdateResponse{
|
||||||
|
Stdout: string(out),
|
||||||
|
Stderr: "",
|
||||||
|
OK: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
// Timeout?
|
||||||
|
if ctx.Err() == context.DeadlineExceeded {
|
||||||
|
resp.OK = false
|
||||||
|
resp.Error = "gpupdate /force: Timeout (2 Minuten)"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exitcode auswerten
|
||||||
|
if err != nil {
|
||||||
|
resp.OK = false
|
||||||
|
resp.Error = err.Error()
|
||||||
|
if exitErr, ok := err.(*exec.ExitError); ok {
|
||||||
|
if status, ok2 := exitErr.Sys().(syscall.WaitStatus); ok2 {
|
||||||
|
resp.ExitCode = status.ExitStatus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if cmd.ProcessState != nil {
|
||||||
|
if status, ok := cmd.ProcessState.Sys().(syscall.WaitStatus); ok {
|
||||||
|
resp.ExitCode = status.ExitStatus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Set("Content-Type", "application/json")
|
||||||
|
_ = json.NewEncoder(w).Encode(resp)
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user