mirror of
https://github.com/opencontainers/runc.git
synced 2026-07-11 06:03:57 +08:00
Merge pull request #5186 from kolyshkin/poststart
Move poststart hook from runc create to runc start
This commit is contained in:
@@ -19,6 +19,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
`github.com/moby/sys/devices` (which is a carbon copy of the package). It
|
`github.com/moby/sys/devices` (which is a carbon copy of the package). It
|
||||||
will be removed in runc 1.6.
|
will be removed in runc 1.6.
|
||||||
|
|
||||||
|
### Fixed ###
|
||||||
|
- The poststart hooks are now executed after starting the user-specified
|
||||||
|
process, fixing a runtime-spec conformance issue. (#4347, #5186)
|
||||||
|
|
||||||
## [1.5.0-rc.1] - 2026-03-12
|
## [1.5.0-rc.1] - 2026-03-12
|
||||||
|
|
||||||
> 憎しみを束ねてもそれは脆い!
|
> 憎しみを束ねてもそれは脆い!
|
||||||
|
|||||||
@@ -232,7 +232,14 @@ func (c *Container) Exec() error {
|
|||||||
|
|
||||||
func (c *Container) exec() error {
|
func (c *Container) exec() error {
|
||||||
path := filepath.Join(c.stateDir, execFifoFilename)
|
path := filepath.Join(c.stateDir, execFifoFilename)
|
||||||
pid := c.initProcess.pid()
|
if err := handleFifo(path, c.initProcess.pid()); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.postStart()
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleFifo(path string, pid int) error {
|
||||||
blockingFifoOpenCh := awaitFifoOpen(path)
|
blockingFifoOpenCh := awaitFifoOpen(path)
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
@@ -253,6 +260,29 @@ func (c *Container) exec() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Container) postStart() (retErr error) {
|
||||||
|
if !c.config.HasHook(configs.Poststart) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
if retErr != nil {
|
||||||
|
// A poststart hook failed; kill the container.
|
||||||
|
if err := c.signal(unix.SIGKILL); err != nil && !errors.Is(err, ErrNotRunning) {
|
||||||
|
logrus.WithError(err).Warn("kill after failed poststart")
|
||||||
|
}
|
||||||
|
// We're still init's parent so wait is required.
|
||||||
|
_, _ = c.initProcess.wait()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
s, err := c.currentOCIState()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return c.config.Hooks.Run(configs.Poststart, s)
|
||||||
|
}
|
||||||
|
|
||||||
func readFromExecFifo(execFifo io.Reader) error {
|
func readFromExecFifo(execFifo io.Reader) error {
|
||||||
data, err := io.ReadAll(execFifo)
|
data, err := io.ReadAll(execFifo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -371,19 +401,6 @@ func (c *Container) start(process *Process) (retErr error) {
|
|||||||
|
|
||||||
if process.Init {
|
if process.Init {
|
||||||
c.fifo.Close()
|
c.fifo.Close()
|
||||||
if c.config.HasHook(configs.Poststart) {
|
|
||||||
s, err := c.currentOCIState()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := c.config.Hooks.Run(configs.Poststart, s); err != nil {
|
|
||||||
if err := ignoreTerminateErrors(parent.terminate()); err != nil {
|
|
||||||
logrus.Warn(fmt.Errorf("error running poststart hook: %w", err))
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -396,7 +413,10 @@ func (c *Container) start(process *Process) (retErr error) {
|
|||||||
func (c *Container) Signal(s os.Signal) error {
|
func (c *Container) Signal(s os.Signal) error {
|
||||||
c.m.Lock()
|
c.m.Lock()
|
||||||
defer c.m.Unlock()
|
defer c.m.Unlock()
|
||||||
|
return c.signal(s)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Container) signal(s os.Signal) error {
|
||||||
// When a container has its own PID namespace, inside it the init PID
|
// When a container has its own PID namespace, inside it the init PID
|
||||||
// is 1, and thus it is handled specially by the kernel. In particular,
|
// is 1, and thus it is handled specially by the kernel. In particular,
|
||||||
// killing init with SIGKILL from an ancestor namespace will also kill
|
// killing init with SIGKILL from an ancestor namespace will also kill
|
||||||
@@ -410,7 +430,7 @@ func (c *Container) Signal(s os.Signal) error {
|
|||||||
logrus.WithError(err).Warn("failed to kill all processes, possibly due to lack of cgroup (Hint: enable cgroup v2 delegation)")
|
logrus.WithError(err).Warn("failed to kill all processes, possibly due to lack of cgroup (Hint: enable cgroup v2 delegation)")
|
||||||
// Some processes may leak when cgroup is not delegated
|
// Some processes may leak when cgroup is not delegated
|
||||||
// https://github.com/opencontainers/runc/pull/4395#pullrequestreview-2291179652
|
// https://github.com/opencontainers/runc/pull/4395#pullrequestreview-2291179652
|
||||||
return c.signal(s)
|
return c.signalInit(s)
|
||||||
}
|
}
|
||||||
// For not rootless container, if there is no init process and no cgroup,
|
// For not rootless container, if there is no init process and no cgroup,
|
||||||
// it means that the container is not running.
|
// it means that the container is not running.
|
||||||
@@ -422,10 +442,10 @@ func (c *Container) Signal(s os.Signal) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return c.signal(s)
|
return c.signalInit(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) signal(s os.Signal) error {
|
func (c *Container) signalInit(s os.Signal) error {
|
||||||
// To avoid a PID reuse attack, don't kill non-running container.
|
// To avoid a PID reuse attack, don't kill non-running container.
|
||||||
if !c.hasInit() {
|
if !c.hasInit() {
|
||||||
return ErrNotRunning
|
return ErrNotRunning
|
||||||
|
|||||||
@@ -35,7 +35,11 @@ function teardown() {
|
|||||||
echo "testing hook $hook"
|
echo "testing hook $hook"
|
||||||
update_config '.hooks |= {"'$hook'": [{"path": "/bin/true"}, {"path": "/bin/false"}]}'
|
update_config '.hooks |= {"'$hook'": [{"path": "/bin/true"}, {"path": "/bin/false"}]}'
|
||||||
runc run "test_hook-$hook"
|
runc run "test_hook-$hook"
|
||||||
|
# Failed poststart hooks results in container being killed,
|
||||||
|
# but only after it has started, so output may or may not appear.
|
||||||
|
if [ "$hook" != "poststart" ]; then
|
||||||
[[ "$output" != "Hello World" ]]
|
[[ "$output" != "Hello World" ]]
|
||||||
|
fi
|
||||||
[ "$status" -ne 0 ]
|
[ "$status" -ne 0 ]
|
||||||
[[ "$output" == *"error running $hook hook #1:"* ]]
|
[[ "$output" == *"error running $hook hook #1:"* ]]
|
||||||
done
|
done
|
||||||
|
|||||||
Reference in New Issue
Block a user