WithStartupCommand silently swallows non-zero exit codes from the inner command
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 76/100
- issue の種類
- バグ
- 明瞭さ
- 明確に書かれている
- 活発さ
- 静か
- 技術スタック
- docker, go
調査の方向性
container/options.go の createExecutableHooks から始め、次に container/container.exec.go の Container.Exec を調べて、終了コードとエラーがどのように返されるかを確認します。WithStartupCommand と WithAfterReadyCommand のゼロ以外のコードが失敗として報告され、ゼロのコードと実行エラーが期待される動作を維持すれば、変更は完了です。
索引モデルが issue の本文から書いたものです。
説明
Summary
container.WithStartupCommand registers a PostStarts lifecycle hook that runs each Executable via Container.Exec. When the inner command exits non-zero, the hook returns nil and container.Run reports success. The container ends up in a "running but the startup command failed" state with no visible signal to the caller.
Where
-
The hook is built in
container/options.go(createExecutableHooks):execFn := func(ctx context.Context, c ContainerInfo) error { if executor, ok := c.(ContainerExecutor); ok { _, _, err := executor.Exec(ctx, exec.AsCommand(), exec.Options()...) return err } return errors.New("container does not support execution") } -
Container.Execincontainer/container.exec.goreturns(int, io.Reader, error). The first return is the inner process's exit code — a value, not an error. The hook discards it.
Reproduction
c, err := container.Run(ctx,
container.WithImage("alpine:latest"),
container.WithEntrypoint("tail", "-f", "/dev/null"),
container.WithStartupCommand(exec.NewRawCommand([]string{"false"})),
)
// err == nil; c is up; the failing startup command is invisible.
This bites consumers in two ways:
- First-create coverage doesn't fail loudly. A startup command that errors is silently ignored at create time. The caller has no way to discover the failure short of checking side effects.
- The same trap applies to
WithAfterReadyCommand(same hook factory).
I hit this while writing tests for WithDurableStartupCommand (#154): a WithUser("nonexistent") case where su aborts, the rendered dispatcher exits non-zero, but Run still succeeds. I had to invoke the dispatcher directly via c.Exec and check the exit code value to observe the failure.
Suggested fix
Have createExecutableHooks (or a thin helper) treat a non-zero exit code as an error:
execFn := func(ctx context.Context, c ContainerInfo) error {
executor, ok := c.(ContainerExecutor)
if !ok {
return errors.New("container does not support execution")
}
code, _, err := executor.Exec(ctx, exec.AsCommand(), exec.Options()...)
if err != nil {
return err
}
if code != 0 {
return fmt.Errorf("startup command %v exited with code %d", exec.AsCommand(), code)
}
return nil
}
This is a behavioural change for any caller that today relies on startup-command failures being invisible — but I'd expect that population to be small, and the silent-failure mode is more dangerous than the loud one.
If a strictly backwards-compatible variant is preferred, an opt-in option (WithStrictStartupCommand?) could keep the current behaviour as the default.
Out of scope (but related)
Container.Exec's signature returning(int, io.Reader, error)makes the exit code easy to ignore. A future API revision could fold non-zero into theerrorreturn; for now, fixing the hook is the smaller change.
- 主要言語
- Go
- スター
- 133
- フォーク
- 28
- 平均マージ
- 3時間 55分
- マージ済み PR(30日)
- 4
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
docker/go-sdk のほかの issue
-
Add Inspect method to the volume module対応中かも @xHozey が 3 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 66/100
-
Proposal: Consider storing container name in Container struct対応中かも @xHozey が 265 日前に担当しました。 オープン
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
-
enhancement
難易度 5/5 1週間以上 初心者へのやさしさ 25/100
-
chore
難易度 5/5 1週間以上 初心者へのやさしさ 30/100
-
chore
難易度 5/5 1週間以上 初心者へのやさしさ 10/100
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 76/100
-
blocked-needs-validation bug
難易度 1/5 1時間未満 初心者へのやさしさ 78/100
projectcapsule/capsule#2280 ·
メンテナーはふだん 1 日以内に返信
-
bug ready-for-agent
難易度 2/5 1〜3時間 初心者へのやさしさ 86/100
kerti/balances-v2#801 ·
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1〜3時間 初心者へのやさしさ 82/100
メンテナーはふだん 1 日以内に返信
-
[BUG] AdvancedCronJob validating webhook reports incorrect field paths for concurrencyPolicy and pod templates対応中かも @bhuvan-somisetty が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
openkruise/kruise#2650 ·
メンテナーはふだん 1 日以内に返信