Skip to content

Commit

Permalink
Add waitForRebootWindow to sleep till next window
Browse files Browse the repository at this point in the history
waitForRebootWindow get the environment variable REBOOT_WINDOW_START and
REBOOT_WINDOW_LENGTH and check if everything is ok or not. If not then
return error. If ok then get the next periodic by the ParsePeriodic
function.

Then check if we are inside the reboot window or not. If we are inside
the reboot window then it will sleep until the next window and return a
true. If outside the window then it just return the false.

In the lockAndReboot function we check if it has sleep or not and handle the
error.
  • Loading branch information
aniruddha2000 committed Aug 2, 2021
1 parent 5854b83 commit f70d888
Showing 1 changed file with 56 additions and 82 deletions.
138 changes: 56 additions & 82 deletions locksmithctl/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ package main
import "C"

import (
"errors"
"fmt"
"os"
"os/signal"
Expand Down Expand Up @@ -116,6 +117,53 @@ func expBackoff(interval time.Duration) time.Duration {
return interval
}

// waitForRebootWindow get the REBOOT_WINDOW_START, REBOOT_WINDOW_LENGTH
// and check if everything is ok and the get then Periodic. Check if
// it is outside of the reboot window and If yes then sleep and return true.
func waitForRebootWindow() (bool, error) {
var period *timeutil.Periodic

startw := os.Getenv("LOCKSMITHD_REBOOT_WINDOW_START")
if startw == "" {
startw = os.Getenv("REBOOT_WINDOW_START")
}

lengthw := os.Getenv("LOCKSMITHD_REBOOT_WINDOW_LENGTH")
if lengthw == "" {
lengthw = os.Getenv("REBOOT_WINDOW_LENGTH")
}

if (startw == "") != (lengthw == "") {
return false, errors.New("Either both or neither $REBOOT_WINDOW_START and $REBOOT_WINDOW_LENGTH must be set")
}

if startw != "" && lengthw != "" {
p, err := timeutil.ParsePeriodic(startw, lengthw)
if err != nil {
return false, fmt.Errorf("unable to parse periodic: %w", err)
}

period = p
}

if period != nil {
now := time.Now()
sleeptime := period.DurationToStart(now)
if sleeptime > 0 {
dlog.Infof("Reboot window start is %q and length is %q", startw, lengthw)
next := period.Next(time.Now())
dlog.Infof("Next window begins at %s and ends at %s", next.Start, next.End)
dlog.Infof("Waiting for %s to reboot.", sleeptime)
time.Sleep(sleeptime)
return true, nil
}
} else {
dlog.Info("No configured reboot window")
}

return false, nil
}

func (r rebooter) rebootAndSleep() {
// Broadcast a notice, if broadcast found lines to notify, delay the reboot.
delaymins := loginsRebootDelay / time.Minute
Expand All @@ -138,8 +186,6 @@ func (r rebooter) rebootAndSleep() {
// infinite loop if it is in the reboot window.
// Returns if the reboot failed.
func (r rebooter) lockAndReboot(lck *lock.Lock) {
var period *timeutil.Periodic

interval := initialInterval
for {
err := lck.Lock()
Expand All @@ -148,47 +194,15 @@ func (r rebooter) lockAndReboot(lck *lock.Lock) {
dlog.Warningf("Failed to acquire lock: %v. Retrying in %v.", err, interval)
time.Sleep(interval)

continue
}

startw := os.Getenv("LOCKSMITHD_REBOOT_WINDOW_START")
if startw == "" {
startw = os.Getenv("REBOOT_WINDOW_START")
}

lengthw := os.Getenv("LOCKSMITHD_REBOOT_WINDOW_LENGTH")
if lengthw == "" {
lengthw = os.Getenv("REBOOT_WINDOW_LENGTH")
}

if (startw == "") != (lengthw == "") {
dlog.Fatal("Either both or neither $REBOOT_WINDOW_START and $REBOOT_WINDOW_LENGTH must be set")
}

if startw != "" && lengthw != "" {
p, err := timeutil.ParsePeriodic(startw, lengthw)
hasSleep, err := waitForRebootWindow()
if err != nil {
dlog.Fatalf("Error parsing reboot window: %s", err)
dlog.Fatalf("unable to check reboot window period: %v", err)
}

period = p
}

if period != nil {
dlog.Infof("Reboot window start is %q and length is %q", startw, lengthw)
next := period.Next(time.Now())
dlog.Infof("Next window begins at %s and ends at %s", next.Start, next.End)
} else {
dlog.Info("No configured reboot window")
}

if period != nil {
now := time.Now()
sleeptime := period.DurationToStart(now)
if sleeptime > 0 {
dlog.Infof("Waiting for %s to reboot.", sleeptime)
time.Sleep(sleeptime)
if hasSleep {
interval = initialInterval
}

continue
}

r.rebootAndSleep()
Expand Down Expand Up @@ -304,8 +318,6 @@ func unlockHeldLocks(strategy string, stop chan struct{}, wg *sync.WaitGroup) {
// attempts to acquire the reboot lock. If the reboot lock is acquired then the
// machine will reboot.
func runDaemon() int {
var period *timeutil.Periodic

strategy := os.Getenv("REBOOT_STRATEGY")

if strategy == "" {
Expand All @@ -317,39 +329,6 @@ func runDaemon() int {
return 0
}

// XXX: REBOOT_WINDOW_* are deprecated in favor of variables with LOCKSMITHD_ prefix,
// but the old ones are read for compatibility.
startw := os.Getenv("LOCKSMITHD_REBOOT_WINDOW_START")
if startw == "" {
startw = os.Getenv("REBOOT_WINDOW_START")
}

lengthw := os.Getenv("LOCKSMITHD_REBOOT_WINDOW_LENGTH")
if lengthw == "" {
lengthw = os.Getenv("REBOOT_WINDOW_LENGTH")
}

if (startw == "") != (lengthw == "") {
dlog.Fatal("Either both or neither $REBOOT_WINDOW_START and $REBOOT_WINDOW_LENGTH must be set")
}

if startw != "" && lengthw != "" {
p, err := timeutil.ParsePeriodic(startw, lengthw)
if err != nil {
dlog.Fatalf("Error parsing reboot window: %s", err)
}

period = p
}

if period != nil {
dlog.Infof("Reboot window start is %q and length is %q", startw, lengthw)
next := period.Next(time.Now())
dlog.Infof("Next window begins at %s and ends at %s", next.Start, next.End)
} else {
dlog.Info("No configured reboot window")
}

coordinatorConf, err := coordinatorconf.New(coordinatorName, strategy)
if err != nil {
dlog.Fatalf("unable to become 'update coordinator': %v", err)
Expand Down Expand Up @@ -407,13 +386,8 @@ func runDaemon() int {
close(stop)
wg.Wait()

if period != nil {
now := time.Now()
sleeptime := period.DurationToStart(now)
if sleeptime > 0 {
dlog.Infof("Waiting for %s to reboot.", sleeptime)
time.Sleep(sleeptime)
}
if _, err := waitForRebootWindow(); err != nil {
dlog.Fatalf("unable to check reboot window period: %v", err)
}

return r.reboot()
Expand Down

0 comments on commit f70d888

Please sign in to comment.