mirror of
https://github.com/psviderski/uncloud.git
synced 2026-08-26 11:03:34 +00:00
fix: correctly wait for journalctl processes to not leave zombies when streaming machine logs (#325)
* fix: call cmd.Wait() Even though the context is cancelled we still need to call cmd.Wait() after a cmd.Start() to clean up the child (reap) process. Not doing so results in a zombie journalctl. I have manually tested this, as I'm still not sure how to e2e test for this in a simple manner. Before: ``` root@uncloud2:~# ps aux|grep jou root 313 0.0 1.2 42272 23352 ? S<s Apr20 0:10 /usr/lib/systemd/systemd-journald root 15751 0.0 0.0 0 0 pts/0 Z+ 07:02 0:00 [journalctl] <defunct> root 15754 0.0 0.0 0 0 pts/0 Z+ 07:02 0:00 [journalctl] <defunct> ``` After: ``` root 313 0.0 1.2 42272 23592 ? S<s Apr20 0:10 /usr/lib/systemd/systemd-journald ``` * follow() doesnt need wait We can keep the wait function more contraint, as follow does not need it Signed-off-by: Miek Gieben <miek@miek.nl> --------- Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
@@ -31,9 +31,9 @@ const journalctl = "journalctl"
|
||||
|
||||
var commandContext = exec.CommandContext // allow override for test
|
||||
|
||||
func logs(ctx context.Context, unit string, opts api.ServiceLogsOptions) (io.ReadCloser, error) {
|
||||
func logs(ctx context.Context, unit string, opts api.ServiceLogsOptions) (io.ReadCloser, func() error, error) {
|
||||
if !ValidUnit(unit) {
|
||||
return nil, fmt.Errorf("journal logs: invalid unit: %s", unit)
|
||||
return nil, nil, fmt.Errorf("journal logs: invalid unit: %s", unit)
|
||||
}
|
||||
args := []string{"-u", unit, "--no-hostname"}
|
||||
args = append(args, "-n")
|
||||
@@ -61,14 +61,14 @@ func logs(ctx context.Context, unit string, opts api.ServiceLogsOptions) (io.Rea
|
||||
cmd := commandContext(ctx, journalctl, args...)
|
||||
p, err := cmd.StdoutPipe()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
if err := cmd.Start(); err != nil {
|
||||
return nil, err
|
||||
return nil, nil, err
|
||||
}
|
||||
|
||||
return p, nil
|
||||
return p, cmd.Wait, nil
|
||||
}
|
||||
|
||||
// follow synchronously follows the io.Reader, writing each new journal entry to channel.
|
||||
|
||||
@@ -16,7 +16,7 @@ func Logs(ctx context.Context, unit string, opts api.ServiceLogsOptions) (<-chan
|
||||
return nil, fmt.Errorf("journal logs: invalid unit: %s", unit)
|
||||
}
|
||||
|
||||
reader, err := logs(ctx, unit, opts)
|
||||
reader, wait, err := logs(ctx, unit, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -26,6 +26,7 @@ func Logs(ctx context.Context, unit string, opts api.ServiceLogsOptions) (<-chan
|
||||
go func() {
|
||||
defer close(outCh)
|
||||
follow(ctx, reader, outCh)
|
||||
wait()
|
||||
}()
|
||||
|
||||
return outCh, nil
|
||||
|
||||
Reference in New Issue
Block a user