diff --git a/.golangci.yml b/.golangci.yml index 8a20f79e8..4c213b1e1 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -23,6 +23,11 @@ issues: max-issues-per-linter: 0 max-same-issues: 0 + # Only using / doesn't work due to https://github.com/golangci/golangci-lint/issues/1398. + exclude-rules: + - path: 'cmd[\\/]containerd[\\/]builtins[\\/]' + text: "blank-imports:" + linters-settings: gosec: # The following issues surfaced when `gosec` linter diff --git a/cmd/containerd/builtins_aufs_linux.go b/cmd/containerd/builtins/aufs_linux.go similarity index 97% rename from cmd/containerd/builtins_aufs_linux.go rename to cmd/containerd/builtins/aufs_linux.go index f06e01f25..f7f77057c 100644 --- a/cmd/containerd/builtins_aufs_linux.go +++ b/cmd/containerd/builtins/aufs_linux.go @@ -17,6 +17,6 @@ limitations under the License. */ -package main +package builtins import _ "github.com/containerd/aufs/plugin" diff --git a/cmd/containerd/builtins_btrfs_linux.go b/cmd/containerd/builtins/btrfs_linux.go similarity index 97% rename from cmd/containerd/builtins_btrfs_linux.go rename to cmd/containerd/builtins/btrfs_linux.go index a6b11ca2a..a66ab284b 100644 --- a/cmd/containerd/builtins_btrfs_linux.go +++ b/cmd/containerd/builtins/btrfs_linux.go @@ -17,6 +17,6 @@ limitations under the License. */ -package main +package builtins import _ "github.com/containerd/containerd/snapshots/btrfs/plugin" diff --git a/cmd/containerd/builtins.go b/cmd/containerd/builtins/builtins.go similarity index 99% rename from cmd/containerd/builtins.go rename to cmd/containerd/builtins/builtins.go index 8ad1f7fdf..3e64dcea5 100644 --- a/cmd/containerd/builtins.go +++ b/cmd/containerd/builtins/builtins.go @@ -14,7 +14,7 @@ limitations under the License. */ -package main +package builtins // register containerd builtins here import ( diff --git a/cmd/containerd/builtins_freebsd.go b/cmd/containerd/builtins/builtins_freebsd.go similarity index 97% rename from cmd/containerd/builtins_freebsd.go rename to cmd/containerd/builtins/builtins_freebsd.go index 2528586ac..c7fdbe190 100644 --- a/cmd/containerd/builtins_freebsd.go +++ b/cmd/containerd/builtins/builtins_freebsd.go @@ -14,6 +14,6 @@ limitations under the License. */ -package main +package builtins import _ "github.com/containerd/zfs/plugin" diff --git a/cmd/containerd/builtins_linux.go b/cmd/containerd/builtins/builtins_linux.go similarity index 98% rename from cmd/containerd/builtins_linux.go rename to cmd/containerd/builtins/builtins_linux.go index bb0defd68..2671606f4 100644 --- a/cmd/containerd/builtins_linux.go +++ b/cmd/containerd/builtins/builtins_linux.go @@ -14,7 +14,7 @@ limitations under the License. */ -package main +package builtins import ( _ "github.com/containerd/containerd/metrics/cgroups" diff --git a/cmd/containerd/builtins_unix.go b/cmd/containerd/builtins/builtins_unix.go similarity index 97% rename from cmd/containerd/builtins_unix.go rename to cmd/containerd/builtins/builtins_unix.go index 2e5c1fa26..5b9eced4b 100644 --- a/cmd/containerd/builtins_unix.go +++ b/cmd/containerd/builtins/builtins_unix.go @@ -17,7 +17,7 @@ limitations under the License. */ -package main +package builtins import ( _ "github.com/containerd/containerd/snapshots/native/plugin" diff --git a/cmd/containerd/builtins_windows.go b/cmd/containerd/builtins/builtins_windows.go similarity index 97% rename from cmd/containerd/builtins_windows.go rename to cmd/containerd/builtins/builtins_windows.go index 8861ca3c8..3ba975a1a 100644 --- a/cmd/containerd/builtins_windows.go +++ b/cmd/containerd/builtins/builtins_windows.go @@ -14,7 +14,7 @@ limitations under the License. */ -package main +package builtins import ( _ "github.com/containerd/containerd/diff/lcow" diff --git a/cmd/containerd/builtins_devmapper_linux.go b/cmd/containerd/builtins/devmapper_linux.go similarity index 97% rename from cmd/containerd/builtins_devmapper_linux.go rename to cmd/containerd/builtins/devmapper_linux.go index 0c036242c..b1b0578f0 100644 --- a/cmd/containerd/builtins_devmapper_linux.go +++ b/cmd/containerd/builtins/devmapper_linux.go @@ -17,6 +17,6 @@ limitations under the License. */ -package main +package builtins import _ "github.com/containerd/containerd/snapshots/devmapper/plugin" diff --git a/cmd/containerd/builtins_tracing.go b/cmd/containerd/builtins/tracing.go similarity index 97% rename from cmd/containerd/builtins_tracing.go rename to cmd/containerd/builtins/tracing.go index 668e990c0..a1d068e56 100644 --- a/cmd/containerd/builtins_tracing.go +++ b/cmd/containerd/builtins/tracing.go @@ -17,7 +17,7 @@ limitations under the License. */ -package main +package builtins import ( _ "github.com/containerd/containerd/tracing/plugin" diff --git a/cmd/containerd/builtins_zfs_linux.go b/cmd/containerd/builtins/zfs_linux.go similarity index 97% rename from cmd/containerd/builtins_zfs_linux.go rename to cmd/containerd/builtins/zfs_linux.go index bde126a61..48e47a6fd 100644 --- a/cmd/containerd/builtins_zfs_linux.go +++ b/cmd/containerd/builtins/zfs_linux.go @@ -17,6 +17,6 @@ limitations under the License. */ -package main +package builtins import _ "github.com/containerd/zfs/plugin" diff --git a/cmd/containerd/builtins_cri.go b/cmd/containerd/builtins_cri.go deleted file mode 100644 index f89d4a220..000000000 --- a/cmd/containerd/builtins_cri.go +++ /dev/null @@ -1,22 +0,0 @@ -//go:build (linux && !no_cri) || (windows && !no_cri) || (darwin && !no_cri) -// +build linux,!no_cri windows,!no_cri darwin,!no_cri - -/* - Copyright The containerd Authors. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package main - -import _ "github.com/containerd/containerd/pkg/cri" diff --git a/cmd/containerd/main.go b/cmd/containerd/main.go index 10bde45bd..7eee0ddf5 100644 --- a/cmd/containerd/main.go +++ b/cmd/containerd/main.go @@ -22,6 +22,9 @@ import ( "github.com/containerd/containerd/cmd/containerd/command" "github.com/containerd/containerd/pkg/seed" + + _ "github.com/containerd/containerd/cmd/containerd/builtins" + _ "github.com/containerd/containerd/pkg/cri" ) func init() { diff --git a/contrib/fuzz/containerd_import_fuzzer.go b/contrib/fuzz/containerd_import_fuzzer.go index 6874e8c87..f471b731b 100644 --- a/contrib/fuzz/containerd_import_fuzzer.go +++ b/contrib/fuzz/containerd_import_fuzzer.go @@ -25,7 +25,7 @@ import ( fuzz "github.com/AdaLogics/go-fuzz-headers" "github.com/containerd/containerd" - _ "github.com/containerd/containerd/cmd/containerd" + _ "github.com/containerd/containerd/cmd/containerd/builtins" "github.com/containerd/containerd/cmd/containerd/command" "github.com/containerd/containerd/namespaces" ) @@ -40,6 +40,11 @@ var ( initDaemon sync.Once ) +func startDaemonForFuzzing(arguments []string) { + app := command.App() + _ = app.Run(arguments) +} + func startDaemon() { args := []string{"--log-level", "debug"} go func() { @@ -47,7 +52,7 @@ func startDaemon() { // containerd binary. // See contrib/fuzz/oss_fuzz_build.sh // for more info. - command.StartDaemonForFuzzing(args) + startDaemonForFuzzing(args) }() time.Sleep(time.Second * 4) } diff --git a/contrib/fuzz/oss_fuzz_build.sh b/contrib/fuzz/oss_fuzz_build.sh index 71e7bf1b2..63c7e49ca 100755 --- a/contrib/fuzz/oss_fuzz_build.sh +++ b/contrib/fuzz/oss_fuzz_build.sh @@ -16,14 +16,16 @@ set -o nounset set -o pipefail set -o errexit +set -x IFS=$'\n' compile_fuzzers() { local regex=$1 local compile_fuzzer=$2 + local blocklist=$3 - for line in $(git grep "$regex" | grep -v vendor) + for line in $(git grep --full-name "$regex" | grep -v -E "$blocklist") do if [[ "$line" =~ (.*)/.*:.*(Fuzz[A-Za-z0-9]+) ]]; then local pkg=${BASH_REMATCH[1]} @@ -53,41 +55,15 @@ rm /root/go/pkg/mod/github.com/cilium/ebpf@v0.7.0/internal/btf/fuzz.go cd "$(dirname "${BASH_SOURCE[0]}")" cd ../../ -# Move all fuzzers that don't have the "fuzz" package out of this dir -mv contrib/fuzz/container_fuzzer.go integration/client/ - rm -r vendor - # Change path of socket since OSS-fuzz does not grant access to /run sed -i 's/\/run\/containerd/\/tmp\/containerd/g' $SRC/containerd/defaults/defaults_unix.go -# To build FuzzContainer2 we need to prepare a few things: -# We change the name of the cmd/containerd package -# so that we can import it. -# We furthermore add an exported function that is similar -# to cmd/containerd.main and call that instead of calling -# the containerd binary. -# -# In the fuzzer we import cmd/containerd as a low-maintenance -# way of initializing all the plugins. -# Make backup of cmd/containerd: -cp -r $SRC/containerd/cmd/containerd $SRC/cmd-containerd-backup -# Rename package: -find $SRC/containerd/cmd/containerd -type f -exec sed -i 's/package main/package mainfuzz/g' {} \; -# Add an exported function -sed -i -e '$afunc StartDaemonForFuzzing(arguments []string) {\n\tapp := App()\n\t_ = app.Run(arguments)\n}' $SRC/containerd/cmd/containerd/command/main.go -# Build fuzzer: -compile_go_fuzzer github.com/containerd/containerd/contrib/fuzz FuzzContainerdImport fuzz_containerd_import -# Reinstante backup of cmd/containerd: -mv $SRC/cmd-containerd-backup $SRC/containerd/cmd/containerd - -# Compile more fuzzers -mv $SRC/containerd/filters/filter_test.go $SRC/containerd/filters/filter_test_fuzz.go go get github.com/AdamKorcz/go-118-fuzz-build/utils -compile_fuzzers '^func Fuzz.*testing\.F' compile_native_go_fuzzer -compile_fuzzers '^func Fuzz.*data' compile_go_fuzzer +compile_fuzzers '^func Fuzz.*testing\.F' compile_native_go_fuzzer vendor +compile_fuzzers '^func Fuzz.*data' compile_go_fuzzer '(vendor|Integ)' # The below fuzzers require more setup than the fuzzers above. # We need the binaries from "make". @@ -122,6 +98,5 @@ for i in $( ls *_test.go ); do mv $i ./${i%.*}_fuzz.go; done # Remove windows test to avoid double declarations: rm ./client_windows_test_fuzz.go rm ./helpers_windows_test_fuzz.go -compile_go_fuzzer github.com/containerd/containerd/integration/client FuzzCreateContainerNoTearDown fuzz_create_container_no_teardown -compile_go_fuzzer github.com/containerd/containerd/integration/client FuzzCreateContainerWithTearDown fuzz_create_container_with_teardown -compile_go_fuzzer github.com/containerd/containerd/integration/client FuzzNoTearDownWithDownload fuzz_no_teardown_with_download + +compile_fuzzers '^func FuzzInteg.*data' compile_go_fuzzer vendor diff --git a/contrib/fuzz/container_fuzzer.go b/integration/client/container_fuzzer.go similarity index 97% rename from contrib/fuzz/container_fuzzer.go rename to integration/client/container_fuzzer.go index 1738dbed8..9afdc7cf2 100644 --- a/contrib/fuzz/container_fuzzer.go +++ b/integration/client/container_fuzzer.go @@ -3,10 +3,13 @@ /* Copyright The containerd Authors. + Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 + Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -14,12 +17,6 @@ limitations under the License. */ -/* - To run this fuzzer, it must first be moved to - integration/client. OSS-fuzz does this automatically - everytime it builds the fuzzers. -*/ - package client import ( @@ -410,7 +407,7 @@ func doFuzz(data []byte, shouldTearDown bool) int { // This fuzzer is experimental for now and is being run // continuously by OSS-fuzz to collect feedback on // its sustainability. -func FuzzNoTearDownWithDownload(data []byte) int { +func FuzzIntegNoTearDownWithDownload(data []byte) int { if !haveInitialized { shouldRestart := initInSteps() if shouldRestart { @@ -426,7 +423,7 @@ func FuzzNoTearDownWithDownload(data []byte) int { // with one minor distinction: One tears down the // daemon after each iteration whereas the other doesn't. // The two fuzzers' performance will be compared over time. -func FuzzCreateContainerNoTearDown(data []byte) int { +func FuzzIntegCreateContainerNoTearDown(data []byte) int { if !haveInitialized { err := updatePathEnv() if err != nil { @@ -441,7 +438,7 @@ func FuzzCreateContainerNoTearDown(data []byte) int { // FuzzCreateContainerNoTearDown() except that // FuzzCreateContainerWithTearDown tears down the daemon // after each iteration. -func FuzzCreateContainerWithTearDown(data []byte) int { +func FuzzIntegCreateContainerWithTearDown(data []byte) int { if !haveInitialized { err := updatePathEnv() if err != nil { diff --git a/integration/client/go.mod b/integration/client/go.mod index d8b13b321..2593b1d79 100644 --- a/integration/client/go.mod +++ b/integration/client/go.mod @@ -19,8 +19,9 @@ require ( golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a ) +require github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8 + require ( - github.com/AdaLogics/go-fuzz-headers v0.0.0-20210715213245-6c3934b029d8 // indirect github.com/Microsoft/go-winio v0.5.2 // indirect github.com/blang/semver v3.5.1+incompatible // indirect github.com/cilium/ebpf v0.7.0 // indirect diff --git a/pkg/cri/server/cri_fuzzer.go b/pkg/cri/server/cri_fuzzer.go new file mode 100644 index 000000000..6fc4e216a --- /dev/null +++ b/pkg/cri/server/cri_fuzzer.go @@ -0,0 +1,578 @@ +//go:build gofuzz +// +build gofuzz + +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package server + +import ( + "context" + "fmt" + golangruntime "runtime" + "strings" + "sync" + "time" + + fuzz "github.com/AdaLogics/go-fuzz-headers" + "github.com/containerd/go-cni" + + criconfig "github.com/containerd/containerd/pkg/cri/config" + servertesting "github.com/containerd/containerd/pkg/cri/server/testing" + containerstore "github.com/containerd/containerd/pkg/cri/store/container" + imagestore "github.com/containerd/containerd/pkg/cri/store/image" + "github.com/containerd/containerd/pkg/cri/store/label" + sandboxstore "github.com/containerd/containerd/pkg/cri/store/sandbox" + snapshotstore "github.com/containerd/containerd/pkg/cri/store/snapshot" + ostesting "github.com/containerd/containerd/pkg/os/testing" + "github.com/containerd/containerd/pkg/registrar" + + "github.com/containerd/containerd" + _ "github.com/containerd/containerd/cmd/containerd/builtins" + "github.com/containerd/containerd/cmd/containerd/command" + runtime "k8s.io/cri-api/pkg/apis/runtime/v1" +) + +var ( + // The APIs the fuzzer can call: + ops = map[int]string{ + 0: "createContainer", + 1: "removeContainer", + 2: "addSandboxes", + 3: "listContainers", + 4: "startContainer", + 5: "containerStats", + 6: "listContainerStats", + 7: "containerStatus", + 8: "stopContainer", + 9: "updateContainerResources", + 10: "listImages", + 11: "removeImages", + 12: "imageStatus", + 13: "imageFsInfo", + 14: "listPodSandbox", + 15: "portForward", + 16: "removePodSandbox", + 17: "runPodSandbox", + 18: "podSandboxStatus", + 19: "stopPodSandbox", + 20: "status", + 21: "updateRuntimeConfig", + } +) + +const ( + defaultRoot = "/var/lib/containerd" + defaultState = "/tmp/containerd" + defaultAddress = "/tmp/containerd/containerd.sock" +) + +var ( + initDaemon sync.Once + + executionOrder []string +) + +func startDaemonForFuzzing(arguments []string) { + app := command.App() + _ = app.Run(arguments) +} + +func startDaemon() { + args := []string{"--log-level", "debug"} + go func() { + // This is similar to invoking the + // containerd binary. + // See contrib/fuzz/oss_fuzz_build.sh + // for more info. + startDaemonForFuzzing(args) + }() + time.Sleep(time.Second * 4) +} + +func printExecutions() { + if r := recover(); r != nil { + var err string + switch r.(type) { + case string: + err = r.(string) + case golangruntime.Error: + err = r.(golangruntime.Error).Error() + case error: + err = r.(error).Error() + default: + err = "uknown error type" + } + fmt.Println("Executions:") + for _, eo := range executionOrder { + fmt.Println(eo) + } + panic(err) + } +} + +// FuzzCRI implements a fuzzer that tests CRI APIs. +func FuzzCRI(data []byte) int { + initDaemon.Do(startDaemon) + + executionOrder = make([]string, 0) + + f := fuzz.NewConsumer(data) + + client, err := containerd.New(defaultAddress) + if err != nil { + return 0 + } + defer client.Close() + + c, err := NewCRIService(criconfig.Config{}, client) + if err != nil { + panic(err) + } + + calls, err := f.GetInt() + if err != nil { + return 0 + } + + defer printExecutions() + for i := 0; i < calls%40; i++ { + op, err := f.GetInt() + if err != nil { + return 0 + } + opType := op % len(ops) + + switch ops[opType] { + case "createContainer": + createContainerFuzz(c.(*criService), f) + case "removeContainer": + removeContainerFuzz(c.(*criService), f) + case "addSandboxes": + addSandboxesFuzz(c.(*criService), f) + case "listContainers": + listContainersFuzz(c.(*criService), f) + case "startContainer": + startContainerFuzz(c.(*criService), f) + case "containerStats": + containerStatsFuzz(c.(*criService), f) + case "listContainerStats": + listContainerStatsFuzz(c.(*criService), f) + case "containerStatus": + containerStatusFuzz(c.(*criService), f) + case "stopContainer": + stopContainerFuzz(c.(*criService), f) + case "updateContainerResources": + updateContainerResourcesFuzz(c.(*criService), f) + case "listImages": + listImagesFuzz(c.(*criService), f) + case "removeImages": + removeImagesFuzz(c.(*criService), f) + case "imageStatus": + imageStatusFuzz(c.(*criService), f) + case "imageFsInfo": + imageFsInfoFuzz(c.(*criService), f) + case "listPodSandbox": + listPodSandboxFuzz(c.(*criService), f) + case "portForward": + portForwardFuzz(c.(*criService), f) + case "removePodSandbox": + removePodSandboxFuzz(c.(*criService), f) + case "runPodSandbox": + runPodSandboxFuzz(c.(*criService), f) + case "podSandboxStatus": + podSandboxStatusFuzz(c.(*criService), f) + case "stopPodSandbox": + stopPodSandboxFuzz(c.(*criService), f) + case "status": + statusFuzz(c.(*criService), f) + case "updateRuntimeConfig": + updateRuntimeConfigFuzz(c.(*criService), f) + } + } + return 1 +} + +func logExecution(apiName, request string) { + var logString strings.Builder + logString.WriteString(fmt.Sprintf("Calling %s with \n %s \n\n", apiName, request)) + executionOrder = append(executionOrder, logString.String()) +} + +// createContainerFuzz creates a CreateContainerRequest and passes +// it to c.CreateContainer +func createContainerFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.CreateContainerRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.CreateContainer(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.CreateContainer", reqString) + return nil +} + +// removeContainerFuzz creates a RemoveContainerRequest and passes +// it to c.RemoveContainer +func removeContainerFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.RemoveContainerRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.RemoveContainer(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.RemoveContainer", reqString) + return nil +} + +// addSandboxesFuzz creates a sandbox and adds it to the sandboxstore +func addSandboxesFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + quantity, err := f.GetInt() + if err != nil { + return err + } + for i := 0; i < quantity%20; i++ { + newSandbox, err := getSandboxFuzz(f) + if err != nil { + return err + } + err = c.sandboxStore.Add(newSandbox) + if err != nil { + return err + } + } + return nil +} + +// getSandboxFuzz creates a sandbox +func getSandboxFuzz(f *fuzz.ConsumeFuzzer) (sandboxstore.Sandbox, error) { + metadata := sandboxstore.Metadata{} + status := sandboxstore.Status{} + err := f.GenerateStruct(&metadata) + if err != nil { + return sandboxstore.Sandbox{}, err + } + err = f.GenerateStruct(&status) + if err != nil { + return sandboxstore.Sandbox{}, err + } + + reqString := fmt.Sprintf("metadata: %+v\nstatus: %+v\n", metadata, status) + logExecution("sandboxstore.NewSandbox", reqString) + + return sandboxstore.NewSandbox(metadata, status), nil +} + +// listContainersFuzz creates a ListContainersRequest and passes +// it to c.ListContainers +func listContainersFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.ListContainersRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.ListContainers(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.ListContainers", reqString) + return nil +} + +// startContainerFuzz creates a StartContainerRequest and passes +// it to c.StartContainer +func startContainerFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.StartContainerRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.StartContainer(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.StartContainer", reqString) + return nil +} + +// containerStatsFuzz creates a ContainerStatsRequest and passes +// it to c.ContainerStats +func containerStatsFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.ContainerStatsRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.ContainerStats(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.ContainerStats", reqString) + return nil +} + +// listContainerStatsFuzz creates a ListContainerStatsRequest and +// passes it to c.ListContainerStats +func listContainerStatsFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.ListContainerStatsRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.ListContainerStats(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.ListContainerStats", reqString) + return nil +} + +// containerStatusFuzz creates a ContainerStatusRequest and passes +// it to c.ContainerStatus +func containerStatusFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.ContainerStatusRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.ContainerStatus(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.ContainerStatus", reqString) + return nil +} + +// stopContainerFuzz creates a StopContainerRequest and passes +// it to c.StopContainer +func stopContainerFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.StopContainerRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.StopContainer(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.StopContainer", reqString) + return nil +} + +// updateContainerResourcesFuzz creates a UpdateContainerResourcesRequest +// and passes it to c.UpdateContainerResources +func updateContainerResourcesFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.UpdateContainerResourcesRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.UpdateContainerResources(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.UpdateContainerResources", reqString) + return nil +} + +// listImagesFuzz creates a ListImagesRequest and passes it to +// c.ListImages +func listImagesFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.ListImagesRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.ListImages(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.ListImages", reqString) + return nil +} + +// removeImagesFuzz creates a RemoveImageRequest and passes it to +// c.RemoveImage +func removeImagesFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.RemoveImageRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.RemoveImage(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.RemoveImage", reqString) + return nil +} + +// imageStatusFuzz creates an ImageStatusRequest and passes it to +// c.ImageStatus +func imageStatusFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.ImageStatusRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.ImageStatus(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.ImageStatus", reqString) + return nil +} + +// imageFsInfoFuzz creates an ImageFsInfoRequest and passes it to +// c.ImageFsInfo +func imageFsInfoFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.ImageFsInfoRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.ImageFsInfo(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.ImageFsInfo", reqString) + return nil +} + +// listPodSandboxFuzz creates a ListPodSandboxRequest and passes +// it to c.ListPodSandbox +func listPodSandboxFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.ListPodSandboxRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.ListPodSandbox(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.ListPodSandbox", reqString) + return nil +} + +// portForwardFuzz creates a PortForwardRequest and passes it to +// c.PortForward +func portForwardFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.PortForwardRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.PortForward(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.PortForward", reqString) + return nil +} + +// removePodSandboxFuzz creates a RemovePodSandboxRequest and +// passes it to c.RemovePodSandbox +func removePodSandboxFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.RemovePodSandboxRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.RemovePodSandbox(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.RemovePodSandbox", reqString) + return nil +} + +// runPodSandboxFuzz creates a RunPodSandboxRequest and passes +// it to c.RunPodSandbox +func runPodSandboxFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.RunPodSandboxRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.RunPodSandbox(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.RunPodSandbox", reqString) + return nil +} + +// podSandboxStatusFuzz creates a PodSandboxStatusRequest and +// passes it to +func podSandboxStatusFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.PodSandboxStatusRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.PodSandboxStatus(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.PodSandboxStatus", reqString) + return nil +} + +// stopPodSandboxFuzz creates a StopPodSandboxRequest and passes +// it to c.StopPodSandbox +func stopPodSandboxFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.StopPodSandboxRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.StopPodSandbox(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.StopPodSandbox", reqString) + return nil +} + +// statusFuzz creates a StatusRequest and passes it to c.Status +func statusFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.StatusRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.Status(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.Status", reqString) + return nil +} + +func updateRuntimeConfigFuzz(c *criService, f *fuzz.ConsumeFuzzer) error { + r := &runtime.UpdateRuntimeConfigRequest{} + err := f.GenerateStruct(r) + if err != nil { + return err + } + _, _ = c.UpdateRuntimeConfig(context.Background(), r) + reqString := fmt.Sprintf("%+v", r) + logExecution("c.UpdateRuntimeConfig", reqString) + return nil +} + +// This creates a container directly in the store. +func getContainer(f *fuzz.ConsumeFuzzer) (containerstore.Container, error) { + metadata := containerstore.Metadata{} + status := containerstore.Status{} + + err := f.GenerateStruct(&metadata) + if err != nil { + return containerstore.Container{}, err + } + err = f.GenerateStruct(&status) + if err != nil { + return containerstore.Container{}, err + } + container, err := containerstore.NewContainer(metadata, containerstore.WithFakeStatus(status)) + return container, err +} + +func newTestCRIServiceForFuzzing(f *fuzz.ConsumeFuzzer) *criService { + labels := label.NewStore() + + return &criService{ + config: testConfig, + imageFSPath: testImageFSPath, + os: ostesting.NewFakeOS(), + sandboxStore: sandboxstore.NewStore(labels), + imageStore: imagestore.NewStore(nil), + snapshotStore: snapshotstore.NewStore(), + sandboxNameIndex: registrar.NewRegistrar(), + containerStore: containerstore.NewStore(labels), + containerNameIndex: registrar.NewRegistrar(), + netPlugin: map[string]cni.CNI{ + defaultNetworkPlugin: servertesting.NewFakeCNIPlugin(), + }, + } +} diff --git a/pkg/cri/server/service_test.go b/pkg/cri/server/service_test.go index ad329d6d2..3143cedf6 100644 --- a/pkg/cri/server/service_test.go +++ b/pkg/cri/server/service_test.go @@ -37,28 +37,11 @@ import ( "github.com/containerd/containerd/pkg/registrar" ) -const ( - testRootDir = "/test/root" - testStateDir = "/test/state" - // Use an image id as test sandbox image to avoid image name resolve. - // TODO(random-liu): Change this to image name after we have complete image - // management unit test framework. - testSandboxImage = "sha256:c75bebcdd211f41b3a460c7bf82970ed6c75acaab9cd4c9a4e125b03ca113798" - testImageFSPath = "/test/image/fs/path" -) - // newTestCRIService creates a fake criService for test. func newTestCRIService() *criService { labels := label.NewStore() return &criService{ - config: criconfig.Config{ - RootDir: testRootDir, - StateDir: testStateDir, - PluginConfig: criconfig.PluginConfig{ - SandboxImage: testSandboxImage, - TolerateMissingHugetlbController: true, - }, - }, + config: testConfig, imageFSPath: testImageFSPath, os: ostesting.NewFakeOS(), sandboxStore: sandboxstore.NewStore(labels), diff --git a/pkg/cri/server/test_config.go b/pkg/cri/server/test_config.go new file mode 100644 index 000000000..c129e38fc --- /dev/null +++ b/pkg/cri/server/test_config.go @@ -0,0 +1,38 @@ +/* + Copyright The containerd Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package server + +import criconfig "github.com/containerd/containerd/pkg/cri/config" + +const ( + testRootDir = "/test/root" + testStateDir = "/test/state" + // Use an image id as test sandbox image to avoid image name resolve. + // TODO(random-liu): Change this to image name after we have complete image + // management unit test framework. + testSandboxImage = "sha256:c75bebcdd211f41b3a460c7bf82970ed6c75acaab9cd4c9a4e125b03ca113798" + testImageFSPath = "/test/image/fs/path" +) + +var testConfig = criconfig.Config{ + RootDir: testRootDir, + StateDir: testStateDir, + PluginConfig: criconfig.PluginConfig{ + SandboxImage: testSandboxImage, + TolerateMissingHugetlbController: true, + }, +}