gui: auto-reboot after deployment with 60s countdown
All checks were successful
release / build-and-release (push) Successful in 22s
All checks were successful
release / build-and-release (push) Successful in 22s
Summary screen shows countdown "Restart za Xs..." and reboots automatically. Buttons: "Restartovat ted" (immediate) and "Zrusit restart" (cancel). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2236fe48e9
commit
d06af1a87f
1 changed files with 64 additions and 4 deletions
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
"os/exec"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
@ -324,11 +325,16 @@ func runPhase(runCfg runner.RunConfig, steps []runner.Step) []runner.Result {
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// Phase 3 – Summary
|
// Phase 3 – Summary with auto-reboot countdown
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const rebootCountdown = 60 // seconds before automatic reboot
|
||||||
|
|
||||||
func donePhase(results []runner.Result) {
|
func donePhase(results []runner.Result) {
|
||||||
var mw *walk.MainWindow
|
var (
|
||||||
|
mw *walk.MainWindow
|
||||||
|
countdownLbl *walk.Label
|
||||||
|
)
|
||||||
|
|
||||||
ok, errs, skipped := 0, 0, 0
|
ok, errs, skipped := 0, 0, 0
|
||||||
rows := make([]Widget, 0, len(results))
|
rows := make([]Widget, 0, len(results))
|
||||||
|
|
@ -358,6 +364,9 @@ func donePhase(results []runner.Result) {
|
||||||
|
|
||||||
summaryText := fmt.Sprintf("OK: %d CHYBY: %d PRESKOCENO: %d", ok, errs, skipped)
|
summaryText := fmt.Sprintf("OK: %d CHYBY: %d PRESKOCENO: %d", ok, errs, skipped)
|
||||||
|
|
||||||
|
// cancelled by "Zrusit restart" button
|
||||||
|
cancelReboot := make(chan struct{})
|
||||||
|
|
||||||
if err := (MainWindow{
|
if err := (MainWindow{
|
||||||
AssignTo: &mw,
|
AssignTo: &mw,
|
||||||
Title: "xetup \u2014 hotovo",
|
Title: "xetup \u2014 hotovo",
|
||||||
|
|
@ -371,7 +380,7 @@ func donePhase(results []runner.Result) {
|
||||||
},
|
},
|
||||||
HSeparator{},
|
HSeparator{},
|
||||||
ScrollView{
|
ScrollView{
|
||||||
MinSize: Size{Height: 560},
|
MinSize: Size{Height: 510},
|
||||||
Layout: VBox{MarginsZero: true},
|
Layout: VBox{MarginsZero: true},
|
||||||
Children: rows,
|
Children: rows,
|
||||||
},
|
},
|
||||||
|
|
@ -381,16 +390,34 @@ func donePhase(results []runner.Result) {
|
||||||
Alignment: AlignHCenterVNear,
|
Alignment: AlignHCenterVNear,
|
||||||
Font: Font{Bold: true},
|
Font: Font{Bold: true},
|
||||||
},
|
},
|
||||||
|
Label{
|
||||||
|
AssignTo: &countdownLbl,
|
||||||
|
Text: fmt.Sprintf("Restart za %ds...", rebootCountdown),
|
||||||
|
Alignment: AlignHCenterVNear,
|
||||||
|
},
|
||||||
Composite{
|
Composite{
|
||||||
Layout: HBox{MarginsZero: true},
|
Layout: HBox{MarginsZero: true},
|
||||||
Children: []Widget{
|
Children: []Widget{
|
||||||
HSpacer{},
|
HSpacer{},
|
||||||
PushButton{
|
PushButton{
|
||||||
Text: " ZAVRIT ",
|
Text: " Restartovat ted ",
|
||||||
OnClicked: func() {
|
OnClicked: func() {
|
||||||
|
close(cancelReboot) // signal goroutine to stop ticker
|
||||||
|
reboot()
|
||||||
mw.Close()
|
mw.Close()
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
PushButton{
|
||||||
|
Text: " Zrusit restart ",
|
||||||
|
OnClicked: func() {
|
||||||
|
select {
|
||||||
|
case <-cancelReboot: // already closed
|
||||||
|
default:
|
||||||
|
close(cancelReboot)
|
||||||
|
}
|
||||||
|
countdownLbl.SetText("Restart zrusen.")
|
||||||
|
},
|
||||||
|
},
|
||||||
HSpacer{},
|
HSpacer{},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -399,9 +426,42 @@ func donePhase(results []runner.Result) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Countdown goroutine
|
||||||
|
go func() {
|
||||||
|
ticker := time.NewTicker(time.Second)
|
||||||
|
defer ticker.Stop()
|
||||||
|
remaining := rebootCountdown
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-cancelReboot:
|
||||||
|
return
|
||||||
|
case <-ticker.C:
|
||||||
|
remaining--
|
||||||
|
r := remaining
|
||||||
|
mw.Synchronize(func() {
|
||||||
|
if r > 0 {
|
||||||
|
countdownLbl.SetText(fmt.Sprintf("Restart za %ds...", r))
|
||||||
|
} else {
|
||||||
|
countdownLbl.SetText("Restartuji...")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if remaining <= 0 {
|
||||||
|
reboot()
|
||||||
|
mw.Synchronize(func() { mw.Close() })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
mw.Run()
|
mw.Run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// reboot issues an immediate Windows restart.
|
||||||
|
func reboot() {
|
||||||
|
exec.Command("shutdown", "/r", "/t", "0").Run() //nolint:errcheck
|
||||||
|
}
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
// Helpers
|
// Helpers
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue