Zap Journals
The is_osd_disk code assumes that the first partition is the osd journal. That might not always be the case. This patch makes that function more general by searching all partitions on a disk. Change-Id: I4239ae498b9b6d2d97551d61d1a4f2981f72b88a
This commit is contained in:
parent
b483fa2668
commit
573bad86dc
|
@ -117,6 +117,42 @@ NETWORK_ADAPTER_SYSCTLS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Partition(object):
|
||||||
|
def __init__(self, name, number, size, start, end, sectors, uuid):
|
||||||
|
"""
|
||||||
|
A block device partition
|
||||||
|
:param name: Name of block device
|
||||||
|
:param number: Partition number
|
||||||
|
:param size: Capacity of the device
|
||||||
|
:param start: Starting block
|
||||||
|
:param end: Ending block
|
||||||
|
:param sectors: Number of blocks
|
||||||
|
:param uuid: UUID of the partition
|
||||||
|
"""
|
||||||
|
self.name = name,
|
||||||
|
self.number = number
|
||||||
|
self.size = size
|
||||||
|
self.start = start
|
||||||
|
self.end = end
|
||||||
|
self.sectors = sectors
|
||||||
|
self.uuid = uuid
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "number: {} start: {} end: {} sectors: {} size: {} " \
|
||||||
|
"name: {} uuid: {}".format(self.number, self.start,
|
||||||
|
self.end,
|
||||||
|
self.sectors, self.size,
|
||||||
|
self.name, self.uuid)
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
if isinstance(other, self.__class__):
|
||||||
|
return self.__dict__ == other.__dict__
|
||||||
|
return False
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
return not self.__eq__(other)
|
||||||
|
|
||||||
|
|
||||||
def unmounted_disks():
|
def unmounted_disks():
|
||||||
"""List of unmounted block devices on the current host."""
|
"""List of unmounted block devices on the current host."""
|
||||||
disks = []
|
disks = []
|
||||||
|
@ -759,9 +795,12 @@ DISK_FORMATS = [
|
||||||
]
|
]
|
||||||
|
|
||||||
CEPH_PARTITIONS = [
|
CEPH_PARTITIONS = [
|
||||||
|
'89C57F98-2FE5-4DC0-89C1-5EC00CEFF2BE', # ceph encrypted disk in creation
|
||||||
|
'45B0969E-9B03-4F30-B4C6-5EC00CEFF106', # ceph encrypted journal
|
||||||
'4FBD7E29-9D25-41B8-AFD0-5EC00CEFF05D', # ceph encrypted osd data
|
'4FBD7E29-9D25-41B8-AFD0-5EC00CEFF05D', # ceph encrypted osd data
|
||||||
'4FBD7E29-9D25-41B8-AFD0-062C0CEFF05D', # ceph osd data
|
'4FBD7E29-9D25-41B8-AFD0-062C0CEFF05D', # ceph osd data
|
||||||
'45B0969E-9B03-4F30-B4C6-B4B80CEFF106', # ceph osd journal
|
'45B0969E-9B03-4F30-B4C6-B4B80CEFF106', # ceph osd journal
|
||||||
|
'89C57F98-2FE5-4DC0-89C1-F3AD0CEFF2BE', # ceph disk in creation
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -872,17 +911,48 @@ def replace_osd(dead_osd_number,
|
||||||
log('replace_osd failed with error: ' + e.output)
|
log('replace_osd failed with error: ' + e.output)
|
||||||
|
|
||||||
|
|
||||||
def is_osd_disk(dev):
|
def get_partition_list(dev):
|
||||||
|
"""
|
||||||
|
Lists the partitions of a block device
|
||||||
|
:param dev: Path to a block device. ex: /dev/sda
|
||||||
|
:return: :raise: Returns a list of Partition objects.
|
||||||
|
Raises CalledProcessException if lsblk fails
|
||||||
|
"""
|
||||||
|
partitions_list = []
|
||||||
try:
|
try:
|
||||||
info = check_output(['sgdisk', '-i', '1', dev])
|
partitions = get_partitions(dev)
|
||||||
info = info.split("\n") # IGNORE:E1103
|
# For each line of output
|
||||||
for line in info:
|
for partition in partitions:
|
||||||
for ptype in CEPH_PARTITIONS:
|
parts = partition.split()
|
||||||
sig = 'Partition GUID code: {}'.format(ptype)
|
partitions_list.append(
|
||||||
if line.startswith(sig):
|
Partition(number=parts[0],
|
||||||
return True
|
start=parts[1],
|
||||||
|
end=parts[2],
|
||||||
|
sectors=parts[3],
|
||||||
|
size=parts[4],
|
||||||
|
name=parts[5],
|
||||||
|
uuid=parts[6])
|
||||||
|
)
|
||||||
|
return partitions_list
|
||||||
except subprocess.CalledProcessError:
|
except subprocess.CalledProcessError:
|
||||||
pass
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
def is_osd_disk(dev):
|
||||||
|
partitions = get_partition_list(dev)
|
||||||
|
for partition in partitions:
|
||||||
|
try:
|
||||||
|
info = check_output(['sgdisk', '-i', partition.number, dev])
|
||||||
|
info = info.split("\n") # IGNORE:E1103
|
||||||
|
for line in info:
|
||||||
|
for ptype in CEPH_PARTITIONS:
|
||||||
|
sig = 'Partition GUID code: {}'.format(ptype)
|
||||||
|
if line.startswith(sig):
|
||||||
|
return True
|
||||||
|
except subprocess.CalledProcessError as e:
|
||||||
|
log("sgdisk inspection of partition {} on {} failed with "
|
||||||
|
"error: {}. Skipping".format(partition.minor, dev, e.message),
|
||||||
|
level=ERROR)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
@ -1923,7 +1993,6 @@ def dirs_need_ownership_update(service):
|
||||||
# All child directories had the expected ownership
|
# All child directories had the expected ownership
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
# A dict of valid ceph upgrade paths. Mapping is old -> new
|
# A dict of valid ceph upgrade paths. Mapping is old -> new
|
||||||
UPGRADE_PATHS = {
|
UPGRADE_PATHS = {
|
||||||
'firefly': 'hammer',
|
'firefly': 'hammer',
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
1 2099200 8377310 6278111 3G ceph\x20data 6e99ac59-1aa3-4812-abd7-9c886a151dd4
|
||||||
|
2 2048 2099199 2097152 1G ceph\x20journal 0333f202-256c-4867-a85c-3e3c92abd461
|
|
@ -153,17 +153,17 @@ class CephTestCase(unittest.TestCase):
|
||||||
|
|
||||||
def test_parse_key_with_caps_existing_key(self):
|
def test_parse_key_with_caps_existing_key(self):
|
||||||
expected = "AQCm7aVYQFXXFhAAj0WIeqcag88DKOvY4UKR/g=="
|
expected = "AQCm7aVYQFXXFhAAj0WIeqcag88DKOvY4UKR/g=="
|
||||||
with_caps = "[client.osd-upgrade]\n"\
|
with_caps = "[client.osd-upgrade]\n" \
|
||||||
" key = AQCm7aVYQFXXFhAAj0WIeqcag88DKOvY4UKR/g==\n"\
|
" key = AQCm7aVYQFXXFhAAj0WIeqcag88DKOvY4UKR/g==\n" \
|
||||||
" caps mon = \"allow command \"config-key\";"
|
" caps mon = \"allow command \"config-key\";"
|
||||||
key = ceph.parse_key(with_caps)
|
key = ceph.parse_key(with_caps)
|
||||||
print("key: {}".format(key))
|
print("key: {}".format(key))
|
||||||
self.assertEqual(key, expected)
|
self.assertEqual(key, expected)
|
||||||
|
|
||||||
def test_parse_key_without_caps(self):
|
def test_parse_key_without_caps(self):
|
||||||
expected = "AQCm7aVYQFXXFhAAj0WIeqcag88DKOvY4UKR/g=="
|
expected = "AQCm7aVYQFXXFhAAj0WIeqcag88DKOvY4UKR/g=="
|
||||||
without_caps = "[client.osd-upgrade]\n"\
|
without_caps = "[client.osd-upgrade]\n" \
|
||||||
" key = AQCm7aVYQFXXFhAAj0WIeqcag88DKOvY4UKR/g=="
|
" key = AQCm7aVYQFXXFhAAj0WIeqcag88DKOvY4UKR/g=="
|
||||||
key = ceph.parse_key(without_caps)
|
key = ceph.parse_key(without_caps)
|
||||||
print("key: {}".format(key))
|
print("key: {}".format(key))
|
||||||
self.assertEqual(key, expected)
|
self.assertEqual(key, expected)
|
||||||
|
@ -193,6 +193,13 @@ class CephTestCase(unittest.TestCase):
|
||||||
devices = ceph.unmounted_disks()
|
devices = ceph.unmounted_disks()
|
||||||
self.assertEqual(devices, [])
|
self.assertEqual(devices, [])
|
||||||
|
|
||||||
|
@mock.patch.object(ceph, 'check_output')
|
||||||
|
def test_get_partition_list(self, output):
|
||||||
|
with open('unit_tests/partx_output', 'r') as partx_out:
|
||||||
|
output.return_value = partx_out.read()
|
||||||
|
partition_list = ceph.get_partition_list('/dev/xvdb')
|
||||||
|
self.assertEqual(len(partition_list), 2)
|
||||||
|
|
||||||
|
|
||||||
class CephVersionTestCase(unittest.TestCase):
|
class CephVersionTestCase(unittest.TestCase):
|
||||||
@mock.patch.object(ceph, 'get_os_codename_install_source')
|
@mock.patch.object(ceph, 'get_os_codename_install_source')
|
||||||
|
|
Loading…
Reference in New Issue