Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
996508d
server: use background context for network stop
haircommander Apr 26, 2021
6568e99
Cleanup pod network on sandbox removal
saschagrunert Apr 15, 2021
bccccf1
server: reuse container removal code for infra
haircommander Apr 15, 2021
3c418d5
storage: remove RemovePodSandbox function
haircommander Apr 15, 2021
a627960
server: breakup stop/remove all functions with internal helpers
haircommander Apr 15, 2021
3b4b5d6
config: add InternalWipe
haircommander Apr 15, 2021
230eeac
crio wipe: add support for internal_wipe
haircommander Apr 15, 2021
7ae3930
server: add support for internal_wipe
haircommander Apr 15, 2021
f0d91a2
test: add test for internal_wipe
haircommander Apr 15, 2021
d060232
Add resource cleaner retry functionality
saschagrunert Apr 16, 2021
87148ff
server: move newPodNetwork to a more logical place
haircommander Apr 16, 2021
d243f6d
server: get hooks after we've check if a sandbox is already stopped
haircommander Apr 16, 2021
1fcca60
InternalWipe: retry on failures
haircommander Apr 16, 2021
ce6527b
test: add test for delayed cleanup of network on restart
haircommander Apr 16, 2021
9e15b55
resourcestore: run cleanup in parallel
haircommander Apr 26, 2021
02c64b7
server: group namespace cleanup with network stop
haircommander Apr 21, 2021
b2eb270
server: don't unconditionally fail on sandbox cleanup
haircommander Apr 21, 2021
72385f4
sandbox: fix race with cleanup
haircommander Apr 26, 2021
616ae87
use more ContainerServer.StopContainer
haircommander Apr 26, 2021
20354c7
sandbox remove: unmount shm before removing infra container
haircommander Apr 26, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions cmd/crio/wipe.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ func crioWipe(c *cli.Context) error {
return handleCleanShutdown(config, store)
}

// If crio is configured to wipe internally (and `--force` wasn't set)
// the `crio wipe` command has nothing left to do,
// as the remaining work will be done on server startup.
if config.InternalWipe && !c.IsSet("force") {
return nil
}

logrus.Infof("Internal wipe not set, meaning crio wipe will wipe. In the future, all wipes after reboot will happen when starting the crio server.")

