diff --git a/pkg/logging/log_viewer.go b/pkg/logging/log_viewer.go index b2741273450..7cbc0292edf 100644 --- a/pkg/logging/log_viewer.go +++ b/pkg/logging/log_viewer.go @@ -135,6 +135,10 @@ func InitContainerLogViewer(containerLabels map[string]string, lvopts LogViewOpt return nil, fmt.Errorf("the `cri` log viewer requires nerdctl to be running in experimental mode") } + if lcfg.Driver == "none" { + return nil, fmt.Errorf("log type `none` was selected, nothing to log") + } + lv := &ContainerLogViewer{ loggingConfig: lcfg, logViewingOptions: lvopts, diff --git a/pkg/logging/logging.go b/pkg/logging/logging.go index 0a42cbb21be..318e3496e6b 100644 --- a/pkg/logging/logging.go +++ b/pkg/logging/logging.go @@ -90,6 +90,9 @@ func GetDriver(name string, opts map[string]string) (Driver, error) { } func init() { + RegisterDriver("none", func(opts map[string]string) (Driver, error) { + return &NoneLogger{}, nil + }, NoneLogOptsValidate) RegisterDriver("json-file", func(opts map[string]string) (Driver, error) { return &JSONLogger{Opts: opts}, nil }, JSONFileLogOptsValidate) diff --git a/pkg/logging/none_logger.go b/pkg/logging/none_logger.go new file mode 100644 index 00000000000..57d7e1c1b34 --- /dev/null +++ b/pkg/logging/none_logger.go @@ -0,0 +1,45 @@ +/* + 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 logging + +import ( + "github.com/containerd/containerd/v2/core/runtime/v2/logging" +) + +type NoneLogger struct { + Opts map[string]string +} + +func (n *NoneLogger) Init(dataStore, ns, id string) error { + return nil +} + +func (n *NoneLogger) PreProcess(dataStore string, config *logging.Config) error { + return nil +} + +func (n *NoneLogger) Process(stdout <-chan string, stderr <-chan string) error { + return nil +} + +func (n *NoneLogger) PostProcess() error { + return nil +} + +func NoneLogOptsValidate(_ map[string]string) error { + return nil +} diff --git a/pkg/logging/none_logger_test.go b/pkg/logging/none_logger_test.go new file mode 100644 index 00000000000..88e35b72d3c --- /dev/null +++ b/pkg/logging/none_logger_test.go @@ -0,0 +1,72 @@ +/* + 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 logging + +import ( + "os" + "testing" + "time" + + "gotest.tools/v3/assert" + + "github.com/containerd/containerd/v2/core/runtime/v2/logging" +) + +func TestNoneLogger(t *testing.T) { + // Create a temporary directory for potential log files + tmpDir := t.TempDir() + + logger := &NoneLogger{ + Opts: map[string]string{}, + } + + t.Run("NoLoggingOccurs", func(t *testing.T) { + initialFiles, err := os.ReadDir(tmpDir) + assert.NilError(t, err, "Failed to read temp dir") + + // Run all logger methods + logger.Init(tmpDir, "namespace", "id") + logger.PreProcess(tmpDir, &logging.Config{}) + + stdout := make(chan string) + stderr := make(chan string) + + go func() { + for i := 0; i < 10; i++ { + stdout <- "test stdout" + stderr <- "test stderr" + } + close(stdout) + close(stderr) + }() + + err = logger.Process(stdout, stderr) + assert.NilError(t, err, "Process() returned unexpected error") + + logger.PostProcess() + + // Wait a bit to ensure any potential writes would have occurred + time.Sleep(100 * time.Millisecond) + + // Check if any new files were created + afterFiles, err := os.ReadDir(tmpDir) + assert.NilError(t, err, "Failed to read temp dir after operations") + + assert.Equal(t, len(afterFiles), len(initialFiles), "Expected no new files, but directory content changed") + + }) +}