Statistics
| Branch: | Tag: | Revision:

root / test / py / cfgupgrade_unittest.py @ d01e51a5

History | View | Annotate | Download (14.9 kB)

1
#!/usr/bin/python
2
#
3

    
4
# Copyright (C) 2010, 2012, 2013 Google Inc.
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License as published by
8
# the Free Software Foundation; either version 2 of the License, or
9
# (at your option) any later version.
10
#
11
# This program is distributed in the hope that it will be useful, but
12
# WITHOUT ANY WARRANTY; without even the implied warranty of
13
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
# General Public License for more details.
15
#
16
# You should have received a copy of the GNU General Public License
17
# along with this program; if not, write to the Free Software
18
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
# 02110-1301, USA.
20

    
21

    
22
"""Script for testing tools/cfgupgrade"""
23

    
24
import os
25
import sys
26
import unittest
27
import shutil
28
import tempfile
29
import operator
30

    
31
from ganeti import constants
32
from ganeti import utils
33
from ganeti import errors
34
from ganeti import serializer
35
from ganeti import netutils
36

    
37
import testutils
38

    
39

    
40
def _RunUpgrade(path, dry_run, no_verify, ignore_hostname=True,
41
                downgrade=False):
42
  cmd = [sys.executable, "%s/tools/cfgupgrade" % testutils.GetSourceDir(),
43
         "--debug", "--force", "--path=%s" % path, "--confdir=%s" % path]
44

    
45
  if ignore_hostname:
46
    cmd.append("--ignore-hostname")
47
  if dry_run:
48
    cmd.append("--dry-run")
49
  if no_verify:
50
    cmd.append("--no-verify")
51
  if downgrade:
52
    cmd.append("--downgrade")
53

    
54
  result = utils.RunCmd(cmd, cwd=os.getcwd())
55
  if result.failed:
56
    raise Exception("cfgupgrade failed: %s, output %r" %
57
                    (result.fail_reason, result.output))
58

    
59

    
60
class TestCfgupgrade(unittest.TestCase):
61
  def setUp(self):
62
    self.tmpdir = tempfile.mkdtemp()
63

    
64
    self.config_path = utils.PathJoin(self.tmpdir, "config.data")
65
    self.noded_cert_path = utils.PathJoin(self.tmpdir, "server.pem")
66
    self.rapi_cert_path = utils.PathJoin(self.tmpdir, "rapi.pem")
67
    self.rapi_users_path = utils.PathJoin(self.tmpdir, "rapi", "users")
68
    self.rapi_users_path_pre24 = utils.PathJoin(self.tmpdir, "rapi_users")
69
    self.known_hosts_path = utils.PathJoin(self.tmpdir, "known_hosts")
70
    self.confd_hmac_path = utils.PathJoin(self.tmpdir, "hmac.key")
71
    self.cds_path = utils.PathJoin(self.tmpdir, "cluster-domain-secret")
72
    self.ss_master_node_path = utils.PathJoin(self.tmpdir, "ssconf_master_node")
73
    self.file_storage_paths = utils.PathJoin(self.tmpdir, "file-storage-paths")
74

    
75
  def tearDown(self):
76
    shutil.rmtree(self.tmpdir)
77

    
78
  def _LoadConfig(self):
79
    return serializer.LoadJson(utils.ReadFile(self.config_path))
80

    
81
  def _CreateValidConfigDir(self):
82
    utils.WriteFile(self.noded_cert_path, data="")
83
    utils.WriteFile(self.known_hosts_path, data="")
84
    utils.WriteFile(self.ss_master_node_path,
85
                    data="node.has.another.name.example.net")
86

    
87
  def testNoConfigDir(self):
88
    self.assertFalse(utils.ListVisibleFiles(self.tmpdir))
89
    self.assertRaises(Exception, _RunUpgrade, self.tmpdir, False, True)
90
    self.assertRaises(Exception, _RunUpgrade, self.tmpdir, True, True)
91

    
92
  def testWrongHostname(self):
93
    self._CreateValidConfigDir()
94

    
95
    utils.WriteFile(self.config_path, data=serializer.DumpJson({
96
      "version": constants.CONFIG_VERSION,
97
      "cluster": {},
98
      "instances": {},
99
      "nodegroups": {},
100
      }))
101

    
102
    hostname = netutils.GetHostname().name
103
    assert hostname != utils.ReadOneLineFile(self.ss_master_node_path)
104

    
105
    self.assertRaises(Exception, _RunUpgrade, self.tmpdir, False, True,
106
                      ignore_hostname=False)
107

    
108
  def testCorrectHostname(self):
109
    self._CreateValidConfigDir()
110

    
111
    utils.WriteFile(self.config_path, data=serializer.DumpJson({
112
      "version": constants.CONFIG_VERSION,
113
      "cluster": {},
114
      "instances": {},
115
      "nodegroups": {},
116
      }))
117

    
118
    utils.WriteFile(self.ss_master_node_path,
119
                    data="%s\n" % netutils.GetHostname().name)
120

    
121
    _RunUpgrade(self.tmpdir, False, True, ignore_hostname=False)
122

    
123
  def testInconsistentConfig(self):
124
    self._CreateValidConfigDir()
125
    # There should be no "config_version"
126
    cfg = {
127
      "version": 0,
128
      "cluster": {
129
        "config_version": 0,
130
        },
131
      "instances": {},
132
      "nodegroups": {},
133
      }
134
    utils.WriteFile(self.config_path, data=serializer.DumpJson(cfg))
135
    self.assertRaises(Exception, _RunUpgrade, self.tmpdir, False, True)
136

    
137
  def testInvalidConfig(self):
138
    self._CreateValidConfigDir()
139
    # Missing version from config
140
    utils.WriteFile(self.config_path, data=serializer.DumpJson({}))
141
    self.assertRaises(Exception, _RunUpgrade, self.tmpdir, False, True)
142

    
143
  def _TestSimpleUpgrade(self, from_version, dry_run,
144
                         file_storage_dir=None,
145
                         shared_file_storage_dir=None):
146
    cluster = {}
147

    
148
    if file_storage_dir:
149
      cluster["file_storage_dir"] = file_storage_dir
150
    if shared_file_storage_dir:
151
      cluster["shared_file_storage_dir"] = shared_file_storage_dir
152

    
153
    cfg = {
154
      "version": from_version,
155
      "cluster": cluster,
156
      "instances": {},
157
      "nodegroups": {},
158
      }
159
    self._CreateValidConfigDir()
160
    utils.WriteFile(self.config_path, data=serializer.DumpJson(cfg))
161

    
162
    self.assertFalse(os.path.isfile(self.rapi_cert_path))
163
    self.assertFalse(os.path.isfile(self.confd_hmac_path))
164
    self.assertFalse(os.path.isfile(self.cds_path))
165

    
166
    _RunUpgrade(self.tmpdir, dry_run, True)
167

    
168
    if dry_run:
169
      expversion = from_version
170
      checkfn = operator.not_
171
    else:
172
      expversion = constants.CONFIG_VERSION
173
      checkfn = operator.truth
174

    
175
    self.assert_(checkfn(os.path.isfile(self.rapi_cert_path)))
176
    self.assert_(checkfn(os.path.isfile(self.confd_hmac_path)))
177
    self.assert_(checkfn(os.path.isfile(self.cds_path)))
178

    
179
    newcfg = self._LoadConfig()
180
    self.assertEqual(newcfg["version"], expversion)
181

    
182
  def testRapiUsers(self):
183
    self.assertFalse(os.path.exists(self.rapi_users_path))
184
    self.assertFalse(os.path.exists(self.rapi_users_path_pre24))
185
    self.assertFalse(os.path.exists(os.path.dirname(self.rapi_users_path)))
186

    
187
    utils.WriteFile(self.rapi_users_path_pre24, data="some user\n")
188
    self._TestSimpleUpgrade(constants.BuildVersion(2, 3, 0), False)