// if we should not wipe, exit with no error
if !shouldWipeContainers {
// we should not wipe images without wiping containers
Expand Down
1 change: 1 addition & 0 deletions completions/bash/crio
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ h
--image-volumes
--infra-ctr-cpuset
--insecure-registry
--internal-wipe
--irqbalance-config-file
--listen
--log
Expand Down
1 change: 1 addition & 0 deletions completions/fish/crio.fish
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ complete -c crio -n '__fish_crio_no_subcommand' -f -l insecure-registry -r -d 'E
be enabled for testing purposes**. For increased security, users should add
their CA to their system\'s list of trusted CAs instead of using
\'--insecure-registry\'.'
complete -c crio -n '__fish_crio_no_subcommand' -f -l internal-wipe -d 'Whether CRI-O should wipe containers after a reboot and images after an upgrade when the server starts. If set to false, one must run `crio wipe` to wipe the containers and images in these situations.'
complete -c crio -n '__fish_crio_no_subcommand' -f -l irqbalance-config-file -r -d 'The irqbalance service config file which is used by CRI-O.'
complete -c crio -n '__fish_crio_no_subcommand' -l listen -r -d 'Path to the CRI-O socket'
complete -c crio -n '__fish_crio_no_subcommand' -l log -r -d 'Set the log file path where internal debug information is written'
Expand Down
2 changes: 1 addition & 1 deletion completions/zsh/_crio
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ it later with **--config**. Global options will modify the output.' 'version:dis
_describe 'commands' cmds

local -a opts
opts=('--absent-mount-sources-to-reject' '--additional-devices' '--apparmor-profile' '--big-files-temporary-dir' '--bind-mount-prefix' '--cgroup-manager' '--clean-shutdown-file' '--cni-config-dir' '--cni-default-network' '--cni-plugin-dir' '--config' '--config-dir' '--conmon' '--conmon-cgroup' '--conmon-env' '--container-attach-socket-dir' '--container-exits-dir' '--ctr-stop-timeout' '--decryption-keys-path' '--default-capabilities' '--default-env' '--default-mounts-file' '--default-runtime' '--default-sysctls' '--default-transport' '--default-ulimits' '--drop-infra-ctr' '--enable-metrics' '--enable-profile-unix-socket' '--gid-mappings' '--global-auth-file' '--grpc-max-recv-msg-size' '--grpc-max-send-msg-size' '--hooks-dir' '--image-volumes' '--infra-ctr-cpuset' '--insecure-registry' '--irqbalance-config-file' '--listen' '--log' '--log-dir' '--log-filter' '--log-format' '--log-journald' '--log-level' '--log-size-max' '--metrics-port' '--metrics-socket' '--namespaces-dir' '--no-pivot' '--pause-command' '--pause-image' '--pause-image-auth-file' '--pids-limit' '--pinns-path' '--profile' '--profile-port' '--read-only' '--registries-conf' '--registries-conf-dir' '--registry' '--root' '--runroot' '--runtimes' '--seccomp-profile' '--seccomp-use-default-when-empty' '--selinux' '--separate-pull-cgroup' '--signature-policy' '--storage-driver' '--storage-opt' '--stream-address' '--stream-enable-tls' '--stream-idle-timeout' '--stream-port' '--stream-tls-ca' '--stream-tls-cert' '--stream-tls-key' '--uid-mappings' '--version-file' '--version-file-persist' '--help' '--version')
opts=('--absent-mount-sources-to-reject' '--additional-devices' '--apparmor-profile' '--big-files-temporary-dir' '--bind-mount-prefix' '--cgroup-manager' '--clean-shutdown-file' '--cni-config-dir' '--cni-default-network' '--cni-plugin-dir' '--config' '--config-dir' '--conmon' '--conmon-cgroup' '--conmon-env' '--container-attach-socket-dir' '--container-exits-dir' '--ctr-stop-timeout' '--decryption-keys-path' '--default-capabilities' '--default-env' '--default-mounts-file' '--default-runtime' '--default-sysctls' '--default-transport' '--default-ulimits' '--drop-infra-ctr' '--enable-metrics' '--enable-profile-unix-socket' '--gid-mappings' '--global-auth-file' '--grpc-max-recv-msg-size' '--grpc-max-send-msg-size' '--hooks-dir' '--image-volumes' '--infra-ctr-cpuset' '--insecure-registry' '--internal-wipe' '--irqbalance-config-file' '--listen' '--log' '--log-dir' '--log-filter' '--log-format' '--log-journald' '--log-level' '--log-size-max' '--metrics-port' '--metrics-socket' '--namespaces-dir' '--no-pivot' '--pause-command' '--pause-image' '--pause-image-auth-file' '--pids-limit' '--pinns-path' '--profile' '--profile-port' '--read-only' '--registries-conf' '--registries-conf-dir' '--registry' '--root' '--runroot' '--runtimes' '--seccomp-profile' '--seccomp-use-default-when-empty' '--selinux' '--separate-pull-cgroup' '--signature-policy' '--storage-driver' '--storage-opt' '--stream-address' '--stream-enable-tls' '--stream-idle-timeout' '--stream-port' '--stream-tls-ca' '--stream-tls-cert' '--stream-tls-key' '--uid-mappings' '--version-file' '--version-file-persist' '--help' '--version')
_describe 'global options' opts

return
Expand Down
3 changes: 3 additions & 0 deletions docs/crio.8.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ crio
[--image-volumes]=[value]
[--infra-ctr-cpuset]=[value]
[--insecure-registry]=[value]
[--internal-wipe]
[--irqbalance-config-file]=[value]
[--listen]=[value]
[--log-dir]=[value]
Expand Down Expand Up @@ -235,6 +236,8 @@ crio [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
their CA to their system's list of trusted CAs instead of using
'--insecure-registry'. (default: [])

**--internal-wipe**: Whether CRI-O should wipe containers after a reboot and images after an upgrade when the server starts. If set to false, one must run `crio wipe` to wipe the containers and images in these situations.

**--irqbalance-config-file**="": The irqbalance service config file which is used by CRI-O. (default: /etc/sysconfig/irqbalance)

**--listen**="": Path to the CRI-O socket (default: /var/run/crio/crio.sock)
Expand Down
4 changes: 4 additions & 0 deletions docs/crio.conf.5.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ CRI-O reads its storage defaults from the containers-storage.conf(5) file locate
It is used to check if crio wipe should wipe images, which should
only happen when CRI-O has been upgraded

**internal_wipe**=false
Whether CRI-O should wipe containers after a reboot and images after an upgrade when the server starts.
If set to false, one must run `crio wipe` to wipe the containers and images in these situations.

**clean_shutdown_file**="/var/lib/crio/clean.shutdown"
Location for CRI-O to lay down the clean shutdown file.
It is used to check whether crio had time to sync before shutting down.
Expand Down
9 changes: 9 additions & 0 deletions internal/criocli/criocli.go
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,9 @@ func mergeConfig(config *libconfig.Config, ctx *cli.Context) error {
if ctx.IsSet("absent-mount-sources-to-reject") {
config.AbsentMountSourcesToReject = StringSliceTrySplit(ctx, "absent-mount-sources-to-reject")
}
if ctx.IsSet("internal-wipe") {
config.InternalWipe = ctx.Bool("internal-wipe")
}
if ctx.IsSet("enable-metrics") {
config.EnableMetrics = ctx.Bool("enable-metrics")
}
Expand Down Expand Up @@ -839,6 +842,12 @@ func getCrioFlags(defConf *libconfig.Config) []cli.Flag {
EnvVars: []string{"CONTAINER_VERSION_FILE_PERSIST"},
TakesFile: true,
},
&cli.BoolFlag{
Name: "internal-wipe",
Usage: "Whether CRI-O should wipe containers after a reboot and images after an upgrade when the server starts. If set to false, one must run `crio wipe` to wipe the containers and images in these situations.",
Value: defConf.InternalWipe,
EnvVars: []string{"CONTAINER_INTERNAL_WIPE"},
},
&cli.StringFlag{
Name: "infra-ctr-cpuset",
Usage: "CPU set to run infra containers, if not specified CRI-O will use all online CPUs to run infra containers (default: '').",
Expand Down
3 changes: 1 addition & 2 deletions internal/lib/remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ func (c *ContainerServer) Remove(ctx context.Context, container string, force bo
return "", errors.Errorf("cannot remove paused container %s", ctrID)
case oci.ContainerStateCreated, oci.ContainerStateRunning:
if force {
_, err = c.ContainerStop(ctx, container, 10)
if err != nil {
if err = c.StopContainer(ctx, ctr, 10); err != nil {
return "", errors.Wrapf(err, "unable to stop container %s", ctrID)
}
} else {
Expand Down
5 changes: 5 additions & 0 deletions internal/lib/sandbox/sandbox.go
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,11 @@ func (s *Sandbox) createFileInInfraDir(filename string) error {
return nil
}
infra := s.InfraContainer()
// If the infra directory has been cleaned up already, we should not fail to
// create this file.
if _, err := os.Stat(infra.Dir()); os.IsNotExist(err) {
return nil
}
f, err := os.Create(filepath.Join(infra.Dir(), filename))
if err == nil {
f.Close()
Expand Down
21 changes: 7 additions & 14 deletions internal/lib/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,35 +10,28 @@ import (
)

// ContainerStop stops a running container with a grace period (i.e., timeout).
func (c *ContainerServer) ContainerStop(ctx context.Context, container string, timeout int64) (string, error) {
ctr, err := c.LookupContainer(container)
if err != nil {
return "", errors.Wrapf(err, "failed to find container %s", container)
}
ctrID := ctr.ID()

err = c.runtime.StopContainer(ctx, ctr, timeout)
if err != nil {
func (c *ContainerServer) StopContainer(ctx context.Context, ctr *oci.Container, timeout int64) error {
if err := c.runtime.StopContainer(ctx, ctr, timeout); err != nil {
// only fatally error if the error is not that the container was already stopped
// we still want to write container state to disk if the container has already
// been stopped
if err != oci.ErrContainerStopped {
return "", errors.Wrapf(err, "failed to stop container %s", ctrID)
return errors.Wrapf(err, "failed to stop container %s", ctr.ID())
}
} else {
// we only do these operations if StopContainer didn't fail (even if the failure
// was the container already being stopped)
if err := c.runtime.WaitContainerStateStopped(ctx, ctr); err != nil {
return "", errors.Wrapf(err, "failed to get container 'stopped' status %s", ctrID)
return errors.Wrapf(err, "failed to get container 'stopped' status %s", ctr.ID())
}
if err := c.storageRuntimeServer.StopContainer(ctrID); err != nil {
return "", errors.Wrapf(err, "failed to unmount container %s", ctrID)
if err := c.storageRuntimeServer.StopContainer(ctr.ID()); err != nil {
return errors.Wrapf(err, "failed to unmount container %s", ctr.ID())
}
}

if err := c.ContainerStateToDisk(ctx, ctr); err != nil {
log.Warnf(ctx, "unable to write containers %s state to disk: %v", ctr.ID(), err)
}

return ctrID, nil
return nil
}
26 changes: 0 additions & 26 deletions internal/lib/stop_test.go

This file was deleted.

76 changes: 64 additions & 12 deletions internal/resourcestore/resourcecleaner.go
Original file line number Diff line number Diff line change
@@ -1,33 +1,85 @@
package resourcestore

// A CleanupFunc is a function that cleans up one piece of
// the associated resource.
type CleanupFunc func()
import (
"context"
"time"

"github.com/pkg/errors"
"k8s.io/apimachinery/pkg/util/wait"

"github.com/cri-o/cri-o/internal/log"
)

// ResourceCleaner is a structure that tracks
// how to cleanup a resource.
// CleanupFuncs can be added to it, and it can be told to
// Cleanup the resource
type ResourceCleaner struct {
funcs []CleanupFunc
funcs []cleanupFunc
}

// A cleanupFunc is a function that cleans up one piece of
// the associated resource.
type cleanupFunc func() error

// NewResourceCleaner creates a new ResourceCleaner
func NewResourceCleaner() *ResourceCleaner {
return &ResourceCleaner{
funcs: make([]CleanupFunc, 0),
}
return &ResourceCleaner{}
}

// Add adds a new CleanupFunc to the ResourceCleaner
func (r *ResourceCleaner) Add(f func()) {
r.funcs = append(r.funcs, CleanupFunc(f))
func (r *ResourceCleaner) Add(
ctx context.Context,
description string,
fn func() error,
) {
// Create a retry task on top of the provided function
task := func() error {
err := retry(ctx, fn)
if err != nil {
log.Errorf(ctx,
"Retried cleanup function %q too often, giving up",
description,
)
}
return err
}

// Prepend reverse iterate by default
r.funcs = append([]cleanupFunc{task}, r.funcs...)
}

// Cleanup cleans up the resource, running
// the cleanup funcs in opposite chronological order
func (r *ResourceCleaner) Cleanup() {
for i := len(r.funcs) - 1; i >= 0; i-- {
r.funcs[i]()
func (r *ResourceCleaner) Cleanup() error {
for _, f := range r.funcs {
if err := f(); err != nil {
return err
}
}
return nil
}

// retry attempts to execute fn up to defaultRetryTimes if its failure meets
// retryCondition.
func retry(ctx context.Context, fn func() error) error {
backoff := wait.Backoff{
Duration: 500 * time.Millisecond,
Factor: 1.5,
Steps: defaultRetryTimes,
}

waitErr := wait.ExponentialBackoff(backoff, func() (bool, error) {
if err := fn(); err != nil {
log.Errorf(ctx, "Failed to cleanup (probably retrying): %v", err)
return false, nil
}
return true, nil
})

if waitErr != nil {
return errors.Wrap(waitErr, "wait on retry")
}

return nil
}
7 changes: 7 additions & 0 deletions internal/resourcestore/resourcecleaner_defaults.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// +build !test

package resourcestore

// defaultRetryTimes defines the amount of default retries for each cleanup
// function.
var defaultRetryTimes = 20
105 changes: 105 additions & 0 deletions internal/resourcestore/resourcecleaner_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package resourcestore_test

import (
"errors"

"github.com/cri-o/cri-o/internal/resourcestore"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
"golang.org/x/net/context"
)

// The actual test suite
var _ = t.Describe("ResourceCleaner", func() {
It("should call the cleanup functions", func() {
// Given
sut := resourcestore.NewResourceCleaner()
called1 := false
called2 := false
sut.Add(context.Background(), "test1", func() error {
called1 = true
return nil
})
sut.Add(context.Background(), "test2", func() error {
called2 = true
return nil
})

// When
err := sut.Cleanup()

// Then
Expect(err).To(BeNil())
Expect(called1).To(BeTrue())
Expect(called2).To(BeTrue())
})

It("should retry the cleanup functions", func() {
// Given
sut := resourcestore.NewResourceCleaner()
called1 := false
called2 := false
sut.Add(context.Background(), "test1", func() error {
called1 = true
return nil
})
failureCnt := 0
sut.Add(context.Background(), "test2", func() error {
if failureCnt == 2 {
called2 = true
return nil
}
failureCnt++
return errors.New("")
})

// When
err := sut.Cleanup()

// Then
Expect(err).To(BeNil())
Expect(called1).To(BeTrue())
Expect(called2).To(BeTrue())
Expect(failureCnt).To(Equal(2))
})

It("should retry three times", func() {
// Given
sut := resourcestore.NewResourceCleaner()
failureCnt := 0
sut.Add(context.Background(), "test", func() error {
failureCnt++
return errors.New("")
})

// When
err := sut.Cleanup()

// Then
Expect(err).NotTo(BeNil())
Expect(failureCnt).To(Equal(3))
})

It("should run in parallel", func() {
// Given
sut := resourcestore.NewResourceCleaner()
testChan := make(chan bool, 1)
succ := false
sut.Add(context.Background(), "test1", func() error {
testChan <- true
return nil
})
sut.Add(context.Background(), "test2", func() error {
<-testChan
succ = true
return nil
})

// When
err := sut.Cleanup()

// Then
Expect(err).To(BeNil())
Expect(succ).To(BeTrue())
})
})
Loading