From b9fe50bf84562c740f593596fa46e189c218bd61 Mon Sep 17 00:00:00 2001
From: Itxaka <itxaka.garcia@spectrocloud.com>
Date: Tue, 9 Apr 2024 08:40:28 +0000
Subject: [PATCH] Add timeout wait for sysroot (#278)

---
 README.md          |  4 +++-
 pkg/state/steps.go | 14 +++++++++++++-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/README.md b/README.md
index 991097b..e292463 100644
--- a/README.md
+++ b/README.md
@@ -89,7 +89,9 @@ The immutable rootfs can be configured with the following kernel parameters:
 
 * `rd.immucore.debug`: Enables debug logging
 
-* `rd.immucore.uki`: Enables UKI booting (Experimental)
+* `rd.immucore.uki`: Enables UKI booting
+
+* `rd.immucore.sysrootwait=<seconds>`: Waits for the sysroot to be mounted up to <seconds> before continuing with the boot process. This is useful when booting from CD/Netboot as immucore doesn't mount the /sysroot in those cases, but we want to run the initramfs stage once the system is ready. Sometimes dracut can be really slow and the default 1 minute of waiting is not enough. In those cases you can increase this value to wait more time. Defaults to 60s.
 
 
 ### Configuration with an environment file
diff --git a/pkg/state/steps.go b/pkg/state/steps.go
index 6056c40..7a65700 100644
--- a/pkg/state/steps.go
+++ b/pkg/state/steps.go
@@ -5,6 +5,7 @@ import (
 	"fmt"
 	"os"
 	"path/filepath"
+	"strconv"
 	"time"
 
 	cnst "github.com/kairos-io/immucore/internal/constants"
@@ -119,7 +120,18 @@ func (s *State) MountRootDagStep(g *herd.Graph) error {
 func (s *State) WaitForSysrootDagStep(g *herd.Graph) error {
 	return g.Add(cnst.OpWaitForSysroot,
 		herd.WithCallback(func(ctx context.Context) error {
-			cc := time.After(60 * time.Second)
+			var timeout = 60 * time.Second
+			timeoutArg := internalUtils.CleanupSlice(internalUtils.ReadCMDLineArg("rd.immucore.sysrootwait="))
+			if len(timeoutArg) > 0 {
+				atoi, err := strconv.Atoi(timeoutArg[0])
+				if err == nil && atoi > 0 {
+					timeout = time.Duration(atoi) * time.Second
+				}
+			}
+
+			internalUtils.Log.Debug().Str("timeout", timeout.String()).Msg("Waiting for sysroot")
+
+			cc := time.After(timeout)
 			for {
 				select {
 				default: