Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package cadvisor for openSUSE:Factory 
checked in at 2026-10-02 23:09:09
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/cadvisor (Old)
 and      /work/SRC/openSUSE:Factory/.cadvisor.new.1631729 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "cadvisor"

Fri Oct  2 23:09:09 2026 rev:9 rq:1382134 version:0.60.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/cadvisor/cadvisor.changes        2026-09-07 
15:49:56.968346629 +0200
+++ /work/SRC/openSUSE:Factory/.cadvisor.new.1631729/cadvisor.changes   
2026-10-02 23:09:11.549999343 +0200
@@ -1,0 +2,13 @@
+Fri Oct  2 14:23:56 UTC 2026 - Dirk Müller <[email protected]>
+
+- update to 0.60.6:
+  * workflows: mirror release tags to lib/ module tags
+  * fs/zfs: fall back to VFS when zfs stats are unavailable
+  * storage/stdout: nil-check Cpu, Network, and Memory stats
+  * Treat memory-only NUMA nodes as valid topology
+- update vendor.tar to fix
+  * bsc#1283657, CVE-2026-63209: cadvisor:
+    github.com/klauspost/compress: signed integer overflow in
+    s2.NewDict()
+
+-------------------------------------------------------------------

Old:
----
  cadvisor-0.60.5.tar.gz

New:
----
  cadvisor-0.60.6.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ cadvisor.spec ++++++
--- /var/tmp/diff_new_pack.S58pzl/_old  2026-10-02 23:09:12.599043197 +0200
+++ /var/tmp/diff_new_pack.S58pzl/_new  2026-10-02 23:09:12.601043281 +0200
@@ -19,7 +19,7 @@
 
 %global goipath github.com/google/cadvisor
 Name:           cadvisor
-Version:        0.60.5
+Version:        0.60.6
 Release:        0
 Summary:        A Simple and Comprehensive Vulnerability Scanner for Containers
 License:        Apache-2.0
@@ -32,7 +32,7 @@
 BuildRequires:  golang-packaging
 BuildRequires:  systemd-rpm-macros
 BuildRequires:  zstd
-BuildRequires:  golang(API) = 1.26
+BuildRequires:  golang(API) = 1.27
 Requires:       ca-certificates
 Requires:       git-core
 Requires:       rpm

++++++ _service ++++++
--- /var/tmp/diff_new_pack.S58pzl/_old  2026-10-02 23:09:12.643045037 +0200
+++ /var/tmp/diff_new_pack.S58pzl/_new  2026-10-02 23:09:12.646045162 +0200
@@ -5,6 +5,7 @@
     <param name="compression">zst</param>
     <param 
name="replace">go.opentelemetry.io/otel=go.opentelemetry.io/[email protected]</param>
     <param 
name="replace">google.golang.org/grpc=google.golang.org/[email protected]</param>
+    <param 
name="replace">github.com/klauspost/compress=github.com/klauspost/[email protected]</param>
   </service>
   <service name="set_version" mode="manual">
     <param name="basename">cadvisor</param>

++++++ cadvisor-0.60.5.tar.gz -> cadvisor-0.60.6.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cadvisor-0.60.5/.github/workflows/tag-lib-module.yml 
new/cadvisor-0.60.6/.github/workflows/tag-lib-module.yml
--- old/cadvisor-0.60.5/.github/workflows/tag-lib-module.yml    1970-01-01 
01:00:00.000000000 +0100
+++ new/cadvisor-0.60.6/.github/workflows/tag-lib-module.yml    2026-09-09 
02:35:58.000000000 +0200
@@ -0,0 +1,44 @@
+name: Tag lib module
+
+on:
+  push:
+    tags:
+      - 'v*'
+  workflow_dispatch:
+    inputs:
+      tag:
+        description: 'Existing v* tag to mirror as lib/<tag>'
+        required: true
+        type: string
+
+jobs:
+  tag-lib:
+    runs-on: ubuntu-latest
+    permissions:
+      contents: write  # Needed for pushing the lib/<tag> tag
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v6
+        with:
+          ref: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || 
github.ref }}
+
+      - name: Set TAG environment variable
+        run: |
+          if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then
+            echo "TAG=${INPUTS_TAG}" >> "$GITHUB_ENV"
+          else
+            echo "TAG=${GITHUB_REF#refs/tags/}" >> "$GITHUB_ENV"
+          fi
+        env:
+          INPUTS_TAG: ${{ inputs.tag }}
+
+      - name: Create and push lib/${{ env.TAG }} tag
+        run: |
+          # Release tags cut from branches that predate the lib module have 
nothing to mirror
+          if [ ! -f lib/go.mod ]; then
+            echo "No lib/go.mod at ${TAG}; skipping"
+            exit 0
+          fi
+          git tag "lib/${TAG}"
+          # Pushing an identical existing tag is a no-op; a conflicting one 
fails the job
+          git push origin "lib/${TAG}"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/cadvisor-0.60.5/cmd/internal/storage/stdout/stdout.go 
new/cadvisor-0.60.6/cmd/internal/storage/stdout/stdout.go
--- old/cadvisor-0.60.5/cmd/internal/storage/stdout/stdout.go   2026-07-11 
07:07:30.000000000 +0200
+++ new/cadvisor-0.60.6/cmd/internal/storage/stdout/stdout.go   2026-09-09 
02:35:58.000000000 +0200
@@ -109,31 +109,36 @@
        // Unix Timestamp
        series[serTimestamp] = uint64(time.Now().UnixNano())
 
