From 782a9b7c28f79bc5e718819a3805da8df30210dc Mon Sep 17 00:00:00 2001 From: Travis Hall Date: Thu, 2 Nov 2017 16:27:26 -0400 Subject: [PATCH] Adds delete_data_dir_on_stop config option - This is so single-node etcd deployments can be restarted [#152475519] Signed-off-by: Brenda Chan Adds options to etcdfab config [#152475519] Signed-off-by: Travis Hall --- jobs/etcd/spec | 4 ++ jobs/etcd/templates/etcdfab.json.erb | 1 + src/etcdfab/application/application.go | 4 +- src/etcdfab/application/application_test.go | 67 +++++++++++++++++++++ src/etcdfab/config/config.go | 9 ++- src/etcdfab/config/config_test.go | 10 +++ 6 files changed, 92 insertions(+), 3 deletions(-) diff --git a/jobs/etcd/spec b/jobs/etcd/spec index c06f52c..34920d0 100644 --- a/jobs/etcd/spec +++ b/jobs/etcd/spec @@ -130,3 +130,7 @@ properties: etcd.enable_debug_logging: description: "Enables etcd's debug logging" default: false + + options.delete_data_dir_on_stop: + description: "Boolean flag to delete etcd data dir on application stop" + default: true diff --git a/jobs/etcd/templates/etcdfab.json.erb b/jobs/etcd/templates/etcdfab.json.erb index 7f3c016..e05b4a8 100644 --- a/jobs/etcd/templates/etcdfab.json.erb +++ b/jobs/etcd/templates/etcdfab.json.erb @@ -24,5 +24,6 @@ external_ip: discover_external_ip, }, etcd: p('etcd'), + options: p('options') }.to_json %> diff --git a/src/etcdfab/application/application.go b/src/etcdfab/application/application.go index 5758993..226743b 100644 --- a/src/etcdfab/application/application.go +++ b/src/etcdfab/application/application.go @@ -168,7 +168,9 @@ func (a Application) Stop() error { a.removeSelfFromCluster(cfg) } - a.removeDataDir(cfg) + if cfg.Options.DeleteDataDirOnStop == true { + a.removeDataDir(cfg) + } a.logger.Info("application.kill") err = a.kill(cfg.PidFile()) diff --git a/src/etcdfab/application/application_test.go b/src/etcdfab/application/application_test.go index 4cdb760..b4972e9 100644 --- a/src/etcdfab/application/application_test.go +++ b/src/etcdfab/application/application_test.go @@ -9,6 +9,7 @@ import ( "os" "path/filepath" "strconv" + "strings" "code.cloudfoundry.org/lager" @@ -684,6 +685,9 @@ var _ = Describe("Application", func() { "client_ip": "some-client-ip", "advertise_urls_dns_suffix": "some-dns-suffix", }, + "options": map[string]interface{}{ + "delete_data_dir_on_stop": true, + }, } configFileName = createConfig(tmpDir, "config-file", configuration) @@ -712,6 +716,9 @@ var _ = Describe("Application", func() { AdvertiseURLsDNSSuffix: "some-dns-suffix", Machines: []string{"some-ip-1", "some-ip-2"}, }, + Options: config.Options{ + DeleteDataDirOnStop: true, + }, } app = application.New(application.NewArgs{ @@ -822,6 +829,66 @@ var _ = Describe("Application", func() { }) }) + Context("If delete_data_dir_on_stop is set to true", func() { + BeforeEach(func() { + fileOut, err := os.Create(strings.Join([]string{dataDir, "foo"}, "/")) + Expect(err).NotTo(HaveOccurred()) + defer fileOut.Close() + + keepDataDirConfiguration := map[string]interface{}{ + "node": map[string]interface{}{ + "name": "some_name", + "index": 3, + "external_ip": "some-external-ip", + }, + "etcd": map[string]interface{}{ + "etcd_path": "path-to-etcd", + "cert_dir": "some/cert/dir", + "run_dir": runDir, + "data_dir": dataDir, + "heartbeat_interval_in_milliseconds": 10, + "election_timeout_in_milliseconds": 20, + "peer_require_ssl": false, + "peer_ip": "some-peer-ip", + "require_ssl": false, + "client_ip": "some-client-ip", + "advertise_urls_dns_suffix": "some-dns-suffix", + }, + "options": map[string]interface{}{ + "delete_data_dir_on_stop": false, + }, + } + + keepDataDirConfigFileName := createConfig(tmpDir, "config-file", keepDataDirConfiguration) + + app = application.New(application.NewArgs{ + Command: fakeCommand, + ConfigFilePath: keepDataDirConfigFileName, + LinkConfigFilePath: linkConfigFileName, + EtcdClient: fakeEtcdClient, + ClusterController: fakeClusterController, + SyncController: fakeSyncController, + OutWriter: &outWriter, + ErrWriter: &errWriter, + Logger: fakeLogger, + }) + }) + + It("stops etcd and doesn't clean up", func() { + err := app.Stop() + Expect(err).NotTo(HaveOccurred()) + + By("keeping the contents inside data dir", func() { + d, err := os.Open(dataDir) + Expect(err).NotTo(HaveOccurred()) + defer d.Close() + files, err := d.Readdirnames(-1) + Expect(err).NotTo(HaveOccurred()) + Expect(len(files)).ToNot(Equal(0)) + }) + }) + }) + Context("when it cannot read the config file", func() { BeforeEach(func() { app = application.New(application.NewArgs{ diff --git a/src/etcdfab/config/config.go b/src/etcdfab/config/config.go index 4d26c05..d0f1dda 100644 --- a/src/etcdfab/config/config.go +++ b/src/etcdfab/config/config.go @@ -37,9 +37,14 @@ type Etcd struct { EnableDebugLogging bool `json:"enable_debug_logging"` } +type Options struct { + DeleteDataDirOnStop bool `json:"delete_data_dir_on_stop"` +} + type Config struct { - Node Node - Etcd Etcd + Node Node + Etcd Etcd + Options Options } func defaultConfig() Config { diff --git a/src/etcdfab/config/config_test.go b/src/etcdfab/config/config_test.go index 83c20dc..42a33da 100644 --- a/src/etcdfab/config/config_test.go +++ b/src/etcdfab/config/config_test.go @@ -56,6 +56,9 @@ var _ = Describe("Config", func() { "advertise_urls_dns_suffix": "some-dns-suffix", "enable_debug_logging": true, }, + "options": map[string]interface{}{ + "delete_data_dir_on_stop": false, + }, } configFilePath = writeConfigurationFile(tmpDir, "config-file", configuration) @@ -101,6 +104,9 @@ var _ = Describe("Config", func() { Machines: []string{"some-ip-1", "some-ip-2", "some-ip-3"}, EnableDebugLogging: true, }, + Options: config.Options{ + DeleteDataDirOnStop: false, + }, })) }) @@ -134,6 +140,9 @@ var _ = Describe("Config", func() { AdvertiseURLsDNSSuffix: "some-dns-suffix", EnableDebugLogging: true, }, + Options: config.Options{ + DeleteDataDirOnStop: false, + }, })) }) }) @@ -152,6 +161,7 @@ var _ = Describe("Config", func() { Expect(cfg.Etcd.CertDir).To(Equal("/var/vcap/jobs/etcd/config/certs")) Expect(cfg.Etcd.RunDir).To(Equal("/var/vcap/sys/run/etcd")) Expect(cfg.Etcd.DataDir).To(Equal("/var/vcap/store/etcd")) + Expect(cfg.Options.DeleteDataDirOnStop).To(Equal(false)) }) Context("failure cases", func() {