Skip to content

Commit 4c4e5f5

Browse files
fix: Remove unreadable CNS state file upon CNS service start (#782)
This change removes unreadable state file ( azure-cns.json ) while starting the CNS service
1 parent 73ae4e0 commit 4c4e5f5

File tree

7 files changed

+53
-21
lines changed

7 files changed

+53
-21
lines changed

cns/restserver/api_test.go

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"encoding/json"
99
"encoding/xml"
1010
"fmt"
11+
"github.com/Azure/azure-container-networking/store"
1112
"net/http"
1213
"net/http/httptest"
1314
"net/url"
@@ -26,6 +27,7 @@ import (
2627
const (
2728
defaultCnsURL = "http://localhost:10090"
2829
contentTypeJSON = "application/json"
30+
cnsJsonFileName = "azure-cns.json"
2931
)
3032

3133
type IPAddress struct {
@@ -125,7 +127,10 @@ func TestMain(m *testing.M) {
125127
logger.InitLogger("testlogs", 0, 0, "./")
126128

127129
// Create the service.
128-
startService()
130+
if err = startService(); err != nil {
131+
fmt.Printf("Failed to start CNS Service. Error: %v", err)
132+
os.Exit(1)
133+
}
129134

130135
// Setup mock nmagent server
131136
u, err := url.Parse("tcp://" + nmagentEndpoint)
@@ -908,34 +913,50 @@ func setEnv(t *testing.T) *httptest.ResponseRecorder {
908913
return w
909914
}
910915

911-
func startService() {
916+
func startService() error {
912917
var err error
913918
// Create the service.
914919
config := common.ServiceConfig{}
920+
// Create the key value store.
921+
if config.Store, err = store.NewJsonFileStore(cnsJsonFileName); err != nil {
922+
logger.Errorf("Failed to create store file: %s, due to error %v\n", cnsJsonFileName, err)
923+
return err
924+
}
925+
915926
service, err = NewHTTPRestService(&config, fakes.NewFakeImdsClient(), fakes.NewFakeNMAgentClient())
916927
if err != nil {
917-
fmt.Printf("Failed to create CNS object %v\n", err)
918-
os.Exit(1)
928+
return err
919929
}
920930
svc = service.(*HTTPRestService)
921931
svc.Name = "cns-test-server"
922932
if err != nil {
923933
logger.Errorf("Failed to create CNS object, err:%v.\n", err)
924-
return
934+
return err
925935
}
926936

927937
svc.IPAMPoolMonitor = fakes.NewIPAMPoolMonitorFake()
928938

929939
if service != nil {
940+
// Create empty azure-cns.json. CNS should start successfully by deleting this file
941+
file, _ := os.Create(cnsJsonFileName)
942+
file.Close()
943+
930944
err = service.Start(&config)
931945
if err != nil {
932946
logger.Errorf("Failed to start CNS, err:%v.\n", err)
933-
return
947+
return err
948+
}
949+
950+
if _, err := os.Stat(cnsJsonFileName); err == nil || !os.IsNotExist(err) {
951+
logger.Errorf("Failed to remove empty CNS state file: %s, err:%v", cnsJsonFileName, err)
952+
return err
934953
}
935954
}
936955

937956
// Get the internal http mux as test hook.
938957
mux = service.(*HTTPRestService).Listener.GetMux()
958+
959+
return nil
939960
}
940961

941962
// IGNORE TEST AS IT IS FAILING. TODO:- Fix it https://msazure.visualstudio.com/One/_workitems/edit/7720083

cns/restserver/internalapi_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"context"
88
"encoding/json"
99
"fmt"
10+
"os"
1011
"reflect"
1112
"strconv"
1213
"testing"
@@ -545,5 +546,8 @@ func restartService() {
545546
fmt.Println("Restart Service")
546547

547548
service.Stop()
548-
startService()
549+
if err := startService(); err != nil {
550+
fmt.Printf("Failed to restart CNS Service. Error: %v", err)
551+
os.Exit(1)
552+
}
549553
}

cns/restserver/restserver.go

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,19 +132,13 @@ func NewHTTPRestService(config *common.ServiceConfig, imdsClientInterface imdscl
132132

133133
// Start starts the CNS listener.
134134
func (service *HTTPRestService) Start(config *common.ServiceConfig) error {
135-
136135
err := service.Initialize(config)
137136
if err != nil {
138137
logger.Errorf("[Azure CNS] Failed to initialize base service, err:%v.", err)
139138
return err
140139
}
141140

142-
err = service.restoreState()
143-
if err != nil {
144-
logger.Errorf("[Azure CNS] Failed to restore service state, err:%v.", err)
145-
return err
146-
}
147-
141+
service.restoreState()
148142
err = service.restoreNetworkState()
149143
if err != nil {
150144
logger.Errorf("[Azure CNS] Failed to restore network state, err:%v.", err)

cns/restserver/util.go

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,13 @@ func (service *HTTPRestService) saveState() error {
7474
}
7575

7676
// restoreState restores CNS state from persistent store.
77-
func (service *HTTPRestService) restoreState() error {
77+
func (service *HTTPRestService) restoreState() {
7878
logger.Printf("[Azure CNS] restoreState")
7979

8080
// Skip if a store is not provided.
8181
if service.store == nil {
8282
logger.Printf("[Azure CNS] store not initialized.")
83-
return nil
83+
return
8484
}
8585

8686
// Read any persisted state.
@@ -89,15 +89,16 @@ func (service *HTTPRestService) restoreState() error {
8989
if err == store.ErrKeyNotFound {
9090
// Nothing to restore.
9191
logger.Printf("[Azure CNS] No state to restore.\n")
92-
return nil
92+
} else {
93+
logger.Errorf("[Azure CNS] Failed to restore state, err:%v. Removing azure-cns.json", err)
94+
service.store.Remove()
9395
}
9496

95-
logger.Errorf("[Azure CNS] Failed to restore state, err:%v\n", err)
96-
return err
97+
return
9798
}
9899

99100
logger.Printf("[Azure CNS] Restored state, %+v\n", service.state)
100-
return nil
101+
return
101102
}
102103

103104
func (service *HTTPRestService) saveNetworkContainerGoalState(req cns.CreateNetworkContainerRequest) (int, string) {

store/json.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,6 @@ func (kvs *jsonFileStore) flush() error {
148148
return fmt.Errorf("temp file close failed with: %v", err)
149149
}
150150

151-
log.Printf("renaming temp file %v to state file", tmpFileName)
152151
// atomic replace
153152
if err = platform.ReplaceFile(tmpFileName, kvs.fileName); err != nil {
154153
return fmt.Errorf("rename temp file to state file failed:%v", err)
@@ -276,3 +275,11 @@ func (kvs *jsonFileStore) GetLockFileModificationTime() (time.Time, error) {
276275
func (kvs *jsonFileStore) GetLockFileName() string {
277276
return kvs.fileName + lockExtension
278277
}
278+
279+
func (kvs *jsonFileStore) Remove() {
280+
kvs.Mutex.Lock()
281+
if err := os.Remove(kvs.fileName); err != nil {
282+
log.Errorf("could not remove file %s. Error: %v", kvs.fileName, err)
283+
}
284+
kvs.Mutex.Unlock()
285+
}

store/store.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ type KeyValueStore interface {
1818
GetModificationTime() (time.Time, error)
1919
GetLockFileModificationTime() (time.Time, error)
2020
GetLockFileName() string
21+
Remove()
2122
}
2223

2324
var (

testutils/store_mock.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,3 +47,7 @@ func (store *KeyValueStoreMock) GetLockFileName() string {
4747
return ""
4848
}
4949

50+
func (store *KeyValueStoreMock) Remove() {
51+
return
52+
}
53+

0 commit comments

Comments
 (0)