-       // Total usage in nanoseconds
-       series[serCPUUsageTotal] = stats.Cpu.Usage.Total
+       // Cpu/Network became pointers; some containers omit one or both.
+       if stats.Cpu != nil {
+               // Total usage in nanoseconds
+               series[serCPUUsageTotal] = stats.Cpu.Usage.Total
+
+               // To be deprecated in 0.39
+               series[colCPUCumulativeUsage] = series[serCPUUsageTotal]
+
+               // CPU usage: Time spend in system space (in nanoseconds)
+               series[serCPUUsageSystem] = stats.Cpu.Usage.System
+
+               // CPU usage: Time spent in user space (in nanoseconds)
+               series[serCPUUsageUser] = stats.Cpu.Usage.User
+
+               // CPU usage per CPU
+               for i := 0; i < len(stats.Cpu.Usage.PerCpu); i++ {
+                       series[serCPUUsagePerCPU+"."+strconv.Itoa(i)] = 
stats.Cpu.Usage.PerCpu[i]
+               }
 
-       // To be deprecated in 0.39
-       series[colCPUCumulativeUsage] = series[serCPUUsageTotal]
-
-       // CPU usage: Time spend in system space (in nanoseconds)
-       series[serCPUUsageSystem] = stats.Cpu.Usage.System
-
-       // CPU usage: Time spent in user space (in nanoseconds)
-       series[serCPUUsageUser] = stats.Cpu.Usage.User
-
-       // CPU usage per CPU
-       for i := 0; i < len(stats.Cpu.Usage.PerCpu); i++ {
-               series[serCPUUsagePerCPU+"."+strconv.Itoa(i)] = 
stats.Cpu.Usage.PerCpu[i]
+               // Load Average
+               series[serLoadAverage] = uint64(stats.Cpu.LoadAverage)
        }
 
-       // Load Average
-       series[serLoadAverage] = uint64(stats.Cpu.LoadAverage)
-
-       // Network stats.
-       series[serRxBytes] = stats.Network.RxBytes
-       series[serRxErrors] = stats.Network.RxErrors
-       series[serTxBytes] = stats.Network.TxBytes
-       series[serTxErrors] = stats.Network.TxErrors
+       if stats.Network != nil {
+               // Network stats.
+               series[serRxBytes] = stats.Network.RxBytes
+               series[serRxErrors] = stats.Network.RxErrors
+               series[serTxBytes] = stats.Network.TxBytes
+               series[serTxErrors] = stats.Network.TxErrors
+       }
 
        // Referenced Memory
        series[serReferencedMemory] = stats.ReferencedMemory
@@ -154,6 +159,9 @@
 }
 
 func (driver *stdoutStorage) memoryStatsToValues(series *map[string]uint64, 
stats *info.ContainerStats) {
+       if stats.Memory == nil {
+               return
+       }
        // Memory Usage
        (*series)[serMemoryUsage] = stats.Memory.Usage
        // Maximum memory usage recorded
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/cadvisor-0.60.5/cmd/internal/storage/stdout/stdout_test.go 
new/cadvisor-0.60.6/cmd/internal/storage/stdout/stdout_test.go
--- old/cadvisor-0.60.5/cmd/internal/storage/stdout/stdout_test.go      
1970-01-01 01:00:00.000000000 +0100
+++ new/cadvisor-0.60.6/cmd/internal/storage/stdout/stdout_test.go      
2026-09-09 02:35:58.000000000 +0200
@@ -0,0 +1,63 @@
+// Copyright 2026 Google Inc. All Rights Reserved.
+//
+// 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 stdout
+
+import (
+       "testing"
+       "time"
+
+       info "github.com/google/cadvisor/info/v1"
+)
+
+func TestAddStatsNilOptionalFields(t *testing.T) {
+       driver, err := newStorage("testhost")
+       if err != nil {
+               t.Fatal(err)
+       }
+
+       cInfo := &info.ContainerInfo{
+               ContainerReference: info.ContainerReference{
+                       Name: "/test",
+               },
+       }
+       // Cpu present, Network/Memory omitted — used to panic at 
stats.Network.RxBytes.
+       stats := &info.ContainerStats{
+               Timestamp: time.Now(),
+               Cpu: &info.CpuStats{
+                       Usage: info.CpuUsage{
+                               Total:  1000,
+                               User:   600,
+                               System: 400,
+                       },
+               },
+       }
+
+       if err := driver.AddStats(cInfo, stats); err != nil {
+               t.Fatalf("AddStats: %v", err)
+       }
+}
+
+func TestAddStatsNilStats(t *testing.T) {
+       driver, err := newStorage("testhost")
+       if err != nil {
+               t.Fatal(err)
+       }
+       cInfo := &info.ContainerInfo{
+               ContainerReference: info.ContainerReference{Name: "/test"},
+       }
+       if err := driver.AddStats(cInfo, nil); err != nil {
+               t.Fatalf("AddStats(nil): %v", err)
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cadvisor-0.60.5/lib/fs/zfs/plugin.go 
new/cadvisor-0.60.6/lib/fs/zfs/plugin.go
--- old/cadvisor-0.60.5/lib/fs/zfs/plugin.go    2026-07-11 07:07:30.000000000 
+0200
+++ new/cadvisor-0.60.6/lib/fs/zfs/plugin.go    2026-09-09 02:35:58.000000000 
+0200
@@ -24,6 +24,12 @@
 
 type zfsPlugin struct{}
 
+// Overridable for tests.
+var (
+       zfsDevicePath = "/dev/zfs"
+       getZfsStats   = GetZfsStats
+)
+
 // NewPlugin creates a new ZFS filesystem plugin.
 func NewPlugin() fs.FsPlugin {
        return &zfsPlugin{}
@@ -44,15 +50,19 @@
 }
 
 // GetStats returns filesystem statistics for ZFS.
+//
+// When /dev/zfs is missing, or when zfs tooling cannot collect stats (common
+// in unprivileged containers that still see the device node but lack
+// permission to use it), fall back to VFS so mountpoint capacity remains
+// available via statfs.
 func (p *zfsPlugin) GetStats(device string, partition fs.PartitionInfo) 
(*fs.FsStats, error) {
-       // Check if ZFS is available - if /dev/zfs doesn't exist, fall back to 
VFS
-       if _, err := os.Stat("/dev/zfs"); os.IsNotExist(err) {
+       if _, err := os.Stat(zfsDevicePath); err != nil {
                return nil, fs.ErrFallbackToVFS
        }
 
-       capacity, free, avail, err := GetZfsStats(device)
+       capacity, free, avail, err := getZfsStats(device)
        if err != nil {
-               return nil, err
+               return nil, fs.ErrFallbackToVFS
        }
 
        return &fs.FsStats{
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cadvisor-0.60.5/lib/fs/zfs/plugin_test.go 
new/cadvisor-0.60.6/lib/fs/zfs/plugin_test.go
--- old/cadvisor-0.60.5/lib/fs/zfs/plugin_test.go       1970-01-01 
01:00:00.000000000 +0100
+++ new/cadvisor-0.60.6/lib/fs/zfs/plugin_test.go       2026-09-09 
02:35:58.000000000 +0200
@@ -0,0 +1,90 @@
+// Copyright 2024 Google Inc. All Rights Reserved.
+//
+// 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 zfs
+
+import (
+       "errors"
+       "os"
+       "path/filepath"
+       "testing"
+
+       "github.com/google/cadvisor/lib/fs"
+)
+
+func TestGetStatsFallsBackWhenDevMissing(t *testing.T) {
+       oldPath := zfsDevicePath
+       zfsDevicePath = filepath.Join(t.TempDir(), "missing-zfs")
+       defer func() { zfsDevicePath = oldPath }()
+
+       _, err := NewPlugin().GetStats("tank/root", 
fs.PartitionInfo{Mountpoint: "/"})
+       if !errors.Is(err, fs.ErrFallbackToVFS) {
+               t.Fatalf("GetStats() error = %v, want ErrFallbackToVFS", err)
+       }
+}
+
+func TestGetStatsFallsBackOnZfsError(t *testing.T) {
+       // Simulate /dev/zfs present but unusable (e.g. EPERM in an unprivileged
+       // container): device node exists, yet zfs list fails.
+       dev := filepath.Join(t.TempDir(), "zfs")
+       if err := os.WriteFile(dev, nil, 0o644); err != nil {
+               t.Fatal(err)
+       }
+
+       oldPath, oldFn := zfsDevicePath, getZfsStats
+       zfsDevicePath = dev
+       getZfsStats = func(string) (uint64, uint64, uint64, error) {
+               return 0, 0, 0, os.ErrPermission
+       }
+       defer func() {
+               zfsDevicePath = oldPath
+               getZfsStats = oldFn
+       }()
+
+       _, err := NewPlugin().GetStats("tank/root", 
fs.PartitionInfo{Mountpoint: "/"})
+       if !errors.Is(err, fs.ErrFallbackToVFS) {
+               t.Fatalf("GetStats() error = %v, want ErrFallbackToVFS", err)
+       }
+}
+
+func TestGetStatsSuccess(t *testing.T) {
+       dev := filepath.Join(t.TempDir(), "zfs")
+       if err := os.WriteFile(dev, nil, 0o644); err != nil {
+               t.Fatal(err)
+       }
+
+       oldPath, oldFn := zfsDevicePath, getZfsStats
+       zfsDevicePath = dev
+       getZfsStats = func(pool string) (uint64, uint64, uint64, error) {
+               if pool != "tank/root" {
+                       t.Errorf("pool = %q, want tank/root", pool)
+               }
+               return 300, 100, 100, nil
+       }
+       defer func() {
+               zfsDevicePath = oldPath
+               getZfsStats = oldFn
+       }()
+
+       stats, err := NewPlugin().GetStats("tank/root", 
fs.PartitionInfo{Mountpoint: "/"})
+       if err != nil {
+               t.Fatalf("GetStats() unexpected error: %v", err)
+       }
+       if stats.Capacity != 300 || stats.Free != 100 || stats.Available != 100 
{
+               t.Errorf("stats = %+v, want capacity=300 free=100 
available=100", stats)
+       }
+       if stats.Type != fs.ZFS {
+               t.Errorf("Type = %q, want %q", stats.Type, fs.ZFS)
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cadvisor-0.60.5/lib/utils/sysinfo/sysinfo.go 
new/cadvisor-0.60.6/lib/utils/sysinfo/sysinfo.go
--- old/cadvisor-0.60.5/lib/utils/sysinfo/sysinfo.go    2026-07-11 
07:07:30.000000000 +0200
+++ new/cadvisor-0.60.6/lib/utils/sysinfo/sysinfo.go    2026-09-09 
02:35:58.000000000 +0200
@@ -223,8 +223,11 @@
                node := info.Node{Id: id}
 
                cpuDirs, err := sysFs.GetCPUsPaths(nodeDir)
+               if err != nil {
+                       return nil, 0, fmt.Errorf("failed to get CPUs for NUMA 
node %q: %w", nodeDir, err)
+               }
                if len(cpuDirs) == 0 {
-                       klog.Warningf("Found node without any CPU, nodeDir: %s, 
number of cpuDirs %d, err: %v", nodeDir, len(cpuDirs), err)
+                       klog.V(4).Infof("Found memory-only NUMA node, nodeDir: 
%s", nodeDir)
                } else {
                        cores, err := getCoresInfo(sysFs, cpuDirs)
                        if err != nil {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/cadvisor-0.60.5/lib/utils/sysinfo/sysinfo_test.go 
new/cadvisor-0.60.6/lib/utils/sysinfo/sysinfo_test.go
--- old/cadvisor-0.60.5/lib/utils/sysinfo/sysinfo_test.go       2026-07-11 
07:07:30.000000000 +0200
+++ new/cadvisor-0.60.6/lib/utils/sysinfo/sysinfo_test.go       2026-09-09 
02:35:58.000000000 +0200
@@ -16,6 +16,7 @@
 
 import (
        "encoding/json"
+       "errors"
        "fmt"
        "os"
        "sort"
@@ -372,6 +373,58 @@
        }
 }
 
+func TestGetNodesInfoWithMemoryOnlyNode(t *testing.T) {
+       fakeSys := &fakesysfs.FakeSysFs{}
+       nodePath := "/fakeSysfs/devices/system/node/node1"
+       fakeSys.SetNodesPaths([]string{nodePath}, nil)
+       fakeSys.SetCPUsPaths(map[string][]string{nodePath: {}}, nil)
+       fakeSys.SetMemory("MemTotal: 1048576 kB", nil)
+       fakeSys.SetHugePages(nil, nil)
+       fakeSys.SetDistances(nodePath, "10", nil)
+       wantMemory := uint64(1024 * 1024 * 1024)
+
+       nodes, cores, err := GetNodesInfo(fakeSys)
+
+       if err != nil {
+               t.Fatalf("GetNodesInfo() returned unexpected error: %v", err)
+       }
+       if cores != 0 {
+               t.Errorf("GetNodesInfo() cores = %d, want 0", cores)
+       }
+       if len(nodes) != 1 {
+               t.Fatalf("GetNodesInfo() returned %d nodes, want 1", len(nodes))
+       }
+       if nodes[0].Id != 1 {
+               t.Errorf("GetNodesInfo() node ID = %d, want 1", nodes[0].Id)
+       }
+       if len(nodes[0].Cores) != 0 {
+               t.Errorf("GetNodesInfo() memory-only node cores = %v, want 
none", nodes[0].Cores)
+       }
+       if nodes[0].Memory != wantMemory {
+               t.Errorf("GetNodesInfo() memory = %d, want %d", 
nodes[0].Memory, wantMemory)
+       }
+}
+
+func TestGetNodesInfoReturnsCPUPathError(t *testing.T) {
+       fakeSys := &fakesysfs.FakeSysFs{}
+       nodePath := "/fakeSysfs/devices/system/node/node0"
+       wantErr := errors.New("cannot read CPU paths")
+       fakeSys.SetNodesPaths([]string{nodePath}, nil)
+       fakeSys.SetCPUsPaths(nil, wantErr)
+
+       nodes, cores, err := GetNodesInfo(fakeSys)
+
+       if !errors.Is(err, wantErr) {
+               t.Errorf("GetNodesInfo() error = %v, want wrapped %v", err, 
wantErr)
+       }
+       if nodes != nil {
+               t.Errorf("GetNodesInfo() nodes on error = %v, want nil", nodes)
+       }
+       if cores != 0 {
+               t.Errorf("GetNodesInfo() cores on error = %d, want 0", cores)
+       }
+}
+
 func TestGetNodesInfoWithOfflineCPUs(t *testing.T) {
        fakeSys := &fakesysfs.FakeSysFs{}
        c := sysfs.CacheInfo{

++++++ vendor.tar.zst ++++++
++++ 3366 lines of diff (skipped)

Reply via email to