Example #1
0
func runReboot(args []string) int {
	if os.Geteuid() != 0 {
		fmt.Fprintln(os.Stderr, "Must be root to initiate reboot.")
		return 1
	}

	elc, err := getClient()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error initializing etcd client:", err)
		return 1
	}

	lgn, err := login1.New()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error initializing login connection:", err)
		return 1
	}

	mID := machineid.MachineID("/")
	if mID == "" {
		fmt.Fprintln(os.Stderr, "Cannot read machine-id")
		return 1
	}

	l := lock.New(mID, elc)

	err = l.Lock()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error locking:", err)
		return 1
	}

	lgn.Reboot(false)

	// TODO(philips): Unlock if the reboot fails.

	return 0
}
Example #2
0
// runDaemon waits for the reboot needed signal coming out of update engine and
// 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 == "" {
		strategy = StrategyBestEffort
	}

	if strategy == StrategyOff {
		fmt.Fprintf(os.Stderr, "Reboot strategy is %q - shutting down.\n", strategy)
		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 == "") {
		fmt.Fprintln(os.Stderr, "either both or neither $REBOOT_WINDOW_START and $REBOOT_WINDOW_LENGTH must be set")
		return 1
	}

	if startw != "" && lengthw != "" {
		p, err := timeutil.ParsePeriodic(startw, lengthw)
		if err != nil {
			fmt.Fprintf(os.Stderr, "error parsing reboot window: %s\n", err)
			return 1
		}

		period = p
	}

	shutdown := make(chan os.Signal, 1)
	stop := make(chan struct{}, 1)

	go func() {
		<-shutdown
		fmt.Fprintln(os.Stderr, "Received interrupt/termination signal - shutting down.")
		os.Exit(0)
	}()
	signal.Notify(shutdown, syscall.SIGINT, syscall.SIGTERM)

	ue, err := updateengine.New()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error initializing update1 client:", err)
		return 1
	}

	lgn, err := login1.New()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Error initializing login1 client:", err)
		return 1
	}

	var wg sync.WaitGroup
	if strategy != StrategyReboot {
		wg.Add(1)
		go unlockHeldLocks(strategy, stop, &wg)
	}

	ch := make(chan updateengine.Status, 1)
	go ue.RebootNeededSignal(ch, stop)

	r := rebooter{strategy, lgn}

	result, err := ue.GetStatus()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Cannot get update engine status:", err)
		return 1
	}

	fmt.Printf("locksmithd starting currentOperation=%q strategy=%q\n",
		result.CurrentOperation,
		strategy,
	)

	if result.CurrentOperation != updateengine.UpdateStatusUpdatedNeedReboot {
		<-ch
	}

	close(stop)
	wg.Wait()

	if period != nil {
		now := time.Now()
		sleeptime := period.DurationToStart(now)
		if sleeptime > 0 {
			fmt.Printf("Waiting for %s to reboot.\n", sleeptime)
			time.Sleep(sleeptime)
		}
	}

	return r.reboot()
}