189

    
190
    self.assertTrue(os.path.isdir(os.path.dirname(self.rapi_users_path)))
191
    self.assert_(os.path.islink(self.rapi_users_path_pre24))
192
    self.assert_(os.path.isfile(self.rapi_users_path))
193
    self.assertEqual(os.readlink(self.rapi_users_path_pre24),
194
                     self.rapi_users_path)
195
    for path in [self.rapi_users_path, self.rapi_users_path_pre24]:
196
      self.assertEqual(utils.ReadFile(path), "some user\n")
197

    
198
  def testRapiUsers24AndAbove(self):
199
    self.assertFalse(os.path.exists(self.rapi_users_path))
200
    self.assertFalse(os.path.exists(self.rapi_users_path_pre24))
201

    
202
    os.mkdir(os.path.dirname(self.rapi_users_path))
203
    utils.WriteFile(self.rapi_users_path, data="other user\n")
204
    self._TestSimpleUpgrade(constants.BuildVersion(2, 3, 0), False)
205

    
206
    self.assert_(os.path.islink(self.rapi_users_path_pre24))
207
    self.assert_(os.path.isfile(self.rapi_users_path))
208
    self.assertEqual(os.readlink(self.rapi_users_path_pre24),
209
                     self.rapi_users_path)
210
    for path in [self.rapi_users_path, self.rapi_users_path_pre24]:
211
      self.assertEqual(utils.ReadFile(path), "other user\n")
212

    
213
  def testRapiUsersExistingSymlink(self):
214
    self.assertFalse(os.path.exists(self.rapi_users_path))
215
    self.assertFalse(os.path.exists(self.rapi_users_path_pre24))
216

    
217
    os.mkdir(os.path.dirname(self.rapi_users_path))
218
    os.symlink(self.rapi_users_path, self.rapi_users_path_pre24)
219
    utils.WriteFile(self.rapi_users_path, data="hello world\n")
220

    
221
    self._TestSimpleUpgrade(constants.BuildVersion(2, 2, 0), False)
222

    
223
    self.assert_(os.path.isfile(self.rapi_users_path) and
224
                 not os.path.islink(self.rapi_users_path))
225
    self.assert_(os.path.islink(self.rapi_users_path_pre24))
226
    self.assertEqual(os.readlink(self.rapi_users_path_pre24),
227
                     self.rapi_users_path)
228
    for path in [self.rapi_users_path, self.rapi_users_path_pre24]:
229
      self.assertEqual(utils.ReadFile(path), "hello world\n")
230

    
231
  def testRapiUsersExistingTarget(self):
232
    self.assertFalse(os.path.exists(self.rapi_users_path))
233
    self.assertFalse(os.path.exists(self.rapi_users_path_pre24))
234

    
235
    os.mkdir(os.path.dirname(self.rapi_users_path))
236
    utils.WriteFile(self.rapi_users_path, data="other user\n")
237
    utils.WriteFile(self.rapi_users_path_pre24, data="hello world\n")
238

    
239
    self.assertRaises(Exception, self._TestSimpleUpgrade,
240
                      constants.BuildVersion(2, 2, 0), False)
241

    
242
    for path in [self.rapi_users_path, self.rapi_users_path_pre24]:
243
      self.assert_(os.path.isfile(path) and not os.path.islink(path))
244
    self.assertEqual(utils.ReadFile(self.rapi_users_path), "other user\n")
245
    self.assertEqual(utils.ReadFile(self.rapi_users_path_pre24),
246
                     "hello world\n")
247

    
248
  def testRapiUsersDryRun(self):
249
    self.assertFalse(os.path.exists(self.rapi_users_path))
250
    self.assertFalse(os.path.exists(self.rapi_users_path_pre24))
251

    
252
    utils.WriteFile(self.rapi_users_path_pre24, data="some user\n")
253
    self._TestSimpleUpgrade(constants.BuildVersion(2, 3, 0), True)
254

    
255
    self.assertFalse(os.path.isdir(os.path.dirname(self.rapi_users_path)))
