Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package flannel for openSUSE:Factory checked 
in at 2026-07-09 22:21:15
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/flannel (Old)
 and      /work/SRC/openSUSE:Factory/.flannel.new.1991 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "flannel"

Thu Jul  9 22:21:15 2026 rev:30 rq:1364706 version:0.28.7

Changes:
--------
--- /work/SRC/openSUSE:Factory/flannel/flannel.changes  2026-06-09 
14:25:47.710188490 +0200
+++ /work/SRC/openSUSE:Factory/.flannel.new.1991/flannel.changes        
2026-07-09 22:22:24.644334583 +0200
@@ -1,0 +2,24 @@
+Thu Jul  9 05:30:40 UTC 2026 - Priyanka Saggu <[email protected]>
+
+- Update to version 0.28.7:
+  * prepare for release v0.28.7 (#2485)
+  * fix: use install-conf in chart (#2484)
+  * fix: use semver tag type in Docker meta to support release events (#2483)
+  * build(deps): bump github/codeql-action/upload-sarif (#2480)
+  * build(deps): bump golang.org/x/net from 0.54.0 to 0.55.0 (#2473), fix for 
CVE-2026-33814 (bsc#1265780) and CVE-2026-39821 (bsc#1266620)
+  * build(deps): bump docker/build-push-action from 7.2.0 to 7.3.0 (#2479)
+  * build(deps): bump golangci/golangci-lint-action from 9.2.1 to 9.3.0 (#2478)
+  * build(deps): bump docker/metadata-action from 6.1.0 to 6.2.0 (#2476)
+  * build(deps): bump the tencent group with 2 updates (#2475)
+  * build(deps): bump the etcd group with 4 updates (#2474)
+  * fix: skip invalid CIDRs in subnet file readers (#2454)
+  * subnet/etcd: recover subnet watch from compaction (#2471)
+  * Bump the tencent group across 1 directory with 2 updates (#2461)
+  * Bump actions/attest-build-provenance from 4.1.0 to 4.1.1 (#2467)
+  * Bump actions/setup-go from 6.4.0 to 6.5.0 (#2468)
+  * feat: new install_conf cmd to install flannel's config file (#2466)
+  * Bump the other-go-modules group with 2 updates (#2464)
+  * Bump actions/checkout from 6.0.2 to 7.0.0 (#2465)
+  * Bump github/codeql-action from 4.36.0 to 4.36.2 (#2463)
+
+-------------------------------------------------------------------

Old:
----
  flannel-0.28.5.tar.gz

New:
----
  flannel-0.28.7.tar.gz

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

Other differences:
------------------
++++++ flannel.spec ++++++
--- /var/tmp/diff_new_pack.jT7Om9/_old  2026-07-09 22:22:25.700370877 +0200
+++ /var/tmp/diff_new_pack.jT7Om9/_new  2026-07-09 22:22:25.700370877 +0200
@@ -24,7 +24,7 @@
 %define flannel_container_path registry.opensuse.org/kubic/flannel
 
 Name:           flannel
-Version:        0.28.5
+Version:        0.28.7
 Release:        0
 Summary:        An etcd backed network fabric for containers
 License:        Apache-2.0

++++++ _service ++++++
--- /var/tmp/diff_new_pack.jT7Om9/_old  2026-07-09 22:22:25.856376239 +0200
+++ /var/tmp/diff_new_pack.jT7Om9/_new  2026-07-09 22:22:25.860376377 +0200
@@ -5,7 +5,7 @@
     <param name="exclude">.git</param>
     <param name="versionformat">@PARENT_TAG@</param>
     <param name="versionrewrite-pattern">v(.*)</param>
-    <param name="revision">v0.28.5</param>
+    <param name="revision">v0.28.7</param>
     <param name="changesgenerate">enable</param>
   </service>
   <service name="tar" mode="disabled"/>

++++++ _servicedata ++++++
--- /var/tmp/diff_new_pack.jT7Om9/_old  2026-07-09 22:22:25.948379401 +0200
+++ /var/tmp/diff_new_pack.jT7Om9/_new  2026-07-09 22:22:25.960379814 +0200
@@ -1,6 +1,6 @@
 <servicedata>
 <service name="tar_scm">
                 <param 
name="url">https://github.com/flannel-io/flannel.git</param>
-              <param 
name="changesrevision">d47fd8e5f1c93fe7fd80cb06d7fc41ac502e2376</param></service></servicedata>
+              <param 
name="changesrevision">4adfab1f33f385f51329bd47dfa7ec57e5049311</param></service></servicedata>
 (No newline at EOF)
 

++++++ flannel-0.28.5.tar.gz -> flannel-0.28.7.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/.github/workflows/build.yaml 
new/flannel-0.28.7/.github/workflows/build.yaml
--- old/flannel-0.28.5/.github/workflows/build.yaml     2026-06-04 
17:51:08.000000000 +0200
+++ new/flannel-0.28.7/.github/workflows/build.yaml     2026-07-07 
18:06:56.000000000 +0200
@@ -16,13 +16,13 @@
 
     steps:
       - name: Checkout repository
-        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
+        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
 
       - name: set tag
         run: echo "GIT_TAG=$(git describe --tags --always)" >> $GITHUB_ENV
 
       - name: Set up Go 1.x
-        uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c #v6.4.0
+        uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 #v6.5.0
         with:
           go-version: ${{ env.GO_VERSION }}
 
@@ -34,7 +34,7 @@
 
       - name: Docker meta
         id: meta
-        uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 
#v6.1.0
+        uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 
#v6.2.0
         with:
           images: ${{ env.REPOSITORY }}
           flavor: latest=false
@@ -42,7 +42,7 @@
             type=ref, event=branch
 
       - name: Build multi-arch Docker image
-        uses: 
docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf #v6.15.0
+        uses: 
docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a #v6.15.0
         with:
           context: .
           file: images/Dockerfile
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/.github/workflows/codeql-analysis.yml 
new/flannel-0.28.7/.github/workflows/codeql-analysis.yml
--- old/flannel-0.28.5/.github/workflows/codeql-analysis.yml    2026-06-04 
17:51:08.000000000 +0200
+++ new/flannel-0.28.7/.github/workflows/codeql-analysis.yml    2026-07-07 
18:06:56.000000000 +0200
@@ -42,16 +42,16 @@
 
     steps:
     - name: Checkout repository
-      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
+      uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
 
     - name: Set up Go 1.x
-      uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c #v6.4.0
+      uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 #v6.5.0
       with:
         go-version: ${{ env.GO_VERSION }}
 
     # Initializes the CodeQL tools for scanning.
     - name: Initialize CodeQL
-      uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa 
#v4.36.0
+      uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e 
#v4.36.2
       with:
         languages: ${{ matrix.language }}
         # If you wish to specify custom queries, you can do so here or in a 
config file.
@@ -74,4 +74,4 @@
        make dist/flanneld
 
     - name: Perform CodeQL Analysis
-      uses: 
github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa #v4.36.0
+      uses: 
github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e #v4.36.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/.github/workflows/e2eTests.yaml 
new/flannel-0.28.7/.github/workflows/e2eTests.yaml
--- old/flannel-0.28.5/.github/workflows/e2eTests.yaml  2026-06-04 
17:51:08.000000000 +0200
+++ new/flannel-0.28.7/.github/workflows/e2eTests.yaml  2026-07-07 
18:06:56.000000000 +0200
@@ -12,12 +12,12 @@
     timeout-minutes: 90
     steps:
     - name: Set up Go 1.x
-      uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c #v6.4.0
+      uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 #v6.5.0
       with:
         go-version: ^1.25
 
     - name: Check out code into the Go module directory
-      uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
+      uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
 
     - name: set up modules
       run: sudo modprobe br_netfilter overlay
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/.github/workflows/golangci-lint.yaml 
new/flannel-0.28.7/.github/workflows/golangci-lint.yaml
--- old/flannel-0.28.5/.github/workflows/golangci-lint.yaml     2026-06-04 
17:51:08.000000000 +0200
+++ new/flannel-0.28.7/.github/workflows/golangci-lint.yaml     2026-07-07 
18:06:56.000000000 +0200
@@ -13,13 +13,13 @@
     name: lint
     runs-on: ubuntu-latest
     steps:
-      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
-      - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c #v6.4.0
+      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
+      - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 #v6.5.0
         with:
           go-version: "1.25"
           cache: false
       - name: golangci-lint
-        uses: 
golangci/golangci-lint-action@82606bf257cbaff209d206a39f5134f0cfbfd2ee #v9.2.1
+        uses: 
golangci/golangci-lint-action@ba0d7d2ec06a0ea1cb5fa41b2e4a3ab91d21278a #v9.3.0
         with:
           version: v2.7.2
           args: "--timeout=5m"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/.github/workflows/k3s-e2eTests.yml 
new/flannel-0.28.7/.github/workflows/k3s-e2eTests.yml
--- old/flannel-0.28.5/.github/workflows/k3s-e2eTests.yml       2026-06-04 
17:51:08.000000000 +0200
+++ new/flannel-0.28.7/.github/workflows/k3s-e2eTests.yml       2026-07-07 
18:06:56.000000000 +0200
@@ -16,10 +16,10 @@
     runs-on: ubuntu-latest
     timeout-minutes: 90
     steps:
-      - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
+      - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
 
       - name: Set up Go 1.x
-        uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c #v6.4.0
+        uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 #v6.5.0
         with:
           go-version: ${{ env.GO_VERSION }}
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/.github/workflows/release.yml 
new/flannel-0.28.7/.github/workflows/release.yml
--- old/flannel-0.28.5/.github/workflows/release.yml    2026-06-04 
17:51:08.000000000 +0200
+++ new/flannel-0.28.7/.github/workflows/release.yml    2026-07-07 
18:06:56.000000000 +0200
@@ -23,13 +23,13 @@
 
     steps:
       - name: Checkout repository
-        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
+        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
 
       - name: set tag
         run: echo "GIT_TAG=$(git describe --tags --always)" >> $GITHUB_ENV
 
       - name: Set up Go 1.x
-        uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c #v6.4.0
+        uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 #v6.5.0
         with:
           go-version: ${{ env.GO_VERSION }}
 
@@ -44,12 +44,12 @@
 
       - name: Docker meta
         id: meta
-        uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 
#v6.1.0
+        uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 
#v6.2.0
         with:
           images: ${{ env.REPOSITORY }}
           flavor: latest=false
           tags: |
-            type=ref,event=tag
+            type=semver,pattern={{version}}
 
       - name: Log in to Docker Hub
         if: github.repository_owner == 'flannel-io' && success()
@@ -60,7 +60,7 @@
 
       - name: Build and push Docker image
         if: github.repository_owner == 'flannel-io' && success()
-        uses: 
docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf #v7.2.0
+        uses: 
docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a #v7.3.0
         with:
           context: .
           file: images/Dockerfile
@@ -79,13 +79,13 @@
 
     steps:
       - name: Checkout repository
-        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
+        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
 
       - name: set tag
         run: echo "GIT_TAG=$(git describe --tags --always)" >> $GITHUB_ENV
 
       - name: Set up Go 1.x
-        uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c #v6.4.0
+        uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 #v6.5.0
         with:
           go-version: ${{ env.GO_VERSION }}
 
@@ -107,13 +107,13 @@
 
       - name: Extract metadata (tags, labels) for Docker
         id: meta
-        uses: docker/metadata-action@80c7e94dd9b9319bd5eb7a0e0fe9291e23a2a2e9 
#v6.1.0
+        uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 
#v6.2.0
         with:
           images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
 
       - name: Build and push Docker image
         id: push
-        uses: 
docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf #v7.2.0
+        uses: 
docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a #v7.3.0
         with:
           context: .
           file: images/Dockerfile
@@ -124,7 +124,7 @@
           build-args: TAG=${{ env.GIT_TAG }}
 
       - name: Generate artifact attestation
-        uses: 
actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 #v4.1.0
+        uses: 
actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 #v4.1.1
         with:
           subject-name: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
           subject-digest: ${{ steps.push.outputs.digest }}
@@ -138,13 +138,13 @@
 
     steps:
       - name: Checkout repository
-        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
+        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
 
       - name: set tag
         run: echo "GIT_TAG=$(git describe --tags --always)" >> $GITHUB_ENV
 
       - name: Set up Go 1.x
-        uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c #v6.4.0
+        uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 #v6.5.0
         with:
           go-version: ${{ env.GO_VERSION }}
 
@@ -177,7 +177,7 @@
     runs-on: ubuntu-latest
     steps:
       - name: Checkout repository
-        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
+        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
 
       - name: set tag
         run: echo "GIT_TAG=$(git describe --tags --always)" >> $GITHUB_ENV
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/.github/workflows/scorecard.yml 
new/flannel-0.28.7/.github/workflows/scorecard.yml
--- old/flannel-0.28.5/.github/workflows/scorecard.yml  2026-06-04 
17:51:08.000000000 +0200
+++ new/flannel-0.28.7/.github/workflows/scorecard.yml  2026-07-07 
18:06:56.000000000 +0200
@@ -34,7 +34,7 @@
 
     steps:
       - name: "Checkout code"
-        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # 
v6.0.2
+        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # 
v7.0.0
         with:
           persist-credentials: false
 
@@ -73,6 +73,6 @@
       # Upload the results to GitHub's code scanning dashboard (optional).
       # Commenting out will disable upload of results to your repo's Code 
Scanning dashboard
       - name: "Upload to code-scanning"
-        uses: 
github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # 
v4.36.0
+        uses: 
github/codeql-action/upload-sarif@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a # 
v4.36.3
         with:
           sarif_file: results.sarif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/.github/workflows/trivy.yml 
new/flannel-0.28.7/.github/workflows/trivy.yml
--- old/flannel-0.28.5/.github/workflows/trivy.yml      2026-06-04 
17:51:08.000000000 +0200
+++ new/flannel-0.28.7/.github/workflows/trivy.yml      2026-07-07 
18:06:56.000000000 +0200
@@ -28,10 +28,10 @@
     runs-on: ubuntu-latest
     steps:
       - name: Checkout code
-        uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd #v6.0.2
+        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 #v7.0.0
 
       - name: Set up Go 1.x
-        uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c #v6.4.0
+        uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 #v6.5.0
         with:
           go-version: ${{ env.GO_VERSION }}
 
@@ -48,6 +48,6 @@
           output: 'trivy-results.sarif'
 
       - name: Upload Trivy scan results to GitHub Security tab
-        uses: 
github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa
+        uses: 
github/codeql-action/upload-sarif@54f647b7e1bb85c95cddabcd46b0c578ec92bc1a
         with:
           sarif_file: 'trivy-results.sarif'
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/Documentation/kube-flannel.yml 
new/flannel-0.28.7/Documentation/kube-flannel.yml
--- old/flannel-0.28.5/Documentation/kube-flannel.yml   2026-06-04 
17:51:08.000000000 +0200
+++ new/flannel-0.28.7/Documentation/kube-flannel.yml   2026-07-07 
18:06:56.000000000 +0200
@@ -133,7 +133,7 @@
       serviceAccountName: flannel
       initContainers:
       - name: install-cni-plugin
-        image: ghcr.io/flannel-io/flannel-cni-plugin:v1.9.1-flannel1
+        image: ghcr.io/flannel-io/flannel-cni-plugin:v1.9.1-flannel2
         command:
         - cp
         args:
@@ -144,11 +144,10 @@
         - name: cni-plugin
           mountPath: /opt/cni/bin
       - name: install-cni
-        image: ghcr.io/flannel-io/flannel:v0.28.5
+        image: ghcr.io/flannel-io/flannel:v0.28.7
         command:
-        - cp
+        - /opt/bin/install-conf
         args:
-        - -f
         - /etc/kube-flannel/cni-conf.json
         - /etc/cni/net.d/10-flannel.conflist
         volumeMounts:
@@ -158,7 +157,7 @@
           mountPath: /etc/kube-flannel/
       containers:
       - name: kube-flannel
-        image: ghcr.io/flannel-io/flannel:v0.28.5
+        image: ghcr.io/flannel-io/flannel:v0.28.7
         command:
         - /opt/bin/flanneld
         args:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/flannel-0.28.5/Documentation/kustomization/kube-flannel/kube-flannel.yml 
new/flannel-0.28.7/Documentation/kustomization/kube-flannel/kube-flannel.yml
--- 
old/flannel-0.28.5/Documentation/kustomization/kube-flannel/kube-flannel.yml    
    2026-06-04 17:51:08.000000000 +0200
+++ 
new/flannel-0.28.7/Documentation/kustomization/kube-flannel/kube-flannel.yml    
    2026-07-07 18:06:56.000000000 +0200
@@ -124,7 +124,7 @@
       serviceAccountName: flannel
       initContainers:
       - name: install-cni-plugin
-        image: ghcr.io/flannel-io/flannel-cni-plugin:v1.9.1-flannel1
+        image: ghcr.io/flannel-io/flannel-cni-plugin:v1.9.1-flannel2
         command:
         - cp
         args:
@@ -135,7 +135,7 @@
         - name: cni-plugin
           mountPath: /opt/cni/bin
       - name: install-cni
-        image: ghcr.io/flannel-io/flannel:v0.28.5
+        image: ghcr.io/flannel-io/flannel:v0.28.7
         command:
         - cp
         args:
@@ -149,7 +149,7 @@
           mountPath: /etc/kube-flannel/
       containers:
       - name: kube-flannel
-        image: ghcr.io/flannel-io/flannel:v0.28.5
+        image: ghcr.io/flannel-io/flannel:v0.28.7
         command:
         - /opt/bin/flanneld
         args:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/flannel-0.28.5/Documentation/kustomization/kube-flannel/kustomization.yaml 
new/flannel-0.28.7/Documentation/kustomization/kube-flannel/kustomization.yaml
--- 
old/flannel-0.28.5/Documentation/kustomization/kube-flannel/kustomization.yaml  
    2026-06-04 17:51:08.000000000 +0200
+++ 
new/flannel-0.28.7/Documentation/kustomization/kube-flannel/kustomization.yaml  
    2026-07-07 18:06:56.000000000 +0200
@@ -6,4 +6,4 @@
 - kube-flannel.yml
 images:
 - name: ghcr.io/flannel-io/flannel
-  newTag: v0.28.5
+  newTag: v0.28.7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/chart/kube-flannel/Chart.yaml 
new/flannel-0.28.7/chart/kube-flannel/Chart.yaml
--- old/flannel-0.28.5/chart/kube-flannel/Chart.yaml    2026-06-04 
17:51:08.000000000 +0200
+++ new/flannel-0.28.7/chart/kube-flannel/Chart.yaml    2026-07-07 
18:06:56.000000000 +0200
@@ -1,9 +1,9 @@
 apiVersion: v1
-appVersion: v0.28.5
+appVersion: v0.28.7
 description: Install Flannel Network Plugin.
 keywords:
 - Flannel
 name: flannel
 sources:
 - https://github.com/flannel-io/flannel
-version: v0.28.5
+version: v0.28.7
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/flannel-0.28.5/chart/kube-flannel/templates/daemonset.yaml 
new/flannel-0.28.7/chart/kube-flannel/templates/daemonset.yaml
--- old/flannel-0.28.5/chart/kube-flannel/templates/daemonset.yaml      
2026-06-04 17:51:08.000000000 +0200
+++ new/flannel-0.28.7/chart/kube-flannel/templates/daemonset.yaml      
2026-07-07 18:06:56.000000000 +0200
@@ -52,9 +52,8 @@
       - name: install-cni
         image: {{ .Values.flannel.image.repository }}:{{ 
.Values.flannel.image.tag }}
         command:
-        - cp
+        - /opt/bin/install-conf
         args:
-        - -f
         - /etc/kube-flannel/cni-conf.json
         - /etc/cni/net.d/10-flannel.conflist
         volumeMounts:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/chart/kube-flannel/values.yaml 
new/flannel-0.28.7/chart/kube-flannel/values.yaml
--- old/flannel-0.28.5/chart/kube-flannel/values.yaml   2026-06-04 
17:51:08.000000000 +0200
+++ new/flannel-0.28.7/chart/kube-flannel/values.yaml   2026-07-07 
18:06:56.000000000 +0200
@@ -12,11 +12,11 @@
   # kube-flannel image
   image:
     repository: ghcr.io/flannel-io/flannel
-    tag: v0.28.5
+    tag: v0.28.7
   flannel_cni:
     image:
       repository: ghcr.io/flannel-io/flannel-cni-plugin
-      tag: v1.9.1-flannel1
+      tag: v1.9.1-flannel2
   # cniBinDir is the directory to which the flannel CNI binary is installed.
   cniBinDir: "/opt/cni/bin"
   # cniConfDir is the directory where the CNI configuration is located.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/cmd/install_conf/main.go 
new/flannel-0.28.7/cmd/install_conf/main.go
--- old/flannel-0.28.5/cmd/install_conf/main.go 1970-01-01 01:00:00.000000000 
+0100
+++ new/flannel-0.28.7/cmd/install_conf/main.go 2026-07-07 18:06:56.000000000 
+0200
@@ -0,0 +1,41 @@
+// Copyright (c) 2026 Flannel 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.
+
+// This is a install tool for multus plugins
+package main
+
+import (
+       "fmt"
+       "os"
+       "path/filepath"
+
+       "github.com/flannel-io/flannel/pkg/utils"
+)
+
+func main() {
+       if len(os.Args) != 3 {
+               fmt.Fprintf(os.Stderr, "usage: %s <src> <dest>\n", os.Args[0])
+               os.Exit(1)
+       }
+
+       src := os.Args[1]
+       dest := os.Args[2]
+       destDir := filepath.Dir(dest)
+       destFileName := filepath.Base(dest)
+
+       if err := utils.CopyFileAtomic(src, destDir, "."+destFileName+".tmp", 
destFileName); err != nil {
+               fmt.Fprintf(os.Stderr, "error installing %q: %v\n", src, err)
+               os.Exit(1)
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/go.mod new/flannel-0.28.7/go.mod
--- old/flannel-0.28.5/go.mod   2026-06-04 17:51:08.000000000 +0200
+++ new/flannel-0.28.7/go.mod   2026-07-07 18:06:56.000000000 +0200
@@ -18,7 +18,7 @@
        github.com/vishvananda/netlink v1.3.1
        github.com/vishvananda/netns v0.0.5
        go.uber.org/zap v1.27.0 // indirect
-       golang.org/x/net v0.52.0 // indirect
+       golang.org/x/net v0.55.0 // indirect
        golang.org/x/oauth2 v0.34.0 // indirect
        golang.org/x/time v0.9.0 // indirect
        golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // 
indirect
@@ -31,9 +31,9 @@
 
 require (
        github.com/avast/retry-go/v4 v4.7.0
-       github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.108
-       github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc v1.3.83
-       golang.org/x/sync v0.20.0
+       github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.128
+       github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc v1.3.128
+       golang.org/x/sync v0.21.0
        sigs.k8s.io/knftables v0.0.18
 )
 
@@ -86,9 +86,9 @@
        github.com/x448/float16 v0.8.4 // indirect
        github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 // 
indirect
        go.etcd.io/bbolt v1.4.3 // indirect
-       go.etcd.io/etcd/etcdctl/v3 v3.6.12 // indirect
-       go.etcd.io/etcd/pkg/v3 v3.6.12 // indirect
-       go.etcd.io/etcd/server/v3 v3.6.12 // indirect
+       go.etcd.io/etcd/etcdctl/v3 v3.6.13 // indirect
+       go.etcd.io/etcd/pkg/v3 v3.6.13 // indirect
+       go.etcd.io/etcd/server/v3 v3.6.13 // indirect
        go.etcd.io/gofail v0.2.0 // indirect
        go.etcd.io/raft/v3 v3.6.0 // indirect
        go.opentelemetry.io/auto/sdk v1.2.1 // indirect
@@ -126,16 +126,16 @@
        github.com/modern-go/reflect2 v1.0.2 // indirect
        github.com/sirupsen/logrus v1.9.3 // indirect
        github.com/spf13/pflag v1.0.10 // indirect
-       go.etcd.io/etcd/api/v3 v3.6.12
-       go.etcd.io/etcd/client/pkg/v3 v3.6.12
-       go.etcd.io/etcd/client/v3 v3.6.12
-       go.etcd.io/etcd/tests/v3 v3.6.12
+       go.etcd.io/etcd/api/v3 v3.6.13
+       go.etcd.io/etcd/client/pkg/v3 v3.6.13
+       go.etcd.io/etcd/client/v3 v3.6.13
+       go.etcd.io/etcd/tests/v3 v3.6.13
        go.opencensus.io v0.24.0 // indirect
        go.uber.org/multierr v1.11.0 // indirect
-       golang.org/x/crypto v0.49.0 // indirect
-       golang.org/x/sys v0.45.0
-       golang.org/x/term v0.41.0 // indirect
-       golang.org/x/text v0.36.0 // indirect
+       golang.org/x/crypto v0.52.0 // indirect
+       golang.org/x/sys v0.46.0
+       golang.org/x/term v0.43.0 // indirect
+       golang.org/x/text v0.37.0 // indirect
        google.golang.org/grpc v1.79.3 // indirect
        google.golang.org/protobuf v1.36.10 // indirect
        gopkg.in/inf.v0 v0.9.1 // indirect
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/go.sum new/flannel-0.28.7/go.sum
--- old/flannel-0.28.5/go.sum   2026-06-04 17:51:08.000000000 +0200
+++ new/flannel-0.28.7/go.sum   2026-07-07 18:06:56.000000000 +0200
@@ -239,11 +239,10 @@
 github.com/stretchr/testify v1.8.1/go.mod 
h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
 github.com/stretchr/testify v1.11.1 
h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
 github.com/stretchr/testify v1.11.1/go.mod 
h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
-github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.83/go.mod 
h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
-github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.108 
h1:hvsGIT99NEIw/M/d0SM3ahPXLTdlKdMeiZaX023sYoM=
-github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common 
v1.3.108/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
-github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc v1.3.83 
h1:ie9YH+k8r+pgZMmexGHPQVxpqjqHqb6aNLwEQ0grnWQ=
-github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc v1.3.83/go.mod 
h1:YEf1XryuGZaXip8sc2zUzFn2H81aIOqh2I7vBlEXVFk=
+github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.3.128 
h1:sgXDEXppIfK18V7ilNGHheFc5GQexXqIEQFUGTXUn9Q=
+github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common 
v1.3.128/go.mod h1:r5r4xbfxSaeR04b166HGsBa/R4U3SueirEUpXGuw+Q0=
+github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc v1.3.128 
h1:4iWU0h3khteVH/PoZcfh3LKfWLoqJCmSbWSSa7lPx1w=
+github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/vpc v1.3.128/go.mod 
h1:qWgvXdUBs/FiD+astuzidFA5n3UkmnRL2wduAJxqRnU=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802 
h1:uruHq4dN7GR16kFc5fp3d1RIYzJW5onx8Ybykw2YQFA=
 github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod 
h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
 github.com/vishvananda/netlink v1.3.1 
h1:3AEMt62VKqz90r0tmNhog0r/PpWKmrEShJU0wJW6bV0=
@@ -258,20 +257,20 @@
 github.com/yuin/goldmark v1.2.1/go.mod 
h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 go.etcd.io/bbolt v1.4.3 h1:dEadXpI6G79deX5prL3QRNP6JB8UxVkqo4UPnHaNXJo=
 go.etcd.io/bbolt v1.4.3/go.mod h1:tKQlpPaYCVFctUIgFKFnAlvbmB3tpy1vkTnDWohtc0E=
-go.etcd.io/etcd/api/v3 v3.6.12 h1:OLOZUKEuAA36TR48F0cIaa8FdzrWygjyfrJxXg4iDgs=
-go.etcd.io/etcd/api/v3 v3.6.12/go.mod 
h1:p14EIQXHbuOQbVvL/WEes5uqKnxP9AgKJgpjbMVvzvE=
-go.etcd.io/etcd/client/pkg/v3 v3.6.12 
h1:36zzB+pQOdHbhN+kH2iJz/K8bJn0ZLtLfPPO7jozTDo=
-go.etcd.io/etcd/client/pkg/v3 v3.6.12/go.mod 
h1:hh2+ZXtfLzs3o6mn92ntgNPBrTJJOvXqICM5g3L3DMY=
-go.etcd.io/etcd/client/v3 v3.6.12 
h1:kMSP6JcPZMqSJiX+TXdUIBU/4eXEZWBAaui4VihMbIc=
-go.etcd.io/etcd/client/v3 v3.6.12/go.mod 
h1:CMs6fJWYiZQk4ytFjd4lE1diOvvRMmtbbn/alZXd3dQ=
-go.etcd.io/etcd/etcdctl/v3 v3.6.12 
h1:76ZC8YRa2DKLIjrDOKcQxC9+Tptlw2ZB3ZU52kiJjfU=
-go.etcd.io/etcd/etcdctl/v3 v3.6.12/go.mod 
h1:umvLlTUPlOAXGXtnH7HnOOIxKv4VtSn3giKIANnPZos=
-go.etcd.io/etcd/pkg/v3 v3.6.12 h1:rewjbWPC/H5GHK0yxPbU0lzdFdQR9RlpZL7XmLYm2BE=
-go.etcd.io/etcd/pkg/v3 v3.6.12/go.mod 
h1:qDFIetmpC8TTZfkZkDzpNrXtVqVsyYumRWNPFXFhcpQ=
-go.etcd.io/etcd/server/v3 v3.6.12 
h1:PAcIHCcTjPM1sbePiu7fCzNKQvOBFEaGnu2JFhgaGJQ=
-go.etcd.io/etcd/server/v3 v3.6.12/go.mod 
h1:iiREo2DGRVjtiAjQeA3LQyYCk6YDFo3uS30/vImHdtk=
-go.etcd.io/etcd/tests/v3 v3.6.12 
h1:4wIhw0O/X5iv+c0wesshrVytfSxxqKCd5RGIuzLbF88=
-go.etcd.io/etcd/tests/v3 v3.6.12/go.mod 
h1:bCdQ46Cw+OhSpVQGRkJjefnah3NeEmUYmd7EeI1+FOc=
+go.etcd.io/etcd/api/v3 v3.6.13 h1:AvHPZv15LYEe7tZDyFglv7xnbiuF6GMZpZqKpIzXTt0=
+go.etcd.io/etcd/api/v3 v3.6.13/go.mod 
h1:X9+3gaKwzjlOxzo6TZ2u3b7HcHBcAL+Ph7EBPjI/VWk=
+go.etcd.io/etcd/client/pkg/v3 v3.6.13 
h1:7QeMOisYByx8dBA7/CKcwCaPWfjb5C0xpmrIov/8WyY=
+go.etcd.io/etcd/client/pkg/v3 v3.6.13/go.mod 
h1:Dn2zUBOCu/6xYcd6iAjB7LgoY16OTQjDZfWHLwvuQj4=
+go.etcd.io/etcd/client/v3 v3.6.13 
h1:0E+9ZYGpMsi9KlOJVoCdONh9PUDawKDTy5mSNY8wOEI=
+go.etcd.io/etcd/client/v3 v3.6.13/go.mod 
h1:rtVI3vwobljb8xlTGcp1Yhz7hBIuBWULXwB848kqJGw=
+go.etcd.io/etcd/etcdctl/v3 v3.6.13 
h1:fhjsw6wPJD34VudE52FkdtYeCUVBw8ELb72qHu25vno=
+go.etcd.io/etcd/etcdctl/v3 v3.6.13/go.mod 
h1:xYM3HdxcRUtge6RFfYZWLJYsBnD0Vp4Vxthdw4kVgow=
+go.etcd.io/etcd/pkg/v3 v3.6.13 h1:Xqb4lSvcBg0el4xRa493+MTNRtMX10MsVoxoOr+O7z8=
+go.etcd.io/etcd/pkg/v3 v3.6.13/go.mod 
h1:YDonhdT0PCdcd/av/IyhXLNNcZk/nVCGZ38iyYFfAHU=
+go.etcd.io/etcd/server/v3 v3.6.13 
h1:gEGFSiJlYwzhvhZjfglj1oqe2LG8bmX47hSizwedAOs=
+go.etcd.io/etcd/server/v3 v3.6.13/go.mod 
h1:9NsHlIEPZFq27IzVfLKyU15HVF/gVAk3gEe4feD7qsk=
+go.etcd.io/etcd/tests/v3 v3.6.13 
h1:/giMm/X+asygOMvoCVbemT9rO9UwlL5Cqy8NjiseDFo=
+go.etcd.io/etcd/tests/v3 v3.6.13/go.mod 
h1:82S5H3OC7/8w0hielU8i2+Dh/VZavfFht2s/wtvuoMQ=
 go.etcd.io/gofail v0.2.0 h1:p19drv16FKK345a09a1iubchlw/vmRuksmRzgBIGjcA=
 go.etcd.io/gofail v0.2.0/go.mod h1:nL3ILMGfkXTekKI3clMBNazKnjUZjYLKmBHzsVAnC1o=
 go.etcd.io/raft/v3 v3.6.0 h1:5NtvbDVYpnfZWcIHgGRk9DyzkBIXOi8j+DDp1IcnUWQ=
@@ -314,8 +313,8 @@
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod 
h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod 
h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod 
h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.49.0 h1:+Ng2ULVvLHnJ/ZFEq4KdcDd/cfjrrjjNSXNzxg0Y4U4=
-golang.org/x/crypto v0.49.0/go.mod 
h1:ErX4dUh2UM+CFYiXZRTcMpEcN8b/1gxEuv3nODoYtCA=
+golang.org/x/crypto v0.52.0 h1:RMs7fP2rXdep0CftQlK8Uf+kibLm7qkCcradZWYz988=
+golang.org/x/crypto v0.52.0/go.mod 
h1:1QgfPxDqh0T2M/elOJtp9RvuR95kVjir0e6/BvEmGbc=
 golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod 
h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod 
h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod 
h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
@@ -332,8 +331,8 @@
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod 
h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod 
h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod 
h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.52.0 h1:He/TN1l0e4mmR3QqHMT2Xab3Aj3L9qjbhRm78/6jrW0=
-golang.org/x/net v0.52.0/go.mod h1:R1MAz7uMZxVMualyPXb+VaqGSa3LIaUqk0eEt3w36Sw=
+golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8=
+golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod 
h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.34.0 h1:hqK/t4AKgbqWkdkcAeI8XLmbK+4m4G5YeQRrmiotGlw=
 golang.org/x/oauth2 v0.34.0/go.mod 
h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
@@ -342,8 +341,8 @@
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod 
h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4=
-golang.org/x/sync v0.20.0/go.mod 
h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
+golang.org/x/sync v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
+golang.org/x/sync v0.21.0/go.mod 
h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod 
h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod 
h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod 
h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -353,14 +352,14 @@
 golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY=
-golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
-golang.org/x/term v0.41.0 h1:QCgPso/Q3RTJx2Th4bDLqML4W6iJiaXFq2/ftQF13YU=
-golang.org/x/term v0.41.0/go.mod 
h1:3pfBgksrReYfZ5lvYM0kSO0LIkAl4Yl2bXOkKP7Ec2A=
+golang.org/x/sys v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
+golang.org/x/sys v0.46.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw=
+golang.org/x/term v0.43.0 h1:S4RLU2sB31O/NCl+zFN9Aru9A/Cq2aqKpTZJ6B+DwT4=
+golang.org/x/term v0.43.0/go.mod 
h1:lrhlHNdQJHO+1qVYiHfFKVuVioJIheAc3fBSMFYEIsk=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
-golang.org/x/text v0.36.0 h1:JfKh3XmcRPqZPKevfXVpI1wXPTqbkE5f7JA92a55Yxg=
-golang.org/x/text v0.36.0/go.mod 
h1:NIdBknypM8iqVmPiuco0Dh6P5Jcdk8lJL0CUebqK164=
+golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc=
+golang.org/x/text v0.37.0/go.mod 
h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38=
 golang.org/x/time v0.9.0 h1:EsRrnYcQiGH+5FfbgvV4AP7qEZstoyrHB0DzarOQ4ZY=
 golang.org/x/time v0.9.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod 
h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@@ -371,8 +370,8 @@
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod 
h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod 
h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod 
h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
-golang.org/x/tools v0.43.0 h1:12BdW9CeB3Z+J/I/wj34VMl8X+fEXBxVR90JeMX5E7s=
-golang.org/x/tools v0.43.0/go.mod 
h1:uHkMso649BX2cZK6+RpuIPXS3ho2hZo4FVwfoy1vIk0=
+golang.org/x/tools v0.44.0 h1:UP4ajHPIcuMjT1GqzDWRlalUEoY+uzoZKnhOjbIPD2c=
+golang.org/x/tools v0.44.0/go.mod 
h1:KA0AfVErSdxRZIsOVipbv3rQhVXTnlU6UhKxHd1seDI=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod 
h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/images/Dockerfile 
new/flannel-0.28.7/images/Dockerfile
--- old/flannel-0.28.5/images/Dockerfile        2026-06-04 17:51:08.000000000 
+0200
+++ new/flannel-0.28.7/images/Dockerfile        2026-07-07 18:06:56.000000000 
+0200
@@ -15,6 +15,7 @@
 FROM --platform=$BUILDPLATFORM base-builder AS flannel-builder
 COPY Makefile go.mod go.sum *.go /build/
 COPY pkg /build/pkg
+COPY cmd /build/cmd
 WORKDIR /build
 RUN mkdir dist
 RUN go mod download
@@ -26,6 +27,9 @@
     export GOARCH=$(xx-info arch) &&\
     export ARCH=$(xx-info arch) &&\
     make dist/flanneld
+RUN export GOOS=$(xx-info os) &&\
+    export GOARCH=$(xx-info arch) &&\
+    CGO_ENABLED=0 go build -o dist/install-conf ./cmd/install_conf/
 RUN git clone https://github.com/kubernetes-sigs/iptables-wrappers.git 
/iptables-wrapper
 WORKDIR /iptables-wrapper
 RUN git checkout bfef9e5087a198b50a4124bb9ce9d2c7c99025dd
@@ -39,6 +43,7 @@
 RUN apk add --no-cache iproute2 ca-certificates nftables iptables strongswan 
iptables-legacy && update-ca-certificates
 RUN apk add wireguard-tools --no-cache --repository 
http://dl-cdn.alpinelinux.org/alpine/edge/community
 COPY --from=flannel-builder /build/dist/flanneld /opt/bin/flanneld
+COPY --from=flannel-builder /build/dist/install-conf /opt/bin/install-conf
 COPY dist/mk-docker-opts.sh /opt/bin/
 COPY --from=flannel-builder /iptables-wrapper/bin/iptables-wrapper /usr/sbin
 # check manually that iptables-legacy and iptables-nft are present since
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/main.go new/flannel-0.28.7/main.go
--- old/flannel-0.28.5/main.go  2026-06-04 17:51:08.000000000 +0200
+++ new/flannel-0.28.7/main.go  2026-07-07 18:06:56.000000000 +0200
@@ -608,6 +608,7 @@
                                _, cidr, err := net.ParseCIDR(cidrs[i])
                                if err != nil {
                                        log.Errorf("Couldn't parse previous %s 
from subnet file at %s: %s", CIDRKey, path, err)
+                                       continue
                                }
                                prevCIDRs = append(prevCIDRs, 
ip.FromIPNet(cidr))
                        }
@@ -643,6 +644,7 @@
                                _, cidr, err := net.ParseCIDR(cidrs[i])
                                if err != nil {
                                        log.Errorf("Couldn't parse previous %s 
from subnet file at %s: %s", CIDRKey, path, err)
+                                       continue
                                }
                                prevCIDRs = append(prevCIDRs, 
ip.FromIP6Net(cidr))
                        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/main_test.go 
new/flannel-0.28.7/main_test.go
--- old/flannel-0.28.5/main_test.go     1970-01-01 01:00:00.000000000 +0100
+++ new/flannel-0.28.7/main_test.go     2026-07-07 18:06:56.000000000 +0200
@@ -0,0 +1,146 @@
+// Copyright 2026 flannel 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 (
+       "net"
+       "os"
+       "path/filepath"
+       "testing"
+
+       "github.com/flannel-io/flannel/pkg/ip"
+)
+
+func TestReadCIDRsFromSubnetFileSkipsInvalidCIDRs(t *testing.T) {
+       path := writeSubnetFile(t, 
"FLANNEL_SUBNET=10.244.1.0/24,not-a-cidr,10.244.2.0/24\n")
+
+       defer assertNotPanics(t)()
+
+       got := ReadCIDRsFromSubnetFile(path, "FLANNEL_SUBNET")
+       want := []ip.IP4Net{
+               mustParseIP4Net(t, "10.244.1.0/24"),
+               mustParseIP4Net(t, "10.244.2.0/24"),
+       }
+
+       assertIP4NetsEqual(t, got, want)
+}
+
+func TestReadIP6CIDRsFromSubnetFileSkipsInvalidCIDRs(t *testing.T) {
+       path := writeSubnetFile(t, 
"FLANNEL_IPV6_SUBNET=fd00::/64,not-a-cidr,fd01::/64\n")
+
+       defer assertNotPanics(t)()
+
+       got := ReadIP6CIDRsFromSubnetFile(path, "FLANNEL_IPV6_SUBNET")
+       want := []ip.IP6Net{
+               mustParseIP6Net(t, "fd00::/64"),
+               mustParseIP6Net(t, "fd01::/64"),
+       }
+
+       assertIP6NetsEqual(t, got, want)
+}
+
+func TestReadCIDRFromSubnetFileInvalidOnlyReturnsEmpty(t *testing.T) {
+       path := writeSubnetFile(t, "FLANNEL_SUBNET=not-a-cidr\n")
+
+       defer assertNotPanics(t)()
+
+       got := ReadCIDRFromSubnetFile(path, "FLANNEL_SUBNET")
+       if !got.Empty() {
+               t.Fatalf("expected empty ipv4 subnet, got %s", got)
+       }
+}
+
+func TestReadIP6CIDRFromSubnetFileInvalidOnlyReturnsEmpty(t *testing.T) {
+       path := writeSubnetFile(t, "FLANNEL_IPV6_SUBNET=not-a-cidr\n")
+
+       defer assertNotPanics(t)()
+
+       got := ReadIP6CIDRFromSubnetFile(path, "FLANNEL_IPV6_SUBNET")
+       if !got.Empty() {
+               t.Fatalf("expected empty ipv6 subnet, got %s", got)
+       }
+}
+
+func writeSubnetFile(t *testing.T, contents string) string {
+       t.Helper()
+
+       path := filepath.Join(t.TempDir(), "subnet.env")
+       if err := os.WriteFile(path, []byte(contents), 0o600); err != nil {
+               t.Fatalf("write subnet file: %v", err)
+       }
+
+       return path
+}
+
+func assertNotPanics(t *testing.T) func() {
+       t.Helper()
+
+       return func() {
+               t.Helper()
+               if r := recover(); r != nil {
+                       t.Fatalf("unexpected panic: %v", r)
+               }
+       }
+}
+
+func mustParseIP4Net(t *testing.T, cidr string) ip.IP4Net {
+       t.Helper()
+
+       _, network, err := net.ParseCIDR(cidr)
+       if err != nil {
+               t.Fatalf("parse ipv4 cidr %q: %v", cidr, err)
+       }
+
+       return ip.FromIPNet(network)
+}
+
+func mustParseIP6Net(t *testing.T, cidr string) ip.IP6Net {
+       t.Helper()
+
+       _, network, err := net.ParseCIDR(cidr)
+       if err != nil {
+               t.Fatalf("parse ipv6 cidr %q: %v", cidr, err)
+       }
+
+       return ip.FromIP6Net(network)
+}
+
+func assertIP4NetsEqual(t *testing.T, got, want []ip.IP4Net) {
+       t.Helper()
+
+       if len(got) != len(want) {
+               t.Fatalf("unexpected ipv4 cidr count: got %d want %d", 
len(got), len(want))
+       }
+
+       for i := range want {
+               if !got[i].Equal(want[i]) {
+                       t.Fatalf("unexpected ipv4 cidr at index %d: got %s want 
%s", i, got[i], want[i])
+               }
+       }
+}
+
+func assertIP6NetsEqual(t *testing.T, got, want []ip.IP6Net) {
+       t.Helper()
+
+       if len(got) != len(want) {
+               t.Fatalf("unexpected ipv6 cidr count: got %d want %d", 
len(got), len(want))
+       }
+
+       for i := range want {
+               if !got[i].Equal(want[i]) {
+                       t.Fatalf("unexpected ipv6 cidr at index %d: got %s want 
%s", i, got[i], want[i])
+               }
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/pkg/subnet/etcd/registry.go 
new/flannel-0.28.7/pkg/subnet/etcd/registry.go
--- old/flannel-0.28.5/pkg/subnet/etcd/registry.go      2026-06-04 
17:51:08.000000000 +0200
+++ new/flannel-0.28.7/pkg/subnet/etcd/registry.go      2026-07-07 
18:06:56.000000000 +0200
@@ -293,7 +293,7 @@
        for {
                wctx, cancel := context.WithCancel(ctx)
                defer cancel()
-               log.Infof("registry: watching subnets starting from rev %d", 
since)
+               log.V(4).Infof("registry: watching subnets starting from rev 
%d", since)
                rch := esr.cli.Watch(etcd.WithRequireLeader(wctx), key, 
etcd.WithPrefix(), etcd.WithRev(since))
                if rch == nil {
                        log.Errorf("Failed to establish etcd watch channel")
@@ -316,17 +316,47 @@
                        case wresp, ok := <-rch:
                                err := wresp.Err()
                                if !ok || err != nil {
-                                       if err != nil {
-                                               log.Warningf("etcd watch 
channel for %s closed with error %v, reconnecting...", key, err)
-                                       } else {
-                                               log.Warningf("etcd watch 
channel for %s closed, reconnecting...", key)
-                                       }
                                        cancel()
+                                       // If the watch fell behind etcd's 
compaction horizon, reconnecting
+                                       // at the same revision fails 
identically forever (mvcc: required
+                                       // revision has been compacted). 
Re-list to grab a fresh snapshot at
+                                       // a current revision and resume from 
there instead of hot-looping.
+                                       if isCompacted(wresp) {
+                                               log.Warningf("etcd watch for %s 
fell behind compaction horizon (compact rev %d), re-listing and resuming", key, 
wresp.CompactRevision)
+                                               for {
+                                                       next, rerr := 
esr.resyncWatch(ctx, leaseWatchChan)
+                                                       if rerr == nil {
+                                                               since = next
+                                                               
exponentialBackoff = initialBackoff
+                                                               break innerLoop
+                                                       }
+                                                       log.Errorf("failed to 
re-list subnets after compaction: %v", rerr)
+                                                       timer := 
time.NewTimer(exponentialBackoff)
+                                                       select {
+                                                       case <-ctx.Done():
+                                                               timer.Stop()
+                                                               err := 
esr.cli.Close()
+                                                               if err != nil {
+                                                                       
log.Errorf("Failed to close etcd client: %v", err)
+                                                               }
+                                                               
close(leaseWatchChan)
+                                                               return ctx.Err()
+                                                       case <-timer.C:
+                                                       }
+                                                       exponentialBackoff = 
min(exponentialBackoff*2, maxBackoff)
+                                               }
+                                       }
+                                       log.Warningf("etcd watch channel for %s 
closed (%v), reconnecting from rev %d...", key, err, since)
                                        time.Sleep(exponentialBackoff)
                                        exponentialBackoff = 
min(exponentialBackoff*2, maxBackoff)
                                        break innerLoop
                                }
                                exponentialBackoff = initialBackoff // Reset 
backoff on success
+                               // Advance the resume revision so a future 
reconnect picks up where we
+                               // left off rather than replaying from the 
original start revision.
+                               if wresp.Header.Revision != 0 {
+                                       since = wresp.Header.Revision + 1
+                               }
                                results := make([]lease.LeaseWatchResult, 0)
                                for _, etcdEvent := range wresp.Events {
                                        subnetEvent, err := 
parseSubnetWatchResponse(ctx, esr.cli, etcdEvent)
@@ -528,6 +558,29 @@
        return &lease, nil
 }
 
+// isCompacted reports whether a watch response failed because its start 
revision
+// has been compacted away by etcd. Reconnecting at the same revision would 
fail
+// identically forever, so the caller must re-list at a fresh revision instead.
+func isCompacted(wresp etcd.WatchResponse) bool {
+       return wresp.CompactRevision != 0 || errors.Is(wresp.Err(), 
rpctypes.ErrCompacted)
+}
+
+// resyncWatch re-lists all subnet leases, emits the fresh snapshot on ch, and
+// returns the revision the caller should resume watching from. Used to 
recover a
+// watch that has fallen behind etcd's compaction horizon.
+func (esr *etcdSubnetRegistry) resyncWatch(ctx context.Context, ch chan 
[]lease.LeaseWatchResult) (int64, error) {
+       wr, err := esr.leasesWatchReset(ctx)
+       if err != nil {
+               return 0, err
+       }
+       select {
+       case ch <- []lease.LeaseWatchResult{wr}:
+       case <-ctx.Done():
+               return 0, ctx.Err()
+       }
+       return getNextIndex(wr.Cursor)
+}
+
 // leasesWatchReset is called when incremental lease watch failed and we need 
to grab a snapshot
 func (esr *etcdSubnetRegistry) leasesWatchReset(ctx context.Context) 
(lease.LeaseWatchResult, error) {
        wr := lease.LeaseWatchResult{}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/pkg/subnet/etcd/registry_test.go 
new/flannel-0.28.7/pkg/subnet/etcd/registry_test.go
--- old/flannel-0.28.5/pkg/subnet/etcd/registry_test.go 2026-06-04 
17:51:08.000000000 +0200
+++ new/flannel-0.28.7/pkg/subnet/etcd/registry_test.go 2026-07-07 
18:06:56.000000000 +0200
@@ -216,3 +216,157 @@
 
        // TODO: watchSubnet and watchNetworks
 }
+
+// TestWatchSubnetsRecoversFromCompaction exercises the case where a subnet 
watch
+// falls behind etcd's compaction horizon. Before the fix, watchSubnets 
reconnected
+// at the same now-compacted revision forever (hot-looping on "required 
revision has
+// been compacted" and never delivering anything). The fix re-lists at a fresh
+// revision and resumes, so the watch must deliver a snapshot followed by live 
events.
+func TestWatchSubnetsRecoversFromCompaction(t *testing.T) {
+       integration.BeforeTestExternal(t)
+
+       clus := integration.NewCluster(t, &integration.ClusterConfig{Size: 1})
+       defer clus.Terminate(t)
+
+       client := clus.RandClient()
+       // Use a non-cancelable context like TestEtcdRegistry: cancelling drives
+       // watchSubnets to Close() the etcd client, which is shared with the 
test
+       // cluster harness and would break Terminate.
+       ctx := context.Background()
+
+       r, kvApi := newTestEtcdRegistry(t, ctx, client)
+
+       if _, err := kvApi.Put(ctx, "/coreos.com/network/config",
+               `{ "Network": "10.1.0.0/16", "Backend": { "Type": "host-gw" } 
}`); err != nil {
+               t.Fatal("Failed to put network config", err)
+       }
+
+       // An existing lease so the recovery re-list has something to snapshot.
+       sn := ip.IP4Net{IP: ip.MustParseIP4("10.1.5.0"), PrefixLen: 24}
+       attrs := &lease.LeaseAttrs{PublicIP: ip.MustParseIP4("1.2.3.4")}
+       if _, err := r.createSubnet(ctx, sn, ip.IP6Net{}, attrs, 24*time.Hour); 
err != nil {
+               t.Fatal("Failed to create subnet lease", err)
+       }
+
+       // Advance the store revision, then compact past it so that watching 
from an
+       // old revision is guaranteed to hit "required revision has been 
compacted".
+       var compactRev int64
+       for i := 0; i < 5; i++ {
+               resp, err := kvApi.Put(ctx, "/coreos.com/network/_bump", 
fmt.Sprintf("%d", i))
+               if err != nil {
+                       t.Fatal("Failed to bump revision", err)
+               }
+               compactRev = resp.Header.Revision
+       }
+       if _, err := client.Compact(ctx, compactRev); err != nil {
+               t.Fatal("Failed to compact etcd", err)
+       }
+
+       // Start the watch from rev 1, now below the compaction horizon.
+       receiver := make(chan []lease.LeaseWatchResult, 16)
+       go func() { _ = r.watchSubnets(ctx, receiver, 1) }()
+
+       // Recovery must surface a re-list snapshot that includes the existing 
lease.
+       if !waitForSnapshot(receiver, sn, 10*time.Second) {
+               t.Fatal("watchSubnets did not recover from compaction with a 
re-list snapshot")
+       }
+
+       // A live event for a newly created lease proves the watch resumed at a 
current
+       // revision instead of staying stuck on the compacted one.
+       sn2 := ip.IP4Net{IP: ip.MustParseIP4("10.1.6.0"), PrefixLen: 24}
+       if _, err := r.createSubnet(ctx, sn2, ip.IP6Net{}, attrs, 
24*time.Hour); err != nil {
+               t.Fatal("Failed to create second subnet lease", err)
+       }
+       if !waitForEvent(receiver, lease.EventAdded, sn2, 10*time.Second) {
+               t.Fatal("watchSubnets did not resume delivering live events 
after recovery")
+       }
+}
+
+// TestResyncWatchCancelWithBlockedReceiver is a regression test for the
+// ctx-aware send in resyncWatch. Before the fix, a blocked receiver caused
+// resyncWatch to hang indefinitely. After the fix it must return
+// context.Canceled promptly.
+func TestResyncWatchCancelWithBlockedReceiver(t *testing.T) {
+       integration.BeforeTestExternal(t)
+
+       clus := integration.NewCluster(t, &integration.ClusterConfig{Size: 1})
+       defer clus.Terminate(t)
+
+       client := clus.RandClient()
+       ctx := context.Background()
+       r, kvApi := newTestEtcdRegistry(t, ctx, client)
+
+       if _, err := kvApi.Put(ctx, "/coreos.com/network/config",
+               `{ "Network": "10.1.0.0/16", "Backend": { "Type": "host-gw" } 
}`); err != nil {
+               t.Fatal("seed config:", err)
+       }
+
+       sn := ip.IP4Net{IP: ip.MustParseIP4("10.1.5.0"), PrefixLen: 24}
+       attrs := &lease.LeaseAttrs{PublicIP: ip.MustParseIP4("1.2.3.4")}
+       if _, err := r.createSubnet(ctx, sn, ip.IP6Net{}, attrs, 24*time.Hour); 
err != nil {
+               t.Fatal("seed subnet:", err)
+       }
+
+       // Unbuffered receiver: resyncWatch's send blocks until a reader arrives
+       // or the context is canceled.
+       receiver := make(chan []lease.LeaseWatchResult)
+       watchCtx, cancel := context.WithCancel(context.Background())
+       defer cancel()
+
+       done := make(chan error, 1)
+       go func() {
+               esr := r.(*etcdSubnetRegistry)
+               _, err := esr.resyncWatch(watchCtx, receiver)
+               done <- err
+       }()
+
+       // 500 ms is generous for a re-list over loopback; by then the goroutine
+       // should be blocked in the select waiting to send to the unbuffered 
receiver.
+       time.Sleep(500 * time.Millisecond)
+       cancel()
+
+       select {
+       case err := <-done:
+               if err != context.Canceled {
+                       t.Fatalf("resyncWatch returned %v, want 
context.Canceled", err)
+               }
+       case <-time.After(3 * time.Second):
+               t.Fatal("resyncWatch did not exit within 3s after context 
cancellation with blocked receiver")
+       }
+}
+
+func waitForSnapshot(receiver chan []lease.LeaseWatchResult, sn ip.IP4Net, 
timeout time.Duration) bool {
+       deadline := time.After(timeout)
+       for {
+               select {
+               case batch := <-receiver:
+                       for _, wr := range batch {
+                               for _, l := range wr.Snapshot {
+                                       if l.Subnet.Equal(sn) {
+                                               return true
+                                       }
+                               }
+                       }
+               case <-deadline:
+                       return false
+               }
+       }
+}
+
+func waitForEvent(receiver chan []lease.LeaseWatchResult, etype 
lease.EventType, sn ip.IP4Net, timeout time.Duration) bool {
+       deadline := time.After(timeout)
+       for {
+               select {
+               case batch := <-receiver:
+                       for _, wr := range batch {
+                               for _, ev := range wr.Events {
+                                       if ev.Type == etype && 
ev.Lease.Subnet.Equal(sn) {
+                                               return true
+                                       }
+                               }
+                       }
+               case <-deadline:
+                       return false
+               }
+       }
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/flannel-0.28.5/pkg/utils/utils.go 
new/flannel-0.28.7/pkg/utils/utils.go
--- old/flannel-0.28.5/pkg/utils/utils.go       1970-01-01 01:00:00.000000000 
+0100
+++ new/flannel-0.28.7/pkg/utils/utils.go       2026-07-07 18:06:56.000000000 
+0200
@@ -0,0 +1,84 @@
+// Copyright (c) 2026 Flannel 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 cmdutils is the package that contains utilities for multus command
+package utils
+
+import (
+       "fmt"
+       "io"
+       "os"
+       "path/filepath"
+)
+
+// CopyFileAtomic does file copy atomically
+func CopyFileAtomic(srcFilePath, destDir, tempFileName, destFileName string) 
error {
+       tempFilePath := filepath.Join(destDir, tempFileName)
+       // check temp filepath and remove old file if exists
+       if _, err := os.Stat(tempFilePath); err == nil {
+               err = os.Remove(tempFilePath)
+               if err != nil {
+                       return fmt.Errorf("cannot remove old temp file %q: %v", 
tempFilePath, err)
+               }
+       }
+
+       // create temp file
+       f, err := os.CreateTemp(destDir, tempFileName)
+       if err != nil {
+               return fmt.Errorf("cannot create temp file %q in %q: %v", 
tempFileName, destDir, err)
+       }
+       defer func() { _ = f.Close() }()
+
+       srcFile, err := os.Open(srcFilePath)
+       if err != nil {
+               return fmt.Errorf("cannot open file %q: %v", srcFilePath, err)
+       }
+       defer func() { _ = srcFile.Close() }()
+
+       // Copy file to tempfile
+       _, err = io.Copy(f, srcFile)
+       if err != nil {
+               _ = f.Close()
+               _ = os.Remove(tempFilePath)
+               return fmt.Errorf("cannot write data to temp file %q: %v", 
tempFilePath, err)
+       }
+       if err := f.Sync(); err != nil {
+               return fmt.Errorf("cannot flush temp file %q: %v", 
tempFilePath, err)
+       }
+       if err := f.Close(); err != nil {
+               return fmt.Errorf("cannot close temp file %q: %v", 
tempFilePath, err)
+       }
+
+       // change file mode if different
+       destFilePath := filepath.Join(destDir, destFileName)
+       _, err = os.Stat(destFilePath)
+       if err != nil && !os.IsNotExist(err) {
+               return err
+       }
+       srcFileStat, err := os.Stat(srcFilePath)
+       if err != nil {
+               return err
+       }
+
+       if err := os.Chmod(f.Name(), srcFileStat.Mode()); err != nil {
+               return fmt.Errorf("cannot set stat on temp file %q: %v", 
f.Name(), err)
+       }
+
+       // replace file with tempfile
+       if err := os.Rename(f.Name(), destFilePath); err != nil {
+               return fmt.Errorf("cannot replace %q with temp file %q: %v", 
destFilePath, tempFilePath, err)
+       }
+
+       return nil
+}

++++++ flannel.obsinfo ++++++
--- /var/tmp/diff_new_pack.jT7Om9/_old  2026-07-09 22:22:26.404395074 +0200
+++ /var/tmp/diff_new_pack.jT7Om9/_new  2026-07-09 22:22:26.412395349 +0200
@@ -1,5 +1,5 @@
 name: flannel
-version: 0.28.5
-mtime: 1780588268
-commit: d47fd8e5f1c93fe7fd80cb06d7fc41ac502e2376
+version: 0.28.7
+mtime: 1783440416
+commit: 4adfab1f33f385f51329bd47dfa7ec57e5049311
 

++++++ vendor.tar.gz ++++++
/work/SRC/openSUSE:Factory/flannel/vendor.tar.gz 
/work/SRC/openSUSE:Factory/.flannel.new.1991/vendor.tar.gz differ: char 117, 
line 1

Reply via email to