mirror of
https://github.com/kata-containers/kata-containers.git
synced 2025-06-30 09:13:29 +00:00
sandbox: support force stop
When force is true, ignore any guest related errors. This can be used to stop a sandbox when hypervisor process is dead. Signed-off-by: Peng Tao <bergwolf@hyper.sh>
This commit is contained in:
parent
4130913ed7
commit
bc4460e12f
@ -112,7 +112,7 @@ func delete(ctx context.Context, containerID string, force bool) error {
|
|||||||
|
|
||||||
switch containerType {
|
switch containerType {
|
||||||
case vc.PodSandbox:
|
case vc.PodSandbox:
|
||||||
if err := deleteSandbox(ctx, sandboxID); err != nil {
|
if err := deleteSandbox(ctx, sandboxID, force); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case vc.PodContainer:
|
case vc.PodContainer:
|
||||||
@ -131,7 +131,7 @@ func delete(ctx context.Context, containerID string, force bool) error {
|
|||||||
return katautils.DelContainerIDMapping(ctx, containerID)
|
return katautils.DelContainerIDMapping(ctx, containerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteSandbox(ctx context.Context, sandboxID string) error {
|
func deleteSandbox(ctx context.Context, sandboxID string, force bool) error {
|
||||||
span, _ := katautils.Trace(ctx, "deleteSandbox")
|
span, _ := katautils.Trace(ctx, "deleteSandbox")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ func deleteSandbox(ctx context.Context, sandboxID string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if oci.StateToOCIState(status.State.State) != oci.StateStopped {
|
if oci.StateToOCIState(status.State.State) != oci.StateStopped {
|
||||||
if _, err := vci.StopSandbox(ctx, sandboxID); err != nil {
|
if _, err := vci.StopSandbox(ctx, sandboxID, force); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ func kill(ctx context.Context, containerID, signal string, all bool) error {
|
|||||||
|
|
||||||
switch containerType {
|
switch containerType {
|
||||||
case vc.PodSandbox:
|
case vc.PodSandbox:
|
||||||
_, err = vci.StopSandbox(ctx, sandboxID)
|
_, err = vci.StopSandbox(ctx, sandboxID, signum == syscall.SIGKILL)
|
||||||
case vc.PodContainer:
|
case vc.PodContainer:
|
||||||
_, err = vci.StopContainer(ctx, sandboxID, containerID)
|
_, err = vci.StopContainer(ctx, sandboxID, containerID)
|
||||||
default:
|
default:
|
||||||
|
@ -70,7 +70,7 @@ func cleanupContainer(ctx context.Context, sid, cid, bundlePath string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if len(sandbox.GetAllContainers()) == 0 {
|
if len(sandbox.GetAllContainers()) == 0 {
|
||||||
err = sandbox.Stop()
|
err = sandbox.Stop(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).WithField("sandbox", sid).Warn("failed to stop sandbox")
|
logrus.WithError(err).WithField("sandbox", sid).Warn("failed to stop sandbox")
|
||||||
return err
|
return err
|
||||||
|
@ -51,7 +51,7 @@ func wait(s *service, c *container, execID string) (int32, error) {
|
|||||||
// sandbox.
|
// sandbox.
|
||||||
|
|
||||||
if c.cType.IsSandbox() {
|
if c.cType.IsSandbox() {
|
||||||
if err = s.sandbox.Stop(); err != nil {
|
if err = s.sandbox.Stop(true); err != nil {
|
||||||
logrus.WithField("sandbox", s.sandbox.ID()).Error("failed to stop sandbox")
|
logrus.WithField("sandbox", s.sandbox.ID()).Error("failed to stop sandbox")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ func StartSandbox(ctx context.Context, sandboxID string) (VCSandbox, error) {
|
|||||||
|
|
||||||
// StopSandbox is the virtcontainers sandbox stopping entry point.
|
// StopSandbox is the virtcontainers sandbox stopping entry point.
|
||||||
// StopSandbox will talk to the given agent to stop an existing sandbox and destroy all containers within that sandbox.
|
// StopSandbox will talk to the given agent to stop an existing sandbox and destroy all containers within that sandbox.
|
||||||
func StopSandbox(ctx context.Context, sandboxID string) (VCSandbox, error) {
|
func StopSandbox(ctx context.Context, sandboxID string, force bool) (VCSandbox, error) {
|
||||||
span, ctx := trace(ctx, "StopSandbox")
|
span, ctx := trace(ctx, "StopSandbox")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
@ -257,7 +257,7 @@ func StopSandbox(ctx context.Context, sandboxID string) (VCSandbox, error) {
|
|||||||
defer s.releaseStatelessSandbox()
|
defer s.releaseStatelessSandbox()
|
||||||
|
|
||||||
// Stop it.
|
// Stop it.
|
||||||
err = s.Stop()
|
err = s.Stop(force)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -596,7 +596,7 @@ func statusContainer(sandbox *Sandbox, containerID string) (ContainerStatus, err
|
|||||||
"state": container.state.State,
|
"state": container.state.State,
|
||||||
"pid": container.process.Pid}).
|
"pid": container.process.Pid}).
|
||||||
Info("container isn't running")
|
Info("container isn't running")
|
||||||
if err := container.stop(); err != nil {
|
if err := container.stop(true); err != nil {
|
||||||
return ContainerStatus{}, err
|
return ContainerStatus{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -332,7 +332,7 @@ func TestStopSandboxNoopAgentSuccessful(t *testing.T) {
|
|||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
assert.NotNil(p)
|
assert.NotNil(p)
|
||||||
|
|
||||||
vp, err := StopSandbox(ctx, p.ID())
|
vp, err := StopSandbox(ctx, p.ID(), false)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
assert.NotNil(vp)
|
assert.NotNil(vp)
|
||||||
}
|
}
|
||||||
@ -427,7 +427,7 @@ func TestStopSandboxKataAgentSuccessful(t *testing.T) {
|
|||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
assert.NotNil(p)
|
assert.NotNil(p)
|
||||||
|
|
||||||
p, err = StopSandbox(ctx, p.ID())
|
p, err = StopSandbox(ctx, p.ID(), false)
|
||||||
assert.NoError(err)
|
assert.NoError(err)
|
||||||
assert.NotNil(p)
|
assert.NotNil(p)
|
||||||
}
|
}
|
||||||
@ -438,7 +438,7 @@ func TestStopSandboxFailing(t *testing.T) {
|
|||||||
sandboxDir := store.SandboxConfigurationRootPath(testSandboxID)
|
sandboxDir := store.SandboxConfigurationRootPath(testSandboxID)
|
||||||
os.Remove(sandboxDir)
|
os.Remove(sandboxDir)
|
||||||
|
|
||||||
p, err := StopSandbox(context.Background(), testSandboxID)
|
p, err := StopSandbox(context.Background(), testSandboxID, false)
|
||||||
assert.Error(t, err)
|
assert.Error(t, err)
|
||||||
assert.Nil(t, p)
|
assert.Nil(t, p)
|
||||||
}
|
}
|
||||||
@ -1461,7 +1461,7 @@ func createStartStopDeleteSandbox(b *testing.B, sandboxConfig SandboxConfig) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stop sandbox
|
// Stop sandbox
|
||||||
_, err = StopSandbox(ctx, p.ID())
|
_, err = StopSandbox(ctx, p.ID(), false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
b.Fatalf("Could not stop sandbox: %s", err)
|
b.Fatalf("Could not stop sandbox: %s", err)
|
||||||
}
|
}
|
||||||
|
@ -946,7 +946,7 @@ func (c *Container) start() error {
|
|||||||
if err := c.sandbox.agent.startContainer(c.sandbox, c); err != nil {
|
if err := c.sandbox.agent.startContainer(c.sandbox, c); err != nil {
|
||||||
c.Logger().WithError(err).Error("Failed to start container")
|
c.Logger().WithError(err).Error("Failed to start container")
|
||||||
|
|
||||||
if err := c.stop(); err != nil {
|
if err := c.stop(true); err != nil {
|
||||||
c.Logger().WithError(err).Warn("Failed to stop container")
|
c.Logger().WithError(err).Warn("Failed to stop container")
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
@ -955,7 +955,7 @@ func (c *Container) start() error {
|
|||||||
return c.setContainerState(types.StateRunning)
|
return c.setContainerState(types.StateRunning)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *Container) stop() error {
|
func (c *Container) stop(force bool) error {
|
||||||
span, _ := c.trace("stop")
|
span, _ := c.trace("stop")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
@ -999,7 +999,7 @@ func (c *Container) stop() error {
|
|||||||
// return an error, but instead try to kill it forcefully.
|
// return an error, but instead try to kill it forcefully.
|
||||||
if err := waitForShim(c.process.Pid); err != nil {
|
if err := waitForShim(c.process.Pid); err != nil {
|
||||||
// Force the container to be killed.
|
// Force the container to be killed.
|
||||||
if err := c.kill(syscall.SIGKILL, true); err != nil {
|
if err := c.kill(syscall.SIGKILL, true); err != nil && !force {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1007,7 +1007,7 @@ func (c *Container) stop() error {
|
|||||||
// to succeed. Indeed, we have already given a second chance
|
// to succeed. Indeed, we have already given a second chance
|
||||||
// to the container by trying to kill it with SIGKILL, there
|
// to the container by trying to kill it with SIGKILL, there
|
||||||
// is no reason to try to go further if we got an error.
|
// is no reason to try to go further if we got an error.
|
||||||
if err := waitForShim(c.process.Pid); err != nil {
|
if err := waitForShim(c.process.Pid); err != nil && !force {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1045,15 +1045,15 @@ func (c *Container) stop() error {
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
if err := c.sandbox.agent.stopContainer(c.sandbox, *c); err != nil {
|
if err := c.sandbox.agent.stopContainer(c.sandbox, *c); err != nil && !force {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.detachDevices(); err != nil {
|
if err := c.detachDevices(); err != nil && !force {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := c.removeDrive(); err != nil {
|
if err := c.removeDrive(); err != nil && !force {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,8 +52,8 @@ func (impl *VCImpl) StartSandbox(ctx context.Context, sandboxID string) (VCSandb
|
|||||||
}
|
}
|
||||||
|
|
||||||
// StopSandbox implements the VC function of the same name.
|
// StopSandbox implements the VC function of the same name.
|
||||||
func (impl *VCImpl) StopSandbox(ctx context.Context, sandboxID string) (VCSandbox, error) {
|
func (impl *VCImpl) StopSandbox(ctx context.Context, sandboxID string, force bool) (VCSandbox, error) {
|
||||||
return StopSandbox(ctx, sandboxID)
|
return StopSandbox(ctx, sandboxID, force)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RunSandbox implements the VC function of the same name.
|
// RunSandbox implements the VC function of the same name.
|
||||||
|
@ -32,7 +32,7 @@ type VC interface {
|
|||||||
RunSandbox(ctx context.Context, sandboxConfig SandboxConfig) (VCSandbox, error)
|
RunSandbox(ctx context.Context, sandboxConfig SandboxConfig) (VCSandbox, error)
|
||||||
StartSandbox(ctx context.Context, sandboxID string) (VCSandbox, error)
|
StartSandbox(ctx context.Context, sandboxID string) (VCSandbox, error)
|
||||||
StatusSandbox(ctx context.Context, sandboxID string) (SandboxStatus, error)
|
StatusSandbox(ctx context.Context, sandboxID string) (SandboxStatus, error)
|
||||||
StopSandbox(ctx context.Context, sandboxID string) (VCSandbox, error)
|
StopSandbox(ctx context.Context, sandboxID string, force bool) (VCSandbox, error)
|
||||||
|
|
||||||
CreateContainer(ctx context.Context, sandboxID string, containerConfig ContainerConfig) (VCSandbox, VCContainer, error)
|
CreateContainer(ctx context.Context, sandboxID string, containerConfig ContainerConfig) (VCSandbox, VCContainer, error)
|
||||||
DeleteContainer(ctx context.Context, sandboxID, containerID string) (VCContainer, error)
|
DeleteContainer(ctx context.Context, sandboxID, containerID string) (VCContainer, error)
|
||||||
@ -68,7 +68,7 @@ type VCSandbox interface {
|
|||||||
SetAnnotations(annotations map[string]string) error
|
SetAnnotations(annotations map[string]string) error
|
||||||
|
|
||||||
Start() error
|
Start() error
|
||||||
Stop() error
|
Stop(force bool) error
|
||||||
Pause() error
|
Pause() error
|
||||||
Resume() error
|
Resume() error
|
||||||
Release() error
|
Release() error
|
||||||
|
@ -74,7 +74,7 @@ func (s *Sandbox) Start() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stop implements the VCSandbox function of the same name.
|
// Stop implements the VCSandbox function of the same name.
|
||||||
func (s *Sandbox) Stop() error {
|
func (s *Sandbox) Stop(force bool) error {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1161,7 +1161,7 @@ func (s *Sandbox) StopContainer(containerID string) (VCContainer, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stop it.
|
// Stop it.
|
||||||
if err := c.stop(); err != nil {
|
if err := c.stop(false); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1427,7 +1427,8 @@ func (s *Sandbox) Start() error {
|
|||||||
|
|
||||||
// Stop stops a sandbox. The containers that are making the sandbox
|
// Stop stops a sandbox. The containers that are making the sandbox
|
||||||
// will be destroyed.
|
// will be destroyed.
|
||||||
func (s *Sandbox) Stop() error {
|
// When force is true, ignore guest related stop failures.
|
||||||
|
func (s *Sandbox) Stop(force bool) error {
|
||||||
span, _ := s.trace("stop")
|
span, _ := s.trace("stop")
|
||||||
defer span.Finish()
|
defer span.Finish()
|
||||||
|
|
||||||
@ -1441,12 +1442,12 @@ func (s *Sandbox) Stop() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range s.containers {
|
for _, c := range s.containers {
|
||||||
if err := c.stop(); err != nil {
|
if err := c.stop(force); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.stopVM(); err != nil {
|
if err := s.stopVM(); err != nil && !force {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1455,7 +1456,7 @@ func (s *Sandbox) Stop() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove the network.
|
// Remove the network.
|
||||||
if err := s.removeNetwork(); err != nil {
|
if err := s.removeNetwork(); err != nil && !force {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1350,7 +1350,7 @@ func TestSandboxStopStopped(t *testing.T) {
|
|||||||
ctx: context.Background(),
|
ctx: context.Background(),
|
||||||
state: types.SandboxState{State: types.StateStopped},
|
state: types.SandboxState{State: types.StateStopped},
|
||||||
}
|
}
|
||||||
err := s.Stop()
|
err := s.Stop(false)
|
||||||
|
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user