256
    self.assertTrue(os.path.isfile(self.rapi_users_path_pre24) and
257
                    not os.path.islink(self.rapi_users_path_pre24))
258
    self.assertFalse(os.path.exists(self.rapi_users_path))
259

    
260
  def testRapiUsers24AndAboveDryRun(self):
261
    self.assertFalse(os.path.exists(self.rapi_users_path))
262
    self.assertFalse(os.path.exists(self.rapi_users_path_pre24))
263

    
264
    os.mkdir(os.path.dirname(self.rapi_users_path))
265
    utils.WriteFile(self.rapi_users_path, data="other user\n")
266
    self._TestSimpleUpgrade(constants.BuildVersion(2, 3, 0), True)
267

    
268
    self.assertTrue(os.path.isfile(self.rapi_users_path) and
269
                    not os.path.islink(self.rapi_users_path))
270
    self.assertFalse(os.path.exists(self.rapi_users_path_pre24))
271
    self.assertEqual(utils.ReadFile(self.rapi_users_path), "other user\n")
272

    
273
  def testRapiUsersExistingSymlinkDryRun(self):
274
    self.assertFalse(os.path.exists(self.rapi_users_path))
275
    self.assertFalse(os.path.exists(self.rapi_users_path_pre24))
276

    
277
    os.mkdir(os.path.dirname(self.rapi_users_path))
278
    os.symlink(self.rapi_users_path, self.rapi_users_path_pre24)
279
    utils.WriteFile(self.rapi_users_path, data="hello world\n")
280

    
281
    self._TestSimpleUpgrade(constants.BuildVersion(2, 2, 0), True)
282

    
283
    self.assertTrue(os.path.islink(self.rapi_users_path_pre24))
284
    self.assertTrue(os.path.isfile(self.rapi_users_path) and
285
                    not os.path.islink(self.rapi_users_path))
286
    self.assertEqual(os.readlink(self.rapi_users_path_pre24),
287
                     self.rapi_users_path)
288
    for path in [self.rapi_users_path, self.rapi_users_path_pre24]:
289
      self.assertEqual(utils.ReadFile(path), "hello world\n")
290

    
291
  def testFileStoragePathsDryRun(self):
292
    self.assertFalse(os.path.exists(self.file_storage_paths))
293

    
294
    self._TestSimpleUpgrade(constants.BuildVersion(2, 6, 0), True,
295
                            file_storage_dir=self.tmpdir,
296
                            shared_file_storage_dir="/tmp")
297

    
298
    self.assertFalse(os.path.exists(self.file_storage_paths))
299

    
300
  def testFileStoragePathsBoth(self):
301
    self.assertFalse(os.path.exists(self.file_storage_paths))
302

    
303
    self._TestSimpleUpgrade(constants.BuildVersion(2, 6, 0), False,
304
                            file_storage_dir=self.tmpdir,
305
                            shared_file_storage_dir="/tmp")
306

    
307
    lines = utils.ReadFile(self.file_storage_paths).splitlines()
308
    self.assertTrue(lines.pop(0).startswith("# "))
309
    self.assertTrue(lines.pop(0).startswith("# cfgupgrade"))
310
    self.assertEqual(lines.pop(0), self.tmpdir)
311
    self.assertEqual(lines.pop(0), "/tmp")
312
    self.assertFalse(lines)
313
    self.assertEqual(os.stat(self.file_storage_paths).st_mode & 0777,
314
                     0600, msg="Wrong permissions")
315

    
316
  def testFileStoragePathsSharedOnly(self):
317
    self.assertFalse(os.path.exists(self.file_storage_paths))
318

    
319
    self._TestSimpleUpgrade(constants.BuildVersion(2, 5, 0), False,
320
                            file_storage_dir=None,
321
                            shared_file_storage_dir=self.tmpdir)
322

    
323
    lines = utils.ReadFile(self.file_storage_paths).splitlines()
324
    self.assertTrue(lines.pop(0).startswith("# "))
325
    self.assertTrue(lines.pop(0).startswith("# cfgupgrade"))
