Revision 4c5dd3ff

b/Makefile.am
684 684
	test/ganeti.runtime_unittest.py \
685 685
	test/ganeti.serializer_unittest.py \
686 686
	test/ganeti.ssh_unittest.py \
687
	test/ganeti.storage_unittest.py \
687 688
	test/ganeti.tools.ensure_dirs_unittest.py \
688 689
	test/ganeti.uidpool_unittest.py \
689 690
	test/ganeti.utils.algo_unittest.py \
......
1078 1079
	fi; \
1079 1080
	for file in doc/iallocator.rst doc/hooks.rst; do \
1080 1081
		if test "`sed -ne '4 p' $(top_srcdir)/$$file`" != \
1081
		        "Documents Ganeti version $$expver"; then \
1082
			"Documents Ganeti version $$expver"; then \
1082 1083
			echo "Incorrect version in $$file, expected $$expver"; \
1083 1084
			exit 1; \
1084 1085
		fi; \
b/lib/storage.py
1 1
#
2 2
#
3 3

  
4
# Copyright (C) 2009, 2011 Google Inc.
4
# Copyright (C) 2009, 2011, 2012 Google Inc.
5 5
#
6 6
# This program is free software; you can redistribute it and/or modify
7 7
# it under the terms of the GNU General Public License as published by
......
406 406

  
407 407
  """
408 408
  LIST_COMMAND = "vgs"
409
  VGREDUCE_COMMAND = "vgreduce"
409 410

  
410 411
  # Make sure to update constants.VALID_STORAGE_FIELDS when changing field
411 412
  # definitions.
......
418 419
    (constants.SF_ALLOCATABLE, [], True),
419 420
    ]
420 421

  
421
  def _RemoveMissing(self, name):
422
  def _RemoveMissing(self, name, _runcmd_fn=utils.RunCmd):
422 423
    """Runs "vgreduce --removemissing" on a volume group.
423 424

  
424 425
    @type name: string
......
428 429
    # Ignoring vgreduce exit code. Older versions exit with an error even tough
429 430
    # the VG is already consistent. This was fixed in later versions, but we
430 431
    # cannot depend on it.
431
    result = utils.RunCmd(["vgreduce", "--removemissing", name])
432
    result = _runcmd_fn([self.VGREDUCE_COMMAND, "--removemissing", name])
432 433

  
433 434
    # Keep output in case something went wrong
434 435
    vgreduce_output = result.output
435 436

  
436
    result = utils.RunCmd(["vgs", "--noheadings", "--nosuffix", name])
437
    if result.failed:
437
    # work around newer LVM version
438
    if ("Wrote out consistent volume group" not in vgreduce_output or
439
        "vgreduce --removemissing --force" in vgreduce_output):
440
      # we need to re-run with --force
441
      result = _runcmd_fn([self.VGREDUCE_COMMAND, "--removemissing",
442
                           "--force", name])
443
      vgreduce_output += "\n" + result.output
444

  
445
    result = _runcmd_fn([self.LIST_COMMAND, "--noheadings",
446
                         "--nosuffix", name])
447
    # we also need to check the output
448
    if result.failed or "Couldn't find device with uuid" in result.output:
