Skip to content

Commit bc6f8a9

Browse files
committed
executor: return error message from the journal
Previously, the output of the systemd unit was only reported in bootc operator. Now, it is returned as part of the error when bootc switch fails. The output for the systemd unit is quite verbose, so we filter for the lines containing the errors tag. The full output will be reduced from: bootc stage failed: running bootc switch: Started bootc-operator-switch.service - [systemd-run] /usr/bin/bootc switch ghcr.io/bootc-dev/bink/node@sha256:9ce7d6d15b8558c226b4c41f3b27bf1722897b0c8a66c7a84a2877bca8d049f7. Switching from image ghcr.io/bootc-dev/bink/node:v1.35-fedora-44 to ghcr.io/bootc-dev/bink/node@sha256:9ce7d6d15b8558c226b4c41f3b27bf1722897b0c8a66c7a84a2877bca8d049f7 Fetching ostree-unverified-registry:ghcr.io/bootc-dev/bink/node@sha256:9ce7d6d15b8558c226b4c41f3b27bf1722897b0c8a66c7a84a2877bca8d049f7 error: Switching: Switching (ostree): Preparing import: Fetching manifest: Target image does not have ostree.bootable label bootc-operator-switch.service: Main process exited, code=exited, status=1/FAILURE bootc-operator-switch.service: Failed with result 'exit-code'. bootc-operator-switch.service: Consumed 210ms CPU time over 1.111s wall clock time, 155.2M memory peak.: exit status 1 to 'bootc stage failed: running bootc switch: error: Switching: Switching (ostree): Preparing import: Fetching manifest: Target image does not have ostree.bootable label: exit status 1' The full message in any case is present in the bootc daemon logs. Assisted-by: AI Signed-off-by: Alice Frosi <afrosi@redhat.com>
1 parent e33121e commit bc6f8a9

1 file changed

Lines changed: 14 additions & 6 deletions

File tree

internal/bootc/executor.go

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,10 @@ func (e *HostExecutor) Stage(ctx context.Context, image string) error {
8585
if ctx.Err() != nil {
8686
return ctx.Err()
8787
}
88-
e.copyJournalUnitLogs(log, stageUnitName, cursor)
88+
journalOutput := e.copyJournalUnitLogs(log, stageUnitName, cursor)
89+
if journalOutput != "" {
90+
return fmt.Errorf("running bootc switch: %s: %w", journalOutput, err)
91+
}
8992
return fmt.Errorf("running bootc switch: %w", err)
9093
}
9194
return nil
@@ -117,10 +120,10 @@ func (e *HostExecutor) journalCursor() string {
117120
return ""
118121
}
119122

120-
// copyJournalUnitLogs logs recent journal output from the given systemd unit.
121-
// If cursor is non-empty, only entries after that cursor are shown; otherwise
122-
// shows all entries.
123-
func (e *HostExecutor) copyJournalUnitLogs(log logr.Logger, unit string, cursor string) {
123+
// copyJournalUnitLogs logs recent journal output from the given systemd unit
124+
// and returns the raw output. If cursor is non-empty, only entries after that
125+
// cursor are shown; otherwise shows all entries.
126+
func (e *HostExecutor) copyJournalUnitLogs(log logr.Logger, unit string, cursor string) string {
124127
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
125128
defer cancel()
126129
args := []string{"journalctl", "-o", "cat", "--no-pager",
@@ -132,13 +135,18 @@ func (e *HostExecutor) copyJournalUnitLogs(log logr.Logger, unit string, cursor
132135
out, err := e.nsenterCmd(ctx, args...).Output()
133136
if err != nil {
134137
log.Error(err, "Failed to read unit journal", "unit", unit)
135-
return
138+
return ""
136139
}
140+
var errLines []string
137141
for _, line := range strings.Split(strings.TrimSpace(string(out)), "\n") {
138142
if line != "" {
139143
log.Info(line, "unit", unit)
144+
if strings.HasPrefix(line, "error:") {
145+
errLines = append(errLines, line)
146+
}
140147
}
141148
}
149+
return strings.Join(errLines, "\n")
142150
}
143151

144152
func (e *HostExecutor) Reboot(ctx context.Context) error {

0 commit comments

Comments
 (0)