File tree Expand file tree Collapse file tree 4 files changed +98
-0
lines changed Expand file tree Collapse file tree 4 files changed +98
-0
lines changed Original file line number Diff line number Diff line change @@ -36,6 +36,14 @@ func TestNewCNIPodInfoProvider(t *testing.T) {
3636 },
3737 wantErr : false ,
3838 },
39+ {
40+ name : "empty CNI response" ,
41+ exec : newCNIStateFakeExec (
42+ `{}` ,
43+ ),
44+ want : map [string ]cns.PodInfo {},
45+ wantErr : false ,
46+ },
3947 }
4048 for _ , tt := range tests {
4149 t .Run (tt .name , func (t * testing.T ) {
Original file line number Diff line number Diff line change 1+ package cnireconciler
2+
3+ import (
4+ "encoding/json"
5+ "errors"
6+ "os"
7+
8+ "github.com/Azure/azure-container-networking/cns/logger"
9+ )
10+
11+ // WriteObjectToCNIStatefile checks for a file at the CNI statefile path,
12+ // and checks if it is empty. If it is empty, writes an empty JSON object to
13+ // it so older CNI can execute. Does nothing and returns no error if the
14+ // file does not exist.
15+ //
16+ // This is a hack to get older CNI to run when CNS has mounted the statefile
17+ // path, but the statefile wasn't written by CNI yet. Kubelet will stub an
18+ // empty file on the host filesystem, crashing older CNI because it doesn't know
19+ // how to handle empty statefiles.
20+ func WriteObjectToCNIStatefile () error {
21+ filename := "/var/run/azure-vnet.json"
22+ return writeObjectToFile (filename )
23+ }
24+
25+ func writeObjectToFile (filename string ) error {
26+ fi , err := os .Stat (filename )
27+ if err != nil {
28+ if errors .Is (err , os .ErrNotExist ) {
29+ return nil
30+ }
31+ return err
32+ }
33+
34+ if fi .Size () != 0 {
35+ return nil
36+ }
37+
38+ logger .Printf ("Writing {} to CNI statefile" )
39+ b , _ := json .Marshal (map [string ]string {})
40+ return os .WriteFile (filename , b , os .FileMode (0666 ))
41+ }
Original file line number Diff line number Diff line change 1+ package cnireconciler
2+
3+ import (
4+ "os"
5+ "path"
6+ "testing"
7+
8+ "github.com/Azure/azure-container-networking/cns/logger"
9+ "github.com/stretchr/testify/assert"
10+ "github.com/stretchr/testify/require"
11+ )
12+
13+ func TestWriteObjectToFile (t * testing.T ) {
14+ name := "testdata/test"
15+ err := os .MkdirAll (path .Dir (name ), 0666 )
16+ require .NoError (t , err )
17+
18+ _ , err = os .Stat (name )
19+ require .ErrorIs (t , err , os .ErrNotExist )
20+
21+ // create empty file
22+ _ , err = os .Create (name )
23+ require .NoError (t , err )
24+ defer os .Remove (name )
25+
26+ // check it's empty
27+ fi , _ := os .Stat (name )
28+ assert .Equal (t , fi .Size (), int64 (0 ))
29+
30+ // populate
31+ require .NoError (t , writeObjectToFile (name ))
32+
33+ // read
34+ b , err := os .ReadFile (name )
35+ require .NoError (t , err )
36+ assert .Equal (t , string (b ), "{}" )
37+ }
38+
39+ func init () {
40+ logger .InitLogger ("testlogs" , 0 , 0 , "./" )
41+ }
Original file line number Diff line number Diff line change @@ -21,6 +21,7 @@ import (
2121 "github.com/Azure/azure-container-networking/cnm/ipam"
2222 "github.com/Azure/azure-container-networking/cnm/network"
2323 "github.com/Azure/azure-container-networking/cns"
24+ "github.com/Azure/azure-container-networking/cns/cnireconciler"
2425 cni "github.com/Azure/azure-container-networking/cns/cnireconciler"
2526 "github.com/Azure/azure-container-networking/cns/cnsclient"
2627 "github.com/Azure/azure-container-networking/cns/common"
@@ -521,6 +522,13 @@ func main() {
521522 // Initialze state in if CNS is running in CRD mode
522523 // State must be initialized before we start HTTPRestService
523524 if config .ChannelMode == cns .CRD {
525+ // Check the CNI statefile mount, and if the file is empty
526+ // stub an empty JSON object
527+ if err := cnireconciler .WriteObjectToCNIStatefile (); err != nil {
528+ logger .Errorf ("Failed to write empty object to CNI state: %v" , err )
529+ return
530+ }
531+
524532 // We might be configured to reinitialize state from the CNI instead of the apiserver.
525533 // If so, we should check that the the CNI is new enough to support the state commands,
526534 // otherwise we fall back to the existing behavior.
You can’t perform that action at this time.
0 commit comments