From 97585cc66746a3afce957b09fac93a75704f39a5 Mon Sep 17 00:00:00 2001 From: Paul Johnston Date: Wed, 13 Oct 2021 16:13:55 -0700 Subject: [PATCH 1/4] parent b1d7723c3a9659737bec78141111a930501fa086 author Paul Johnston 1634166835 -0700 committer Paul Johnston 1637019591 -0800 parent b1d7723c3a9659737bec78141111a930501fa086 author Paul Johnston 1634166835 -0700 committer Paul Johnston 1637019572 -0800 feat: Exists() method on store feat: config as flag to cns feat: statefile path per OS binary as os specific path feat: Exists() method on store feat: config as flag to cns binary as os specific path --- cni/client/client.go | 9 +++------ cns/cnireconciler/statefile.go | 3 ++- cns/configuration/configuration.go | 11 ++++++++--- cns/configuration/configuration_test.go | 9 +++++++-- cns/restserver/util.go | 2 +- cns/service/main.go | 10 +++++++++- common/config.go | 4 ++++ platform/os_linux.go | 4 ++++ platform/os_windows.go | 6 ++++++ store/json.go | 7 +++++++ store/mockstore.go | 4 ++++ store/store.go | 1 + testutils/store_mock.go | 9 +++++++-- 13 files changed, 63 insertions(+), 16 deletions(-) diff --git a/cni/client/client.go b/cni/client/client.go index 745f8dde48..d78aa8790b 100644 --- a/cni/client/client.go +++ b/cni/client/client.go @@ -9,14 +9,11 @@ import ( "github.com/Azure/azure-container-networking/cni" "github.com/Azure/azure-container-networking/cni/api" "github.com/Azure/azure-container-networking/log" + "github.com/Azure/azure-container-networking/platform" semver "github.com/hashicorp/go-version" utilexec "k8s.io/utils/exec" ) -const ( - azureVnetExecutable = "/opt/cni/bin/azure-vnet" -) - type Client interface { GetEndpointState() (*api.AzureCNIState, error) } @@ -32,7 +29,7 @@ func New(exec utilexec.Interface) *client { } func (c *client) GetEndpointState() (*api.AzureCNIState, error) { - cmd := c.exec.Command(azureVnetExecutable) + cmd := c.exec.Command(platform.CNIBinaryPath) envs := os.Environ() cmdenv := fmt.Sprintf("%s=%s", cni.Cmd, cni.CmdGetEndpointsState) @@ -54,7 +51,7 @@ func (c *client) GetEndpointState() (*api.AzureCNIState, error) { } func (c *client) GetVersion() (*semver.Version, error) { - cmd := c.exec.Command(azureVnetExecutable, "-v") + cmd := c.exec.Command(platform.CNIBinaryPath, "-v") output, err := cmd.CombinedOutput() if err != nil { diff --git a/cns/cnireconciler/statefile.go b/cns/cnireconciler/statefile.go index 5dcc128a46..58649b1b57 100644 --- a/cns/cnireconciler/statefile.go +++ b/cns/cnireconciler/statefile.go @@ -6,6 +6,7 @@ import ( "os" "github.com/Azure/azure-container-networking/cns/logger" + "github.com/Azure/azure-container-networking/platform" ) // WriteObjectToCNIStatefile checks for a file at the CNI statefile path, @@ -18,7 +19,7 @@ import ( // empty file on the host filesystem, crashing older CNI because it doesn't know // how to handle empty statefiles. func WriteObjectToCNIStatefile() error { - filename := "/var/run/azure-vnet.json" + filename := platform.CNIStateFilePath return writeObjectToFile(filename) } diff --git a/cns/configuration/configuration.go b/cns/configuration/configuration.go index 382bed1613..b1414a2fc7 100644 --- a/cns/configuration/configuration.go +++ b/cns/configuration/configuration.go @@ -66,7 +66,12 @@ type ManagedSettings struct { NodeSyncIntervalInSeconds int } -func getConfigFilePath() (string, error) { +func getConfigFilePath(cmdLineConfigPath string) (string, error) { + // If config path is set from cmd line, return that + if cmdLineConfigPath != "" { + return cmdLineConfigPath, nil + } + // Check if env set for config path otherwise use default path configpath, found := os.LookupEnv(EnvCNSConfig) if !found { @@ -80,8 +85,8 @@ func getConfigFilePath() (string, error) { } // ReadConfig returns a CNS config from file or an error. -func ReadConfig() (*CNSConfig, error) { - configpath, err := getConfigFilePath() +func ReadConfig(cmdLineConfigPath string) (*CNSConfig, error) { + configpath, err := getConfigFilePath(cmdLineConfigPath) if err != nil { return nil, err } diff --git a/cns/configuration/configuration_test.go b/cns/configuration/configuration_test.go index bb984fd429..eee4c61b99 100644 --- a/cns/configuration/configuration_test.go +++ b/cns/configuration/configuration_test.go @@ -14,15 +14,20 @@ func TestGetConfigFilePath(t *testing.T) { execpath, _ := common.GetExecutableDirectory() // env unset - f, err := getConfigFilePath() + f, err := getConfigFilePath("") assert.NoError(t, err) assert.Equal(t, filepath.Join(execpath, defaultConfigName), f) // env set os.Setenv(EnvCNSConfig, "test.cfg") - f, err = getConfigFilePath() + f, err = getConfigFilePath("") assert.NoError(t, err) assert.Equal(t, "test.cfg", f) + + // test with cmdline config path + f, err = getConfigFilePath("/var/lib/cns_config.json") + assert.NoError(t, err) + assert.Equal(t, "/var/lib/cns_config.json", f) } func TestReadConfigFromFile(t *testing.T) { diff --git a/cns/restserver/util.go b/cns/restserver/util.go index c06e37ac2c..b79df2be57 100644 --- a/cns/restserver/util.go +++ b/cns/restserver/util.go @@ -449,7 +449,7 @@ func (service *HTTPRestService) getNetworkContainerResponse( func (service *HTTPRestService) restoreNetworkState() error { logger.Printf("[Azure CNS] Enter Restoring Network State") - if service.store == nil { + if service.store == nil || !service.store.Exists() { logger.Printf("[Azure CNS] Store is not initialized, nothing to restore for network state.") return nil } diff --git a/cns/service/main.go b/cns/service/main.go index 09672bac3c..e59ce49e4e 100644 --- a/cns/service/main.go +++ b/cns/service/main.go @@ -251,6 +251,13 @@ var args = acn.ArgumentList{ Type: "string", DefaultValue: "", }, + { + Name: acn.OptCNSConfigPath, + Shorthand: acn.OptCNSConfigPathAlias, + Description: "File path to the cns config file", + Type: "string", + DefaultValue: "", + }, } // init() is executed before main() whenever this package is imported @@ -385,6 +392,7 @@ func main() { nodeID := acn.GetArg(acn.OptNodeID).(string) clientDebugCmd := acn.GetArg(acn.OptDebugCmd).(string) clientDebugArg := acn.GetArg(acn.OptDebugArg).(string) + cmdLineConfigPath := acn.GetArg(acn.OptCNSConfigPath).(string) if vers { printVersion() @@ -418,7 +426,7 @@ func main() { logger.Errorf("[Azure CNS] Cannot disable telemetry via cmdline. Update cns_config.json to disable telemetry.") } - cnsconfig, err := configuration.ReadConfig() + cnsconfig, err := configuration.ReadConfig(cmdLineConfigPath) if err != nil { logger.Errorf("[Azure CNS] Error reading cns config: %v", err) } diff --git a/common/config.go b/common/config.go index 024349a4ce..b1e7b199e6 100644 --- a/common/config.go +++ b/common/config.go @@ -122,4 +122,8 @@ const ( // Client mode, args for cmd OptDebugArg = "debugarg" OptDebugArgAlias = "darg" + + // CNS config path + OptCNSConfigPath = "config-path" + OptCNSConfigPathAlias = "cp" ) diff --git a/platform/os_linux.go b/platform/os_linux.go index cc2417769f..0403ea422b 100644 --- a/platform/os_linux.go +++ b/platform/os_linux.go @@ -21,6 +21,10 @@ const ( CNIRuntimePath = "/var/run/" // CNILockPath is the path where CNI lock files are stored. CNILockPath = "/var/run/azure-vnet/" + // CNIStateFilePath is the path to the CNI state file + CNIStateFilePath = "/var/run/azure-vnet.json" + // CNIBinaryPath is the path to the CNI binary + CNIBinaryPath = "/opt/cni/bin/azure-vnet" // CNSRuntimePath is the path where CNS state files are stored. CNSRuntimePath = "/var/run/" // CNI runtime path on a Kubernetes cluster diff --git a/platform/os_windows.go b/platform/os_windows.go index 811bc7fd2b..38652396dd 100644 --- a/platform/os_windows.go +++ b/platform/os_windows.go @@ -26,6 +26,12 @@ const ( // CNILockPath is the path where CNI lock files are stored. CNILockPath = "" + // CNIStateFilePath is the path to the CNI state file + CNIStateFilePath = "C:\\k\\azure-vnet.json" + + // CNIBinaryPath is the path to the CNI binary + CNIBinaryPath = "C:\\k\\azurecni\\bin\\azure-vnet.exe" + // CNI runtime path on a Kubernetes cluster K8SCNIRuntimePath = "C:\\k\\azurecni\\bin" diff --git a/store/json.go b/store/json.go index ff0552d58f..5e2711014c 100644 --- a/store/json.go +++ b/store/json.go @@ -54,6 +54,13 @@ func NewJsonFileStore(fileName string, lockclient processlock.Interface) (KeyVal return kvs, nil } +func (kvs *jsonFileStore) Exists() bool { + if _, err := os.Stat(kvs.fileName); err != nil { + return false + } + return true +} + // Read restores the value for the given key from persistent store. func (kvs *jsonFileStore) Read(key string, value interface{}) error { kvs.Mutex.Lock() diff --git a/store/mockstore.go b/store/mockstore.go index c3acfff2af..4077510d6b 100644 --- a/store/mockstore.go +++ b/store/mockstore.go @@ -15,6 +15,10 @@ func NewMockStore(lockFilePath string) KeyValueStore { } } +func (ms *mockStore) Exists() bool { + return false +} + // Read restores the value for the given key from persistent store. func (ms *mockStore) Read(key string, value interface{}) error { return nil diff --git a/store/store.go b/store/store.go index 0408310925..73b9e3fc72 100644 --- a/store/store.go +++ b/store/store.go @@ -10,6 +10,7 @@ import ( // KeyValueStore represents a persistent store of (key,value) pairs. type KeyValueStore interface { + Exists() bool Read(key string, value interface{}) error Write(key string, value interface{}) error Flush() error diff --git a/testutils/store_mock.go b/testutils/store_mock.go index 5ddd66f9a5..27015ee388 100644 --- a/testutils/store_mock.go +++ b/testutils/store_mock.go @@ -12,6 +12,7 @@ import ( var _ store.KeyValueStore = (*KeyValueStoreMock)(nil) type KeyValueStoreMock struct { + ExistsBool bool ReadError error WriteError error FlushError error @@ -21,8 +22,12 @@ type KeyValueStoreMock struct { GetModificationTimeError error } -func (mockst *KeyValueStoreMock) Read(key string, value interface{}) error { - return mockst.ReadError +func (store *KeyValueStoreMock) Exists() bool { + return store.ExistsBool +} + +func (store *KeyValueStoreMock) Read(key string, value interface{}) error { + return store.ReadError } func (mockst *KeyValueStoreMock) Write(key string, value interface{}) error { From dd1a9369c6ebfa380a7dddc0710313f0254ea965 Mon Sep 17 00:00:00 2001 From: Paul Johnston Date: Wed, 17 Nov 2021 12:43:42 -0800 Subject: [PATCH 2/4] Rename File Path to cns config to path to cns config --- cns/service/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cns/service/main.go b/cns/service/main.go index e59ce49e4e..ec3f1f2c2f 100644 --- a/cns/service/main.go +++ b/cns/service/main.go @@ -254,7 +254,7 @@ var args = acn.ArgumentList{ { Name: acn.OptCNSConfigPath, Shorthand: acn.OptCNSConfigPathAlias, - Description: "File path to the cns config file", + Description: "Path to cns config file", Type: "string", DefaultValue: "", }, From 868dcf5af187071003f214d928035fb2bfc82b53 Mon Sep 17 00:00:00 2001 From: Paul Johnston Date: Thu, 18 Nov 2021 12:24:10 -0800 Subject: [PATCH 3/4] feat: made changes according to TM --- cns/restserver/util.go | 7 ++++++- cns/service/main.go | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/cns/restserver/util.go b/cns/restserver/util.go index b79df2be57..c5835eeb98 100644 --- a/cns/restserver/util.go +++ b/cns/restserver/util.go @@ -449,11 +449,16 @@ func (service *HTTPRestService) getNetworkContainerResponse( func (service *HTTPRestService) restoreNetworkState() error { logger.Printf("[Azure CNS] Enter Restoring Network State") - if service.store == nil || !service.store.Exists() { + if service.store == nil { logger.Printf("[Azure CNS] Store is not initialized, nothing to restore for network state.") return nil } + if !service.store.Exists() { + logger.Printf("[Azure CNS] Store does not exist, nothing to restore for network state.") + return nil + } + rebooted := false modTime, err := service.store.GetModificationTime() diff --git a/cns/service/main.go b/cns/service/main.go index ec3f1f2c2f..06b8749b9b 100644 --- a/cns/service/main.go +++ b/cns/service/main.go @@ -426,6 +426,7 @@ func main() { logger.Errorf("[Azure CNS] Cannot disable telemetry via cmdline. Update cns_config.json to disable telemetry.") } + logger.Printf("[Azure CNS] cmdLineConfigPath: %s", cmdLineConfigPath) cnsconfig, err := configuration.ReadConfig(cmdLineConfigPath) if err != nil { logger.Errorf("[Azure CNS] Error reading cns config: %v", err) From 29b162736c952e4d72fe9ae20d72f98fba08adbc Mon Sep 17 00:00:00 2001 From: Paul Johnston Date: Thu, 18 Nov 2021 12:42:36 -0800 Subject: [PATCH 4/4] Fixing lint hopefully --- testutils/store_mock.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/testutils/store_mock.go b/testutils/store_mock.go index 27015ee388..cead32138c 100644 --- a/testutils/store_mock.go +++ b/testutils/store_mock.go @@ -22,12 +22,12 @@ type KeyValueStoreMock struct { GetModificationTimeError error } -func (store *KeyValueStoreMock) Exists() bool { - return store.ExistsBool +func (mockst *KeyValueStoreMock) Exists() bool { + return mockst.ExistsBool } -func (store *KeyValueStoreMock) Read(key string, value interface{}) error { - return store.ReadError +func (mockst *KeyValueStoreMock) Read(key string, value interface{}) error { + return mockst.ReadError } func (mockst *KeyValueStoreMock) Write(key string, value interface{}) error {