326
    self.assertEqual(lines.pop(0), self.tmpdir)
327
    self.assertFalse(lines)
328

    
329
  def testUpgradeFrom_2_0(self):
330
    self._TestSimpleUpgrade(constants.BuildVersion(2, 0, 0), False)
331

    
332
  def testUpgradeFrom_2_1(self):
333
    self._TestSimpleUpgrade(constants.BuildVersion(2, 1, 0), False)
334

    
335
  def testUpgradeFrom_2_2(self):
336
    self._TestSimpleUpgrade(constants.BuildVersion(2, 2, 0), False)
337

    
338
  def testUpgradeFrom_2_3(self):
339
    self._TestSimpleUpgrade(constants.BuildVersion(2, 3, 0), False)
340

    
341
  def testUpgradeFrom_2_4(self):
342
    self._TestSimpleUpgrade(constants.BuildVersion(2, 4, 0), False)
343

    
344
  def testUpgradeFrom_2_5(self):
345
    self._TestSimpleUpgrade(constants.BuildVersion(2, 5, 0), False)
346

    
347
  def testUpgradeFrom_2_6(self):
348
    self._TestSimpleUpgrade(constants.BuildVersion(2, 6, 0), False)
349

    
350
  def testUpgradeCurrent(self):
351
    self._TestSimpleUpgrade(constants.CONFIG_VERSION, False)
352

    
353
  def testDowngrade(self):
354
    self._TestSimpleUpgrade(constants.CONFIG_VERSION, False)
355
    oldconf = self._LoadConfig()
356
    _RunUpgrade(self.tmpdir, False, True, downgrade=True)
357
    _RunUpgrade(self.tmpdir, False, True)
358
    newconf = self._LoadConfig()
359
    self.assertEqual(oldconf, newconf)
360

    
361
  def testDowngradeTwice(self):
362
    self._TestSimpleUpgrade(constants.CONFIG_VERSION, False)
363
    _RunUpgrade(self.tmpdir, False, True, downgrade=True)
364
    oldconf = self._LoadConfig()
365
    _RunUpgrade(self.tmpdir, False, True, downgrade=True)
366
    newconf = self._LoadConfig()
367
    self.assertEqual(oldconf, newconf)
368

    
369
  def testUpgradeDryRunFrom_2_0(self):
370
    self._TestSimpleUpgrade(constants.BuildVersion(2, 0, 0), True)
371

    
372
  def testUpgradeDryRunFrom_2_1(self):
373
    self._TestSimpleUpgrade(constants.BuildVersion(2, 1, 0), True)
374

    
375
  def testUpgradeDryRunFrom_2_2(self):
376
    self._TestSimpleUpgrade(constants.BuildVersion(2, 2, 0), True)
377

    
378
  def testUpgradeDryRunFrom_2_3(self):
379
    self._TestSimpleUpgrade(constants.BuildVersion(2, 3, 0), True)
380

    
381
  def testUpgradeDryRunFrom_2_4(self):
382
    self._TestSimpleUpgrade(constants.BuildVersion(2, 4, 0), True)
383

    
384
  def testUpgradeDryRunFrom_2_5(self):
385
    self._TestSimpleUpgrade(constants.BuildVersion(2, 5, 0), True)
386

    
387
  def testUpgradeDryRunFrom_2_6(self):
388
    self._TestSimpleUpgrade(constants.BuildVersion(2, 6, 0), True)
389

    
390
  def testUpgradeCurrentDryRun(self):
391
    self._TestSimpleUpgrade(constants.CONFIG_VERSION, True)
392

    
393
  def testDowngradeDryRun(self):
394
    self._TestSimpleUpgrade(constants.CONFIG_VERSION, False)
395
    oldconf = self._LoadConfig()
396
    _RunUpgrade(self.tmpdir, True, True, downgrade=True)
397
    newconf = self._LoadConfig()
398
    self.assertEqual(oldconf["version"], newconf["version"])
399

    
400
if __name__ == "__main__":
401
  testutils.GanetiTestProgram()