diff --git a/containerd.spec b/containerd.spec index c09634ef30fcaaab30216031cc9fd5e881524806..540b02ccfb013d0cbd3cc344405a738a6efe46de 100644 --- a/containerd.spec +++ b/containerd.spec @@ -2,7 +2,7 @@ %global debug_package %{nil} Version: 1.6.22 Name: containerd -Release: 2 +Release: 3 Summary: An industry-standard container runtime License: ASL 2.0 URL: https://containerd.io @@ -67,6 +67,12 @@ install -D -p -m 0644 %{S:7} %{buildroot}%{_sysconfdir}/containerd/config.toml %exclude %{_bindir}/containerd-stress %changelog +* Tue Sep 19 2023 zhongjiawei - 1.6.22-3 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC:sync some patches + * Fri Sep 8 2023 zhongjiawei - 1.6.22-2 - Type:bugfix - ID:NA diff --git a/git-commit b/git-commit index abe4d7458308f681a4a28a9b2f2101943f36fa25..86c295dedfb0ab97c143ebc991be2ce75ade5f63 100644 --- a/git-commit +++ b/git-commit @@ -1 +1 @@ -ecdc685acc9021b4af0f0996eccea19f8dc500fe +495056854f1bd0e7e88da11867a70629276604b6 diff --git a/patch/0027-containerd-fix-allow-attaching-to-any-combination-of-stdin-stdo.patch b/patch/0027-containerd-fix-allow-attaching-to-any-combination-of-stdin-stdo.patch new file mode 100644 index 0000000000000000000000000000000000000000..87d6799a0c6343c94379ad1499bfdab40ee927ae --- /dev/null +++ b/patch/0027-containerd-fix-allow-attaching-to-any-combination-of-stdin-stdo.patch @@ -0,0 +1,250 @@ +From fe6bf665fd2c990a4c9db8323ee7e1a43eda7b4b Mon Sep 17 00:00:00 2001 +From: "Hsing-Yu (David) Chen" +Date: Tue, 28 Mar 2023 17:13:28 -0700 +Subject: [PATCH] fix: allow attaching to any combination of + stdin/stdout/stderr + +Before this PR, if a stdin/stdout/stderr stream is nil, +and the corresponding FIFO is not an empty string, +a panic will occur when Read/Write of the nil stream is invoked in io.CopyBuffer. + +Signed-off-by: Hsing-Yu (David) Chen +--- + cio/io.go | 9 ++ + cio/io_unix_test.go | 203 ++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 212 insertions(+) + +diff --git a/cio/io.go b/cio/io.go +index 8ee13edda..917684189 100644 +--- a/cio/io.go ++++ b/cio/io.go +@@ -167,6 +167,15 @@ func NewAttach(opts ...Opt) Attach { + if fifos == nil { + return nil, fmt.Errorf("cannot attach, missing fifos") + } ++ if streams.Stdin == nil { ++ fifos.Stdin = "" ++ } ++ if streams.Stdout == nil { ++ fifos.Stdout = "" ++ } ++ if streams.Stderr == nil { ++ fifos.Stderr = "" ++ } + return copyIO(fifos, streams) + } + } +diff --git a/cio/io_unix_test.go b/cio/io_unix_test.go +index d4e0a70bf..cdaeb7738 100644 +--- a/cio/io_unix_test.go ++++ b/cio/io_unix_test.go +@@ -95,3 +95,206 @@ func TestOpenFifosWithTerminal(t *testing.T) { + } + } + } ++ ++func assertHasPrefix(t *testing.T, s, prefix string) { ++ t.Helper() ++ if !strings.HasPrefix(s, prefix) { ++ t.Fatalf("expected %s to start with %s", s, prefix) ++ } ++} ++ ++func TestNewFIFOSetInDir(t *testing.T) { ++ root := t.TempDir() ++ ++ fifos, err := NewFIFOSetInDir(root, "theid", true) ++ assert.NoError(t, err) ++ ++ dir := filepath.Dir(fifos.Stdin) ++ assertHasPrefix(t, dir, root) ++ expected := &FIFOSet{ ++ Config: Config{ ++ Stdin: filepath.Join(dir, "theid-stdin"), ++ Stdout: filepath.Join(dir, "theid-stdout"), ++ Stderr: filepath.Join(dir, "theid-stderr"), ++ Terminal: true, ++ }, ++ } ++ ++ assert.Equal(t, fifos.Config, expected.Config) ++ ++ files, err := os.ReadDir(root) ++ assert.NoError(t, err) ++ assert.Len(t, files, 1) ++ ++ assert.Nil(t, fifos.Close()) ++ files, err = os.ReadDir(root) ++ assert.NoError(t, err) ++ assert.Len(t, files, 0) ++} ++ ++func TestNewAttach(t *testing.T) { ++ testCases := []struct { ++ name string ++ expectedStdin, expectedStdout, expectedStderr string ++ }{ ++ { ++ name: "attach to all streams (stdin, stdout, and stderr)", ++ expectedStdin: "this is the stdin", ++ expectedStdout: "this is the stdout", ++ expectedStderr: "this is the stderr", ++ }, ++ { ++ name: "don't attach to stdin", ++ expectedStdout: "this is the stdout", ++ expectedStderr: "this is the stderr", ++ }, ++ { ++ name: "don't attach to stdout", ++ expectedStdin: "this is the stdin", ++ expectedStderr: "this is the stderr", ++ }, ++ { ++ name: "don't attach to stderr", ++ expectedStdin: "this is the stdin", ++ expectedStdout: "this is the stdout", ++ }, ++ } ++ ++ for _, tc := range testCases { ++ t.Run(tc.name, func(t *testing.T) { ++ var ( ++ stdin = bytes.NewBufferString(tc.expectedStdin) ++ stdout = new(bytes.Buffer) ++ stderr = new(bytes.Buffer) ++ ++ // The variables below have to be of the interface type (i.e., io.Reader/io.Writer) ++ // instead of the concrete type (i.e., *bytes.Buffer) *before* being passed to NewAttach. ++ // Otherwise, in NewAttach, the interface value won't be nil ++ // (it's just that the concrete value inside the interface itself is nil. [1]), ++ // which means that the corresponding FIFO path won't be set to be an empty string, ++ // and that's not what we want. ++ // ++ // [1] https://go.dev/tour/methods/12 ++ stdinArg io.Reader ++ stdoutArg, stderrArg io.Writer ++ ) ++ if tc.expectedStdin != "" { ++ stdinArg = stdin ++ } ++ if tc.expectedStdout != "" { ++ stdoutArg = stdout ++ } ++ if tc.expectedStderr != "" { ++ stderrArg = stderr ++ } ++ ++ attacher := NewAttach(WithStreams(stdinArg, stdoutArg, stderrArg)) ++ ++ fifos, err := NewFIFOSetInDir("", "theid", false) ++ assert.NoError(t, err) ++ ++ attachedFifos, err := attacher(fifos) ++ assert.NoError(t, err) ++ defer attachedFifos.Close() ++ ++ producers := setupFIFOProducers(t, attachedFifos.Config()) ++ initProducers(t, producers, tc.expectedStdout, tc.expectedStderr) ++ ++ var actualStdin []byte ++ if producers.Stdin != nil { ++ actualStdin, err = io.ReadAll(producers.Stdin) ++ assert.NoError(t, err) ++ } ++ ++ attachedFifos.Wait() ++ attachedFifos.Cancel() ++ assert.Nil(t, attachedFifos.Close()) ++ ++ assert.Equal(t, tc.expectedStdout, stdout.String()) ++ assert.Equal(t, tc.expectedStderr, stderr.String()) ++ assert.Equal(t, tc.expectedStdin, string(actualStdin)) ++ }) ++ } ++} ++ ++type producers struct { ++ Stdin io.ReadCloser ++ Stdout io.WriteCloser ++ Stderr io.WriteCloser ++} ++ ++func setupFIFOProducers(t *testing.T, fifos Config) producers { ++ var ( ++ err error ++ pipes producers ++ ctx = context.Background() ++ ) ++ ++ if fifos.Stdin != "" { ++ pipes.Stdin, err = fifo.OpenFifo(ctx, fifos.Stdin, syscall.O_RDONLY, 0) ++ assert.NoError(t, err) ++ } ++ ++ if fifos.Stdout != "" { ++ pipes.Stdout, err = fifo.OpenFifo(ctx, fifos.Stdout, syscall.O_WRONLY, 0) ++ assert.NoError(t, err) ++ } ++ ++ if fifos.Stderr != "" { ++ pipes.Stderr, err = fifo.OpenFifo(ctx, fifos.Stderr, syscall.O_WRONLY, 0) ++ assert.NoError(t, err) ++ } ++ ++ return pipes ++} ++ ++func initProducers(t *testing.T, producers producers, stdout, stderr string) { ++ if producers.Stdout != nil { ++ _, err := producers.Stdout.Write([]byte(stdout)) ++ assert.NoError(t, err) ++ assert.Nil(t, producers.Stdout.Close()) ++ } ++ ++ if producers.Stderr != nil { ++ _, err := producers.Stderr.Write([]byte(stderr)) ++ assert.NoError(t, err) ++ assert.Nil(t, producers.Stderr.Close()) ++ } ++} ++ ++func TestLogURIGenerator(t *testing.T) { ++ baseTestLogURIGenerator(t, []LogURIGeneratorTestCase{ ++ { ++ scheme: "fifo", ++ path: "/full/path/pipe.fifo", ++ expected: "fifo:///full/path/pipe.fifo", ++ }, ++ { ++ scheme: "file", ++ path: "/full/path/file.txt", ++ args: map[string]string{ ++ "maxSize": "100MB", ++ }, ++ expected: "file:///full/path/file.txt?maxSize=100MB", ++ }, ++ { ++ scheme: "binary", ++ path: "/full/path/bin", ++ args: map[string]string{ ++ "id": "testing", ++ }, ++ expected: "binary:///full/path/bin?id=testing", ++ }, ++ { ++ scheme: "unknown", ++ path: "nowhere", ++ err: "must be absolute", ++ }, ++ { ++ scheme: "binary", ++ path: "C:\\path\\to\\binary", ++ // NOTE: Windows paths should not be parse-able outside of Windows: ++ err: "must be absolute", ++ }, ++ }) ++} +-- +2.33.0 + diff --git a/patch/0028-containerd-bugfix-add-nil-pointer-check-for-cgroup-v1-mem-usage.patch b/patch/0028-containerd-bugfix-add-nil-pointer-check-for-cgroup-v1-mem-usage.patch new file mode 100644 index 0000000000000000000000000000000000000000..cc6b10f585bcdb1a75b60cb8a4723dfc21169771 --- /dev/null +++ b/patch/0028-containerd-bugfix-add-nil-pointer-check-for-cgroup-v1-mem-usage.patch @@ -0,0 +1,161 @@ +From 2cf8b902f59636b35f187165637d2660d905ce54 Mon Sep 17 00:00:00 2001 +From: "Cardy.Tang" +Date: Fri, 19 May 2023 09:49:58 +0800 +Subject: [PATCH] bugfix: add nil pointer check for cgroup v1 mem usage + +Signed-off-by: Cardy.Tang +--- + metrics/cgroups/v1/memory.go | 32 ++++++++++++++++---------------- + 1 file changed, 16 insertions(+), 16 deletions(-) + +diff --git a/metrics/cgroups/v1/memory.go b/metrics/cgroups/v1/memory.go +index 86f6196ce..90ccc16ea 100644 +--- a/metrics/cgroups/v1/memory.go ++++ b/metrics/cgroups/v1/memory.go +@@ -544,7 +544,7 @@ var memoryMetrics = []*metric{ + unit: metrics.Total, + vt: prometheus.GaugeValue, + getValues: func(stats *v1.Metrics) []value { +- if stats.Memory == nil { ++ if stats.Memory == nil || stats.Memory.Usage == nil { + return nil + } + return []value{ +@@ -560,7 +560,7 @@ var memoryMetrics = []*metric{ + unit: metrics.Bytes, + vt: prometheus.GaugeValue, + getValues: func(stats *v1.Metrics) []value { +- if stats.Memory == nil { ++ if stats.Memory == nil || stats.Memory.Usage == nil { + return nil + } + return []value{ +@@ -576,7 +576,7 @@ var memoryMetrics = []*metric{ + unit: metrics.Bytes, + vt: prometheus.GaugeValue, + getValues: func(stats *v1.Metrics) []value { +- if stats.Memory == nil { ++ if stats.Memory == nil || stats.Memory.Usage == nil { + return nil + } + return []value{ +@@ -592,7 +592,7 @@ var memoryMetrics = []*metric{ + unit: metrics.Bytes, + vt: prometheus.GaugeValue, + getValues: func(stats *v1.Metrics) []value { +- if stats.Memory == nil { ++ if stats.Memory == nil || stats.Memory.Usage == nil { + return nil + } + return []value{ +@@ -608,7 +608,7 @@ var memoryMetrics = []*metric{ + unit: metrics.Total, + vt: prometheus.GaugeValue, + getValues: func(stats *v1.Metrics) []value { +- if stats.Memory == nil { ++ if stats.Memory == nil || stats.Memory.Swap == nil { + return nil + } + return []value{ +@@ -624,7 +624,7 @@ var memoryMetrics = []*metric{ + unit: metrics.Bytes, + vt: prometheus.GaugeValue, + getValues: func(stats *v1.Metrics) []value { +- if stats.Memory == nil { ++ if stats.Memory == nil || stats.Memory.Swap == nil { + return nil + } + return []value{ +@@ -640,7 +640,7 @@ var memoryMetrics = []*metric{ + unit: metrics.Bytes, + vt: prometheus.GaugeValue, + getValues: func(stats *v1.Metrics) []value { +- if stats.Memory == nil { ++ if stats.Memory == nil || stats.Memory.Swap == nil { + return nil + } + return []value{ +@@ -656,7 +656,7 @@ var memoryMetrics = []*metric{ + unit: metrics.Bytes, + vt: prometheus.GaugeValue, + getValues: func(stats *v1.Metrics) []value { +- if stats.Memory == nil { ++ if stats.Memory == nil || stats.Memory.Swap == nil { + return nil + } + return []value{ +@@ -672,7 +672,7 @@ var memoryMetrics = []*metric{ + unit: metrics.Total, + vt: prometheus.GaugeValue, + getValues: func(stats *v1.Metrics) []value { +- if stats.Memory == nil { ++ if stats.Memory == nil || stats.Memory.Kernel == nil { + return nil + } + return []value{ +@@ -688,7 +688,7 @@ var memoryMetrics = []*metric{ + unit: metrics.Bytes, + vt: prometheus.GaugeValue, + getValues: func(stats *v1.Metrics) []value { +- if stats.Memory == nil { ++ if stats.Memory == nil || stats.Memory.Kernel == nil { + return nil + } + return []value{ +@@ -704,7 +704,7 @@ var memoryMetrics = []*metric{ + unit: metrics.Bytes, + vt: prometheus.GaugeValue, + getValues: func(stats *v1.Metrics) []value { +- if stats.Memory == nil { ++ if stats.Memory == nil || stats.Memory.Kernel == nil { + return nil + } + return []value{ +@@ -720,7 +720,7 @@ var memoryMetrics = []*metric{ + unit: metrics.Bytes, + vt: prometheus.GaugeValue, + getValues: func(stats *v1.Metrics) []value { +- if stats.Memory == nil { ++ if stats.Memory == nil || stats.Memory.Kernel == nil { + return nil + } + return []value{ +@@ -736,7 +736,7 @@ var memoryMetrics = []*metric{ + unit: metrics.Total, + vt: prometheus.GaugeValue, + getValues: func(stats *v1.Metrics) []value { +- if stats.Memory == nil { ++ if stats.Memory == nil || stats.Memory.KernelTCP == nil { + return nil + } + return []value{ +@@ -752,7 +752,7 @@ var memoryMetrics = []*metric{ + unit: metrics.Bytes, + vt: prometheus.GaugeValue, + getValues: func(stats *v1.Metrics) []value { +- if stats.Memory == nil { ++ if stats.Memory == nil || stats.Memory.KernelTCP == nil { + return nil + } + return []value{ +@@ -768,7 +768,7 @@ var memoryMetrics = []*metric{ + unit: metrics.Bytes, + vt: prometheus.GaugeValue, + getValues: func(stats *v1.Metrics) []value { +- if stats.Memory == nil { ++ if stats.Memory == nil || stats.Memory.KernelTCP == nil { + return nil + } + return []value{ +@@ -784,7 +784,7 @@ var memoryMetrics = []*metric{ + unit: metrics.Bytes, + vt: prometheus.GaugeValue, + getValues: func(stats *v1.Metrics) []value { +- if stats.Memory == nil { ++ if stats.Memory == nil || stats.Memory.KernelTCP == nil { + return nil + } + return []value{ +-- +2.33.0 + diff --git a/patch/0029-containerd-fix-unable-to-checkpoint-the-container-more-than-onc.patch b/patch/0029-containerd-fix-unable-to-checkpoint-the-container-more-than-onc.patch new file mode 100644 index 0000000000000000000000000000000000000000..c3fabc79dbcb6758d9a5cefccbfcde8b43765dc1 --- /dev/null +++ b/patch/0029-containerd-fix-unable-to-checkpoint-the-container-more-than-onc.patch @@ -0,0 +1,26 @@ +From 26c96255462ea2abc3ec702b8303225c5a71a4a3 Mon Sep 17 00:00:00 2001 +From: Iceber Gu +Date: Mon, 17 Apr 2023 14:02:18 +0800 +Subject: [PATCH] fix unable to checkpoint the container more than once + +Signed-off-by: Iceber Gu +--- + services/tasks/local.go | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/services/tasks/local.go b/services/tasks/local.go +index 7f60d253a..d09fca200 100644 +--- a/services/tasks/local.go ++++ b/services/tasks/local.go +@@ -707,7 +707,7 @@ func (l *local) writeContent(ctx context.Context, mediaType, ref string, r io.Re + if err != nil { + return nil, err + } +- if err := writer.Commit(ctx, 0, ""); err != nil { ++ if err := writer.Commit(ctx, 0, ""); err != nil && !errdefs.IsAlreadyExists(err) { + return nil, err + } + return &types.Descriptor{ +-- +2.33.0 + diff --git a/patch/0030-containerd-fix-cio.Cancel-should-close-the-pipes.patch b/patch/0030-containerd-fix-cio.Cancel-should-close-the-pipes.patch new file mode 100644 index 0000000000000000000000000000000000000000..9fe5d0f4dcdaa618f27b8fb6d142e7bddf0b1e22 --- /dev/null +++ b/patch/0030-containerd-fix-cio.Cancel-should-close-the-pipes.patch @@ -0,0 +1,35 @@ +From 4789ed1a8f4e846400be9a0d5cd28643b1b9b6e4 Mon Sep 17 00:00:00 2001 +From: "Hsing-Yu (David) Chen" +Date: Thu, 30 Mar 2023 18:38:54 -0700 +Subject: [PATCH] fix: cio.Cancel() should close the pipes + +PR fixes #8326. + +Signed-off-by: Hsing-Yu (David) Chen +--- + cio/io_unix.go | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/cio/io_unix.go b/cio/io_unix.go +index 5606cc88a..f7a12cf8d 100644 +--- a/cio/io_unix.go ++++ b/cio/io_unix.go +@@ -99,7 +99,14 @@ func copyIO(fifos *FIFOSet, ioset *Streams) (*cio, error) { + config: fifos.Config, + wg: wg, + closers: append(pipes.closers(), fifos), +- cancel: cancel, ++ cancel: func() { ++ cancel() ++ for _, c := range pipes.closers() { ++ if c != nil { ++ c.Close() ++ } ++ } ++ }, + }, nil + } + +-- +2.33.0 + diff --git a/series.conf b/series.conf index f09db8df053e17622ac88fc821ca131d8e1af105..1c2a92fd521bb9b185bb4b8c1d63a0d7ee74068a 100644 --- a/series.conf +++ b/series.conf @@ -24,3 +24,7 @@ patch/0023-containerd-fix-exec-event-missing-due-to-pid-reuse.patch patch/0024-containerd-fix-dm-left-when-pause-contaienr-and-kill.patch patch/0025-containerd-drop-opt-package.patch patch/0026-containerd-fix-race-access-for-mobySubcribed.patch +patch/0027-containerd-fix-allow-attaching-to-any-combination-of-stdin-stdo.patch +patch/0028-containerd-bugfix-add-nil-pointer-check-for-cgroup-v1-mem-usage.patch +patch/0029-containerd-fix-unable-to-checkpoint-the-container-more-than-onc.patch +patch/0030-containerd-fix-cio.Cancel-should-close-the-pipes.patch