Skip to content

Commit 088561d

Browse files
committed
feat(systemd): Add WasSkippedDueToConditions method and handle skipped services
Implement the WasSkippedDueToConditions method in the systemd Commander to check if service conditions are met. Update the WaitForServiceSuccessfullyFinished function to handle cases where services are skipped due to unmet conditions, indicating that their work was already completed in a previous run. This enhancement improves service management and logging clarity.
1 parent 930327e commit 088561d

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

pkg/crc/cluster/cluster.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ func EnsureSSHKeyPresentInTheCluster(ctx context.Context, ocConfig oc.Config, ss
187187
// 1. Run (verified by checking ExecMainExitTimestamp changes)
188188
// 2. Finish (transition to Stopped state)
189189
// 3. Exit with Result=success
190+
// It also handles services that are skipped due to unmet conditions (e.g., ConditionPathExists).
191+
// When a service is skipped, its work was already done in a previous run.
190192
func WaitForServiceSuccessfullyFinished(ctx context.Context, systemdRunner *systemd.Commander,
191193
serviceName string, timeout, retryInterval time.Duration) error {
192194
return errors.Retry(ctx, timeout, func() error {
@@ -208,6 +210,21 @@ func WaitForServiceSuccessfullyFinished(ctx context.Context, systemdRunner *syst
208210
logging.Debugf("Service %s current ExecMainExitTimestamp: '%s'", serviceName, currentExecMainExitTimestamp)
209211

210212
if currentExecMainExitTimestamp == "" {
213+
// No exit timestamp means service didn't run. Check if it was skipped due to conditions.
214+
// This can happen after system restart when ConditionPathExists marks work as already done.
215+
wasSkipped, err := systemdRunner.WasSkippedDueToConditions(serviceName)
216+
if err != nil {
217+
return &errors.RetriableError{Err: err}
218+
}
219+
logging.Debugf("Service %s was skipped due to conditions: %v", serviceName, wasSkipped)
220+
221+
if wasSkipped {
222+
// Service was skipped because conditions weren't met (e.g., .done file exists).
223+
// This means the work was already completed in a previous run.
224+
logging.Debugf("Service %s was skipped due to unmet conditions (work already done)", serviceName)
225+
return nil
226+
}
227+
211228
return &errors.RetriableError{Err: fmt.Errorf("service %s has not run yet (no exit timestamp)", serviceName)}
212229
}
213230

pkg/crc/systemd/systemd.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,32 @@ func (c Commander) ExecMainExitTimestamp(name string) (string, error) {
8181
return strings.TrimSpace(stdOut), nil
8282
}
8383

84+
// WasSkippedDueToConditions returns true if the service was triggered but skipped
85+
// because its condition checks (e.g., ConditionPathExists) were not met.
86+
// This is determined by checking both ConditionResult and ConditionTimestamp:
87+
// - If ConditionTimestamp is empty, conditions were never evaluated (service never triggered)
88+
// - If ConditionTimestamp has a value and ConditionResult is "no", service was skipped
89+
func (c Commander) WasSkippedDueToConditions(name string) (bool, error) {
90+
stdOut, stdErr, err := c.commandRunner.Run("systemctl", "show", "-p", "ConditionResult", "-p", "ConditionTimestamp", name)
91+
if err != nil {
92+
return false, fmt.Errorf("failed to get service condition info: %s %v: %s", stdOut, err, stdErr)
93+
}
94+
95+
output := strings.TrimSpace(stdOut)
96+
var conditionResult, conditionTimestamp string
97+
for _, line := range strings.Split(output, "\n") {
98+
if strings.HasPrefix(line, "ConditionResult=") {
99+
conditionResult = strings.TrimPrefix(line, "ConditionResult=")
100+
} else if strings.HasPrefix(line, "ConditionTimestamp=") {
101+
conditionTimestamp = strings.TrimPrefix(line, "ConditionTimestamp=")
102+
}
103+
}
104+
105+
// Service was skipped only if conditions were actually evaluated (timestamp exists)
106+
// AND the result was "no" (conditions not met)
107+
return conditionTimestamp != "" && conditionResult == "no", nil
108+
}
109+
84110
func (c Commander) DaemonReload() error {
85111
stdOut, stdErr, err := c.commandRunner.RunPrivileged("Executing systemctl daemon-reload command", "systemctl", "daemon-reload")
86112
if err != nil {

0 commit comments

Comments
 (0)