438 449
      raise errors.StorageError(("Volume group '%s' still not consistent,"
439 450
                                 " 'vgreduce' output: %r,"
440 451
                                 " 'vgs' output: %r") %
b/test/data/vgreduce-removemissing-2.02.02.txt
1
  Couldn't find device with uuid 'gg4cmC-4lrT-EN1v-39OA-6S2b-6eEI-wWlJJJ'.
2
  Couldn't find all physical volumes for volume group xenvg.
3
  Couldn't find device with uuid 'gg4cmC-4lrT-EN1v-39OA-6S2b-6eEI-wWlJJJ'.
4
  Couldn't find all physical volumes for volume group xenvg.
5
  Couldn't find device with uuid 'gg4cmC-4lrT-EN1v-39OA-6S2b-6eEI-wWlJJJ'.
6
  Couldn't find device with uuid 'gg4cmC-4lrT-EN1v-39OA-6S2b-6eEI-wWlJJJ'.
7
  Wrote out consistent volume group xenvg
b/test/data/vgreduce-removemissing-2.02.66-fail.txt
1
  Couldn't find device with uuid bHRa26-svpL-ihJX-e0S4-2HNz-wAAi-AlBFtl.
2
  WARNING: Partial LV 4ba7abfa-8459-43b6-b00f-c016244980f0.disk0 needs to be repaired or removed. 
3
  WARNING: Partial LV e972960d-4e35-46b2-9cda-7029916b28c1.disk0_data needs to be repaired or removed. 
4
  WARNING: Partial LV e972960d-4e35-46b2-9cda-7029916b28c1.disk0_meta needs to be repaired or removed. 
5
  WARNING: Partial LV 4fa40b51-dd4d-4fd9-aef1-35cc3a0f1f11.disk0_data needs to be repaired or removed. 
6
  WARNING: Partial LV 4fa40b51-dd4d-4fd9-aef1-35cc3a0f1f11.disk0_meta needs to be repaired or removed. 
7
  WARNING: Partial LV 0a184b34-1270-4f1a-94df-86da2167cfee.disk0_data needs to be repaired or removed. 
8
  WARNING: Partial LV 0a184b34-1270-4f1a-94df-86da2167cfee.disk0_meta needs to be repaired or removed. 
9
  WARNING: Partial LV 7e49c8a9-9c65-4e76-810e-bd3d7a1d97a9.disk0_data needs to be repaired or removed. 
10
  WARNING: Partial LV 7e49c8a9-9c65-4e76-810e-bd3d7a1d97a9.disk0_meta needs to be repaired or removed. 
11
  WARNING: Partial LV 290a3fd4-c035-4fbe-9a18-f5a0889bd45d.disk0_data needs to be repaired or removed. 
12
  WARNING: Partial LV 290a3fd4-c035-4fbe-9a18-f5a0889bd45d.disk0_meta needs to be repaired or removed. 
13
  WARNING: Partial LV c579be32-c041-4f1b-ae3e-c58aac9c2593.disk0_data needs to be repaired or removed. 
14
  WARNING: Partial LV c579be32-c041-4f1b-ae3e-c58aac9c2593.disk0_meta needs to be repaired or removed. 
15
  WARNING: Partial LV 47524563-3788-4a89-a61f-4274134dea73.disk0_data needs to be repaired or removed. 
16
  WARNING: Partial LV 47524563-3788-4a89-a61f-4274134dea73.disk0_meta needs to be repaired or removed. 
17
  WARNING: Partial LV ede9f706-a0dc-4202-96f2-1728240bbf05.disk0_data needs to be repaired or removed. 
18
  WARNING: Partial LV ede9f706-a0dc-4202-96f2-1728240bbf05.disk0_meta needs to be repaired or removed. 
19
  WARNING: Partial LV 731d9f1b-3f2f-4860-85b3-217a36b9c48e.disk1_data needs to be repaired or removed. 
20
  WARNING: Partial LV 731d9f1b-3f2f-4860-85b3-217a36b9c48e.disk1_meta needs to be repaired or removed. 
21
  WARNING: Partial LV f449ccfd-4e6b-42d6-9a52-838371988ab5.disk0_data needs to be repaired or removed. 
22
  WARNING: Partial LV f449ccfd-4e6b-42d6-9a52-838371988ab5.disk0_meta needs to be repaired or removed. 
23
  WARNING: Partial LV 69bb4f61-fd0c-4c89-a57f-5285ae99b3bd.disk0_data needs to be repaired or removed. 
24
  WARNING: Partial LV 9c29c24a-97ed-4fc7-b479-7a3385365a71.disk0 needs to be repaired or removed. 
25
  WARNING: Partial LV a919d93e-0f51-4e4d-9018-e25ee7d5b36b.disk0 needs to be repaired or removed. 
26
  WARNING: Partial LV d2501e6b-56a4-43b6-8856-471e5d49e892.disk0_data needs to be repaired or removed. 
27
  WARNING: Partial LV d2501e6b-56a4-43b6-8856-471e5d49e892.disk0_meta needs to be repaired or removed. 
28
  WARNING: Partial LV 31a1f85a-ecc8-40c0-88aa-e694626906a3.disk0 needs to be repaired or removed. 
29
  WARNING: Partial LV d124d70a-4776-4e00-bf0d-43511c29c534.disk0_data needs to be repaired or removed. 
30
  WARNING: Partial LV d124d70a-4776-4e00-bf0d-43511c29c534.disk0_meta needs to be repaired or removed. 
31
  WARNING: Partial LV f73b4499-34ec-4f70-a543-e43152a8644a.disk0 needs to be repaired or removed. 
32
  WARNING: There are still partial LVs in VG xenvg.
33
  To remove them unconditionally use: vgreduce --removemissing --force.
34
  Proceeding to remove empty missing PVs.
b/test/data/vgreduce-removemissing-2.02.66-ok.txt
1
  Couldn't find device with uuid NzfYON-F7ky-1Szf-aGf1-v8Xa-Bt1W-8V3bou.
2
  Wrote out consistent volume group xenvg
b/test/data/vgs-missing-pvs-2.02.02.txt
1
  Couldn't find device with uuid 'gg4cmC-4lrT-EN1v-39OA-6S2b-6eEI-wWlJJJ'.
2
  Couldn't find all physical volumes for volume group xenvg.
3
  Couldn't find device with uuid 'gg4cmC-4lrT-EN1v-39OA-6S2b-6eEI-wWlJJJ'.
4
  Couldn't find all physical volumes for volume group xenvg.
5
  Volume group xenvg not found
b/test/data/vgs-missing-pvs-2.02.66.txt
1
  Couldn't find device with uuid bHRa26-svpL-ihJX-e0S4-2HNz-wAAi-AlBFtl.
2
  xenvg   2  52   0 wz-pn- 1.31t 1.07t
b/test/ganeti.storage_unittest.py
1
#!/usr/bin/python
2
#
3

  
4
# Copyright (C) 2012 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 ganeti.storage"""
23

  
24
import re
25
import unittest
26
import random
27

  
28
from ganeti import constants
29
from ganeti import utils
30
from ganeti import compat
31
from ganeti import errors
32
from ganeti import storage
33

  
34
import testutils
35

  
36

  
37
class TestVGReduce(testutils.GanetiTestCase):
38
  VGNAME = "xenvg"
39
  LIST_CMD = storage.LvmVgStorage.LIST_COMMAND
40
  VGREDUCE_CMD = storage.LvmVgStorage.VGREDUCE_COMMAND
41

  
42
  def _runCmd(self, cmd, **kwargs):
43
    if not self.run_history:
44
      self.fail("Empty run results")
45
    exp_cmd, result = self.run_history.pop(0)
46
    self.assertEqual(cmd, exp_cmd)
47
    return result
48

  
49
  def testOldVersion(self):
50
    lvmvg = storage.LvmVgStorage()
51
    stdout = self._ReadTestData("vgreduce-removemissing-2.02.02.txt")
52
    vgs_fail = self._ReadTestData("vgs-missing-pvs-2.02.02.txt")
53
    self.run_history = [
54
      ([self.VGREDUCE_CMD, "--removemissing", self.VGNAME],
55
       utils.RunResult(0, None, stdout, "", "", None, None)),
56
      ([self.LIST_CMD, "--noheadings", "--nosuffix", self.VGNAME],
57
       utils.RunResult(0, None, "", "", "", None, None)),
58
      ]
59
    lvmvg._RemoveMissing(self.VGNAME, _runcmd_fn=self._runCmd)
60
    self.assertEqual(self.run_history, [])
61
    for ecode, out in [(1, ""), (0, vgs_fail)]:
62
      self.run_history = [
63
        ([self.VGREDUCE_CMD, "--removemissing", self.VGNAME],
64
         utils.RunResult(0, None, stdout, "", "", None, None)),
65
        ([self.LIST_CMD, "--noheadings", "--nosuffix", self.VGNAME],
66
         utils.RunResult(ecode, None, out, "", "", None, None)),
67
        ]
68
      self.assertRaises(errors.StorageError, lvmvg._RemoveMissing, self.VGNAME,
69
                        _runcmd_fn=self._runCmd)
70
      self.assertEqual(self.run_history, [])
71

  
72
  def testNewVersion(self):
73
    lvmvg = storage.LvmVgStorage()
74
    stdout1 = self._ReadTestData("vgreduce-removemissing-2.02.66-fail.txt")
75
    stdout2 = self._ReadTestData("vgreduce-removemissing-2.02.66-ok.txt")
76
    vgs_fail = self._ReadTestData("vgs-missing-pvs-2.02.66.txt")
77
    # first: require --fail, check that it's used
78
    self.run_history = [
79
      ([self.VGREDUCE_CMD, "--removemissing", self.VGNAME],
80
       utils.RunResult(0, None, stdout1, "", "", None, None)),
81
      ([self.VGREDUCE_CMD, "--removemissing", "--force", self.VGNAME],
82
       utils.RunResult(0, None, stdout2, "", "", None, None)),
83
      ([self.LIST_CMD, "--noheadings", "--nosuffix", self.VGNAME],
84
       utils.RunResult(0, None, "", "", "", None, None)),
85
      ]
86
    lvmvg._RemoveMissing(self.VGNAME, _runcmd_fn=self._runCmd)
87
    self.assertEqual(self.run_history, [])
88
    # second: make sure --fail is not used if not needed
89
    self.run_history = [
90
      ([self.VGREDUCE_CMD, "--removemissing", self.VGNAME],
91
       utils.RunResult(0, None, stdout2, "", "", None, None)),
92
      ([self.LIST_CMD, "--noheadings", "--nosuffix", self.VGNAME],
93
       utils.RunResult(0, None, "", "", "", None, None)),
94
      ]
95
    lvmvg._RemoveMissing(self.VGNAME, _runcmd_fn=self._runCmd)
96
    self.assertEqual(self.run_history, [])
97
    # third: make sure we error out if vgs doesn't find the volume
98
    for ecode, out in [(1, ""), (0, vgs_fail)]:
99
      self.run_history = [
100
        ([self.VGREDUCE_CMD, "--removemissing", self.VGNAME],
101
         utils.RunResult(0, None, stdout1, "", "", None, None)),
102
        ([self.VGREDUCE_CMD, "--removemissing", "--force", self.VGNAME],
103
         utils.RunResult(0, None, stdout2, "", "", None, None)),
104
        ([self.LIST_CMD, "--noheadings", "--nosuffix", self.VGNAME],
105
         utils.RunResult(ecode, None, out, "", "", None, None)),
106
        ]
107
      self.assertRaises(errors.StorageError, lvmvg._RemoveMissing, self.VGNAME,
108
                        _runcmd_fn=self._runCmd)
109
      self.assertEqual(self.run_history, [])
110

  
111

  
112
if __name__ == "__main__":
113
  testutils.GanetiTestProgram()

Also available in: Unified diff