Skip to content

Commit

Permalink
Create ActiveHoursEnabled registry key to gate new Active Hours logic.
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 730420906
  • Loading branch information
jm2 authored and copybara-github committed Feb 24, 2025
1 parent c9c5934 commit d107872
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 38 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ NotifyAvailable | REG_DWORD | 1
AukeraEnabled | REG_DWORD | 0 | Enable Cabbie to use the open source Aukera maintenance window manager.
AukeraPort | REG_DWORD | 9119 | LocalHost port to check against for Aukera maintenance windows.
AukeraName | REG_SZ | Cabbie | Aukera maintenance window label to query for to determine if a maintenance window is currently open.
ActiveHoursEnabled | REG_DWORD | 0 | Enable Cabbie to follow Microsoft Active Hours; requires Aukera enabled.
ScriptTimeout | REG_DWORD | 10 | Pre/Post Update script timeout in minutes.

### Pre/Post Update script execution
Expand Down
36 changes: 22 additions & 14 deletions cabbie.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ import (
"golang.org/x/sys/windows/svc/debug"
"golang.org/x/sys/windows/svc"
"github.com/google/subcommands"
gos "github.com/google/glazier/go/os"
)

var (
Expand Down Expand Up @@ -84,6 +83,9 @@ type Settings struct {
AukeraPort uint64
AukeraName string

// Microsoft Active Hours Integration (Requires Aukera Enabled)
ActiveHoursEnabled uint64

PprofPort uint64

ScriptTimeout time.Duration
Expand Down Expand Up @@ -195,6 +197,9 @@ func (s *Settings) regLoad(path string) error {
if i, _, err := k.GetIntegerValue("PprofPort"); err == nil {
s.PprofPort = i
}
if i, _, err := k.GetIntegerValue("ActiveHoursEnabled"); err == nil {
s.ActiveHoursEnabled = i
}
if i, _, err := k.GetIntegerValue("ScriptTimeout"); err == nil {
s.ScriptTimeout = time.Duration(i) * time.Minute
}
Expand Down Expand Up @@ -395,25 +400,28 @@ func runMainLoop() error {
deck.ErrorfA("Error getting maintenance window %q with error:\n%v", config.AukeraName, err).With(eventID(cablib.EvtErrMaintWindow)).Go()
break
}
ah, err := client.Label(int(config.AukeraPort), `active_hours`)
if err != nil {
deck.ErrorfA("Error getting maintenance window %q with error:\n%v", `active_hours`, err).With(eventID(cablib.EvtErrMaintWindow)).Go()
break
}
if *runInDebug {
fmt.Printf("Cabbie maintenance window schedule:\n%+v", s)
fmt.Printf("Cabbie active hours schedule:\n%+v", ah)
}
if len(s) == 0 {
deck.ErrorfA("Aukera maintenance window label %q not found, skipping update check...", config.AukeraName).With(eventID(cablib.EvtErrMaintWindow)).Go()
break
}
osType, err := gos.GetType()
if err != nil {
deck.ErrorfA("Error machine type with error:\n%v", err).With(eventID(cablib.EvtErrPowerMgmt)).Go()
}
if (osType == gos.Client) && (len(ah) != 0) {
deck.InfofA("Client machine detected with active hours aukera window present; using active hours schedule.").With(eventID(cablib.EvtMisc)).Go()
if config.ActiveHoursEnabled == 1 {
deck.InfofA("Active hours enabled: checking for active hours schedule.").With(eventID(cablib.EvtMisc)).Go()
ah, err := client.Label(int(config.AukeraPort), `active_hours`)
if err != nil {
deck.ErrorfA("Error getting maintenance window %q with error:\n%v", `active_hours`, err).With(eventID(cablib.EvtErrMaintWindow)).Go()
break
}
if *runInDebug {
fmt.Printf("Cabbie active hours schedule:\n%+v", ah)
}
if len(ah) == 0 {
deck.ErrorfA("Aukera maintenance window label %q not found, skipping update check...", `active_hours`).With(eventID(cablib.EvtErrMaintWindow)).Go()
break
}
deck.InfofA("Active hours enabled and schedule found: using active hours schedule.").With(eventID(cablib.EvtMisc)).Go()
trimmedOpen := ah[0].Opens.Add(time.Hour)
trimmedClose := ah[0].Closes.Add(-time.Hour)
now := time.Now()
Expand All @@ -437,7 +445,7 @@ func runMainLoop() error {
setRebootMetric()
}
} else {
deck.InfofA("Server machine detected or no active hours aukera window present; using standard maintenance window schedule.").With(eventID(cablib.EvtMisc)).Go()
deck.InfofA("Active hours disabled; using standard maintenance window schedule.").With(eventID(cablib.EvtMisc)).Go()
// If we're a server, or we don't have an active hours window, we'll install updates
// as long as the standard `cabbie` maintenance window is open.
if s[0].State == "open" {
Expand Down
42 changes: 18 additions & 24 deletions install.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ import (
"github.com/google/aukera/client"
"github.com/google/subcommands"
"github.com/google/glazier/go/helpers"
gos "github.com/google/glazier/go/os"
)

// Available flags
Expand Down Expand Up @@ -196,7 +195,7 @@ func installCollection(s *session.UpdateSession, c *updatecollection.Collection,
if err := inst.Commit(); err != nil {
return nil, fmt.Errorf("error committing updates:\n %v", err)
}
}
}

return &installRsp{
hResult: hr,
Expand Down Expand Up @@ -445,31 +444,26 @@ outerLoop:
deck.ErrorfA("Failed to write updates requiring reboot to registry: %v", err).With(eventID(cablib.EvtRebootRequired)).Go()
}

ah, err := client.Label(int(config.AukeraPort), `active_hours`)
if err != nil {
deck.ErrorfA("Error getting maintenance window %q with error:\n%v", `active_hours`, err).With(eventID(cablib.EvtErrMaintWindow)).Go()
}

osType, err := gos.GetType()
if err != nil {
deck.ErrorfA("Error machine type with error:\n%v", err).With(eventID(cablib.EvtErrPowerMgmt)).Go()
}

// Use active hours for client machines.
// Use active hours if enabled and available, otherwise use the standard reboot delay.
now := time.Now()
timerEnd := now.Add(time.Second * time.Duration(config.RebootDelay))
if (osType == gos.Client) && (len(ah) != 0) {
todayEnd := ah[0].Closes
tomorrowEnd := todayEnd.Add(time.Hour * time.Duration(24))
// If the active hours end time is in the future, use the end time.
// Otherwise, use the same end time of the next day.
if todayEnd.After(now) {
rebootTime = todayEnd
} else {
rebootTime = tomorrowEnd
rebootTime := timerEnd
if config.ActiveHoursEnabled == 1 {
ah, err := client.Label(int(config.AukeraPort), `active_hours`)
if err != nil {
deck.ErrorfA("Error getting maintenance window %q with error:\n%v", `active_hours`, err).With(eventID(cablib.EvtErrMaintWindow)).Go()
}
if len(ah) != 0 {
todayEnd := ah[0].Closes
tomorrowEnd := todayEnd.Add(time.Hour * time.Duration(24))
// If the active hours end time is in the future, use the end time.
// Otherwise, use the same end time of the next day.
if todayEnd.After(now) {
rebootTime = todayEnd
} else {
rebootTime = tomorrowEnd
}
}
} else {
rebootTime = timerEnd
}
rebootMessage(rebootTime)
if err := cablib.SetRebootTime(rebootTime); err != nil {
Expand Down

0 comments on commit d107872

Please sign in to comment.