Browse Source

support local.conf files with no [[local]] section yet

Previously if we tried to added content to a local.conf file without a
local section, we actually inserted that content in the wrong place at
the end of the file. This fixes that, with unit tests.

Change-Id: Ib886d78ce5f3718def784db59ba9abf41bdb0e7b
tags/0.3.0^0
Sean Dague 2 years ago
parent
commit
c5626f3b4b
2 changed files with 74 additions and 4 deletions
  1. 35
    4
      devstack/dsconf.py
  2. 39
    0
      devstack/tests/test_localconf_set_local.py

+ 35
- 4
devstack/dsconf.py View File

@@ -175,6 +175,12 @@ class LocalConf(object):
175 175
                 if in_section:
176 176
                     yield line
177 177
 
178
+    def _has_local_section(self):
179
+        for group in self.groups():
180
+            if group == ("local", "localrc"):
181
+                return True
182
+        return False
183
+
178 184
     def extract(self, group, conf, target):
179 185
         ini_file = IniFile(target)
180 186
         for section, name, value in self._conf(group, conf):
@@ -186,9 +192,28 @@ class LocalConf(object):
186 192
                 f.write(line)
187 193
 
188 194
     def _at_insert_point_local(self, name, func):
195
+        """Run function when we are at the right insertion point in file.
196
+
197
+        This lets us process an arbitrary file and insert content at
198
+        the correct point. It has a few different state flags that we
199
+        are looking for.
200
+
201
+        Does this file have a local section at all? If not, we need to
202
+        write one early in the file (this means we work with an empty
203
+        file, as well as a file that has only post-config sections.
204
+
205
+        Are we currently in a local section, if so, we need to write
206
+        out content to the end, because items added to local always
207
+        have to be added at the end.
208
+
209
+        Did we write out the work that we expected? If so, just blast
210
+        all lines to the end of the file.
211
+
212
+        """
189 213
         temp = tempfile.NamedTemporaryFile(mode='r')
190 214
         shutil.copyfile(self.fname, temp.name)
191
-        in_meta = False
215
+        in_local = False
216
+        has_local = self._has_local_section()
192 217
         done = False
193 218
         with open(self.fname, "w+") as writer:
194 219
             with open(temp.name) as reader:
@@ -198,11 +223,17 @@ class LocalConf(object):
198 223
                         continue
199 224
 
200 225
                     if re.match(re.escape("[[local|localrc]]"), line):
201
-                        in_meta = True
202
-                    elif in_meta and re.match(re.escape("[["), line):
226
+                        in_local = True
227
+                    elif in_local and re.match(re.escape("[["), line):
203 228
                         func(writer, None)
204 229
                         done = True
205
-                        in_meta = False
230
+                        in_local = False
231
+                    elif not has_local and re.match(re.escape("[["), line):
232
+                        writer.write("[[local|localrc]]\n")
233
+                        func(writer, None)
234
+                        done = True
235
+                        in_local = False
236
+                        has_local = True
206 237
 
207 238
                     # otherwise, just write what we found
208 239
                     writer.write(line)

+ 39
- 0
devstack/tests/test_localconf_set_local.py View File

@@ -35,6 +35,15 @@ global_physnet_mtu=1450
35 35
 compute = auto
36 36
 """
37 37
 
38
+BASIC_NO_LOCAL = """
39
+[[post-config|$NEUTRON_CONF]]
40
+[DEFAULT]
41
+global_physnet_mtu=1450
42
+[[post-config|$NOVA_CONF]]
43
+[upgrade_levels]
44
+compute = auto
45
+"""
46
+
38 47
 RESULT1 = """
39 48
 [[local|localrc]]
40 49
 a=b
@@ -78,6 +87,18 @@ global_physnet_mtu=1450
78 87
 compute = auto
79 88
 """
80 89
 
90
+RESULT_NO_LOCAL = """
91
+[[local|localrc]]
92
+a=b
93
+c=d
94
+[[post-config|$NEUTRON_CONF]]
95
+[DEFAULT]
96
+global_physnet_mtu=1450
97
+[[post-config|$NOVA_CONF]]
98
+[upgrade_levels]
99
+compute = auto
100
+"""
101
+
81 102
 
82 103
 class TestLcSet(testtools.TestCase):
83 104
 
@@ -117,3 +138,21 @@ class TestLcSet(testtools.TestCase):
117 138
         with open(self._path) as f:
118 139
             content = f.read()
119 140
             self.assertEqual(content, RESULT3)
141
+
142
+
143
+class TestNoLocal(testtools.TestCase):
144
+
145
+    def setUp(self):
146
+        super(TestNoLocal, self).setUp()
147
+        self._path = self.useFixture(fixtures.TempDir()).path
148
+        self._path += "/local.conf"
149
+        with open(self._path, "w") as f:
150
+            f.write(BASIC_NO_LOCAL)
151
+
152
+    def test_set_new(self):
153
+        conf = dsconf.LocalConf(self._path)
154
+        conf.set_local("a=b")
155
+        conf.set_local("c=d")
156
+        with open(self._path) as f:
157
+            content = f.read()
158
+            self.assertEqual(content, RESULT_NO_LOCAL)

Loading…
Cancel
Save