X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fqa%2Fworkunits%2Fceph-disk%2Fceph-disk-test.py;fp=src%2Fceph%2Fqa%2Fworkunits%2Fceph-disk%2Fceph-disk-test.py;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=637fa90ebdd231ec299ba79f2f25a61204a8cde1;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/qa/workunits/ceph-disk/ceph-disk-test.py b/src/ceph/qa/workunits/ceph-disk/ceph-disk-test.py deleted file mode 100644 index 637fa90..0000000 --- a/src/ceph/qa/workunits/ceph-disk/ceph-disk-test.py +++ /dev/null @@ -1,777 +0,0 @@ -# -# Copyright (C) 2015, 2016 Red Hat -# -# Author: Loic Dachary -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU Library Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Library Public License for more details. -# -# When debugging these tests (must be root), here are a few useful commands: -# -# export PATH=.:..:$PATH -# ceph-disk.sh # run once to prepare the environment as it would be by teuthology -# ln -sf /home/ubuntu/ceph/src/ceph-disk/ceph_disk/main.py $(which ceph-disk) -# ln -sf /home/ubuntu/ceph/udev/95-ceph-osd.rules /lib/udev/rules.d/95-ceph-osd.rules -# ln -sf /home/ubuntu/ceph/systemd/ceph-disk@.service /usr/lib/systemd/system/ceph-disk@.service -# ceph-disk.conf will be silently ignored if it is a symbolic link or a hard link /var/log/upstart for logs -# cp /home/ubuntu/ceph/src/upstart/ceph-disk.conf /etc/init/ceph-disk.conf -# id=3 ; ceph-disk deactivate --deactivate-by-id $id ; ceph-disk destroy --purge --zap --destroy-by-id $id -# py.test -s -v -k test_activate_dmcrypt_luks ceph-disk-test.py -# -# CentOS 7 -# udevadm monitor --property & tail -f /var/log/messages -# udev rules messages are logged in /var/log/messages -# systemctl stop ceph-osd@2 -# systemctl start ceph-osd@2 -# -# udevadm monitor --property & tail -f /var/log/syslog /var/log/upstart/* # on Ubuntu 14.04 -# udevadm test --action=add /block/vdb/vdb1 # verify the udev rule is run as expected -# udevadm control --reload # when changing the udev rules -# sudo /usr/sbin/ceph-disk -v trigger /dev/vdb1 # activates if vdb1 is data -# -# integration tests coverage -# pip install coverage -# perl -pi -e 's|"ceph-disk |"coverage run --source=/usr/sbin/ceph-disk --append /usr/sbin/ceph-disk |' ceph-disk-test.py -# rm -f .coverage ; py.test -s -v ceph-disk-test.py -# coverage report --show-missing -# -import argparse -import json -import logging -import configobj -import os -import pytest -import re -import subprocess -import sys -import tempfile -import time -import uuid - -LOG = logging.getLogger('CephDisk') - - -class CephDisk: - - def __init__(self): - self.conf = configobj.ConfigObj('/etc/ceph/ceph.conf') - - def save_conf(self): - self.conf.write(open('/etc/ceph/ceph.conf', 'wb')) - - @staticmethod - def helper(command): - command = "ceph-helpers-root.sh " + command - return CephDisk.sh(command) - - @staticmethod - def sh(command): - LOG.debug(":sh: " + command) - proc = subprocess.Popen( - args=command, - stdout=subprocess.PIPE, - stderr=subprocess.STDOUT, - shell=True, - bufsize=1) - output, _ = proc.communicate() - if proc.poll(): - LOG.warning(output.decode('utf-8')) - raise subprocess.CalledProcessError( - returncode=proc.returncode, - cmd=command, - output=output, - ) - lines = [] - for line in output.decode('utf-8').split('\n'): - if 'dangerous and experimental' in line: - LOG.debug('SKIP dangerous and experimental') - continue - lines.append(line) - LOG.debug(line.strip().encode('ascii', 'ignore')) - return "".join(lines) - - def unused_disks(self, pattern='[vs]d.'): - names = [x for x in os.listdir("/sys/block") if re.match(pattern, x)] - if not names: - return [] - disks = json.loads( - self.sh("ceph-disk list --format json " + " ".join(names))) - unused = [] - for disk in disks: - if 'partitions' not in disk: - unused.append(disk['path']) - return unused - - def ensure_sd(self): - LOG.debug(self.unused_disks('sd.')) - if self.unused_disks('sd.'): - return - modprobe = "modprobe scsi_debug vpd_use_hostno=0 add_host=1 dev_size_mb=300 ; udevadm settle" - try: - self.sh(modprobe) - except: - self.helper("install linux-image-extra-3.13.0-61-generic") - self.sh(modprobe) - - def unload_scsi_debug(self): - self.sh("rmmod scsi_debug || true") - - def get_lockbox(self): - disks = json.loads(self.sh("ceph-disk list --format json")) - for disk in disks: - if 'partitions' in disk: - for partition in disk['partitions']: - if partition.get('type') == 'lockbox': - return partition - raise Exception("no lockbox found " + str(disks)) - - def get_osd_partition(self, uuid): - disks = json.loads(self.sh("ceph-disk list --format json")) - for disk in disks: - if 'partitions' in disk: - for partition in disk['partitions']: - if partition.get('uuid') == uuid: - return partition - raise Exception("uuid = " + uuid + " not found in " + str(disks)) - - def get_journal_partition(self, uuid): - return self.get_space_partition('journal', uuid) - - def get_block_partition(self, uuid): - return self.get_space_partition('block', uuid) - - def get_blockdb_partition(self, uuid): - return self.get_space_partition('block.db', uuid) - - def get_blockwal_partition(self, uuid): - return self.get_space_partition('block.wal', uuid) - - def get_space_partition(self, name, uuid): - data_partition = self.get_osd_partition(uuid) - space_dev = data_partition[name + '_dev'] - disks = json.loads(self.sh("ceph-disk list --format json")) - for disk in disks: - if 'partitions' in disk: - for partition in disk['partitions']: - if partition['path'] == space_dev: - if name + '_for' in partition: - assert partition[ - name + '_for'] == data_partition['path'] - return partition - raise Exception( - name + " for uuid = " + uuid + " not found in " + str(disks)) - - def destroy_osd(self, uuid): - id = self.sh("ceph osd create " + uuid).strip() - self.sh(""" - set -xe - ceph-disk --verbose deactivate --deactivate-by-id {id} - ceph-disk --verbose destroy --purge --destroy-by-id {id} --zap - """.format(id=id)) - - def deactivate_osd(self, uuid): - id = self.sh("ceph osd create " + uuid).strip() - self.sh(""" - set -xe - ceph-disk --verbose deactivate --once --deactivate-by-id {id} - """.format(id=id)) - - @staticmethod - def osd_up_predicate(osds, uuid): - for osd in osds: - if osd['uuid'] == uuid and 'up' in osd['state']: - return True - return False - - @staticmethod - def wait_for_osd_up(uuid): - CephDisk.wait_for_osd(uuid, CephDisk.osd_up_predicate, 'up') - - @staticmethod - def osd_down_predicate(osds, uuid): - found = False - for osd in osds: - if osd['uuid'] == uuid: - found = True - if 'down' in osd['state'] or ['exists'] == osd['state']: - return True - return not found - - @staticmethod - def wait_for_osd_down(uuid): - CephDisk.wait_for_osd(uuid, CephDisk.osd_down_predicate, 'down') - - @staticmethod - def wait_for_osd(uuid, predicate, info): - LOG.info("wait_for_osd " + info + " " + uuid) - for delay in (1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024): - dump = json.loads(CephDisk.sh("ceph osd dump -f json")) - if predicate(dump['osds'], uuid): - return True - time.sleep(delay) - raise Exception('timeout waiting for osd ' + uuid + ' to be ' + info) - - def check_osd_status(self, uuid, space_name=None): - data_partition = self.get_osd_partition(uuid) - assert data_partition['type'] == 'data' - assert data_partition['state'] == 'active' - if space_name is not None: - space_partition = self.get_space_partition(space_name, uuid) - assert space_partition - - -class TestCephDisk(object): - - def setup_class(self): - logging.basicConfig(level=logging.DEBUG) - c = CephDisk() - if c.sh("lsb_release -si").strip() == 'CentOS': - c.helper("install multipath-tools device-mapper-multipath") - c.conf['global']['pid file'] = '/var/run/ceph/$cluster-$name.pid' - # - # Avoid json parsing interference - # - c.conf['global']['debug monc'] = 0 - # - # objecstore - # - c.conf['global']['osd journal size'] = 100 - # - # bluestore - # - c.conf['global']['bluestore fsck on mount'] = 'true' - c.save_conf() - - def setup(self): - c = CephDisk() - for key in ('osd objectstore', 'osd dmcrypt type'): - if key in c.conf['global']: - del c.conf['global'][key] - c.save_conf() - - def test_deactivate_reactivate_osd(self): - c = CephDisk() - disk = c.unused_disks()[0] - osd_uuid = str(uuid.uuid1()) - c.sh("ceph-disk --verbose zap " + disk) - c.sh("ceph-disk --verbose prepare --filestore --osd-uuid " + osd_uuid + - " " + disk) - c.wait_for_osd_up(osd_uuid) - device = json.loads(c.sh("ceph-disk list --format json " + disk))[0] - assert len(device['partitions']) == 2 - c.check_osd_status(osd_uuid, 'journal') - data_partition = c.get_osd_partition(osd_uuid) - c.sh("ceph-disk --verbose deactivate " + data_partition['path']) - c.wait_for_osd_down(osd_uuid) - c.sh("ceph-disk --verbose activate " + data_partition['path'] + " --reactivate") - # check again - c.wait_for_osd_up(osd_uuid) - device = json.loads(c.sh("ceph-disk list --format json " + disk))[0] - assert len(device['partitions']) == 2 - c.check_osd_status(osd_uuid, 'journal') - c.helper("pool_read_write") - c.destroy_osd(osd_uuid) - - def test_destroy_osd_by_id(self): - c = CephDisk() - disk = c.unused_disks()[0] - osd_uuid = str(uuid.uuid1()) - c.sh("ceph-disk --verbose prepare --filestore --osd-uuid " + osd_uuid + " " + disk) - c.wait_for_osd_up(osd_uuid) - c.check_osd_status(osd_uuid) - c.destroy_osd(osd_uuid) - - def test_destroy_osd_by_dev_path(self): - c = CephDisk() - disk = c.unused_disks()[0] - osd_uuid = str(uuid.uuid1()) - c.sh("ceph-disk --verbose prepare --filestore --osd-uuid " + osd_uuid + " " + disk) - c.wait_for_osd_up(osd_uuid) - partition = c.get_osd_partition(osd_uuid) - assert partition['type'] == 'data' - assert partition['state'] == 'active' - c.sh("ceph-disk --verbose deactivate " + partition['path']) - c.wait_for_osd_down(osd_uuid) - c.sh("ceph-disk --verbose destroy --purge " + partition['path'] + " --zap") - - def test_deactivate_reactivate_dmcrypt_plain(self): - c = CephDisk() - c.conf['global']['osd dmcrypt type'] = 'plain' - c.save_conf() - osd_uuid = self.activate_dmcrypt('ceph-disk-no-lockbox') - data_partition = c.get_osd_partition(osd_uuid) - c.sh("ceph-disk --verbose deactivate " + data_partition['path']) - c.wait_for_osd_down(osd_uuid) - c.sh("ceph-disk --verbose activate-journal " + data_partition['journal_dev'] + - " --reactivate" + " --dmcrypt") - c.wait_for_osd_up(osd_uuid) - c.check_osd_status(osd_uuid, 'journal') - c.destroy_osd(osd_uuid) - c.save_conf() - - def test_deactivate_reactivate_dmcrypt_luks(self): - c = CephDisk() - osd_uuid = self.activate_dmcrypt('ceph-disk') - data_partition = c.get_osd_partition(osd_uuid) - lockbox_partition = c.get_lockbox() - c.sh("ceph-disk --verbose deactivate " + data_partition['path']) - c.wait_for_osd_down(osd_uuid) - c.sh("ceph-disk --verbose trigger --sync " + lockbox_partition['path']) - c.sh("ceph-disk --verbose activate-journal " + data_partition['journal_dev'] + - " --reactivate" + " --dmcrypt") - c.wait_for_osd_up(osd_uuid) - c.check_osd_status(osd_uuid, 'journal') - c.destroy_osd(osd_uuid) - - def test_activate_dmcrypt_plain_no_lockbox(self): - c = CephDisk() - c.conf['global']['osd dmcrypt type'] = 'plain' - c.save_conf() - osd_uuid = self.activate_dmcrypt('ceph-disk-no-lockbox') - c.destroy_osd(osd_uuid) - c.save_conf() - - def test_activate_dmcrypt_luks_no_lockbox(self): - c = CephDisk() - osd_uuid = self.activate_dmcrypt('ceph-disk-no-lockbox') - c.destroy_osd(osd_uuid) - - def test_activate_dmcrypt_luks_with_lockbox(self): - c = CephDisk() - osd_uuid = self.activate_dmcrypt('ceph-disk') - c.destroy_osd(osd_uuid) - - def test_activate_lockbox(self): - c = CephDisk() - osd_uuid = self.activate_dmcrypt('ceph-disk') - lockbox = c.get_lockbox() - assert lockbox['state'] == 'active' - c.sh("umount " + lockbox['path']) - lockbox = c.get_lockbox() - assert lockbox['state'] == 'prepared' - c.sh("ceph-disk --verbose trigger " + lockbox['path']) - success = False - for delay in (1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024): - lockbox = c.get_lockbox() - if lockbox['state'] == 'active': - success = True - break - time.sleep(delay) - if not success: - raise Exception('timeout waiting for lockbox ' + lockbox['path']) - c.destroy_osd(osd_uuid) - - def activate_dmcrypt(self, ceph_disk): - c = CephDisk() - disk = c.unused_disks()[0] - osd_uuid = str(uuid.uuid1()) - journal_uuid = str(uuid.uuid1()) - c.sh("ceph-disk --verbose zap " + disk) - c.sh(ceph_disk + " --verbose prepare --filestore " + - " --osd-uuid " + osd_uuid + - " --journal-uuid " + journal_uuid + - " --dmcrypt " + - " " + disk) - c.wait_for_osd_up(osd_uuid) - c.check_osd_status(osd_uuid, 'journal') - return osd_uuid - - def test_trigger_dmcrypt_journal_lockbox(self): - c = CephDisk() - osd_uuid = self.activate_dmcrypt('ceph-disk') - data_partition = c.get_osd_partition(osd_uuid) - lockbox_partition = c.get_lockbox() - c.deactivate_osd(osd_uuid) - c.wait_for_osd_down(osd_uuid) - with pytest.raises(subprocess.CalledProcessError): - # fails because the lockbox is not mounted yet - c.sh("ceph-disk --verbose trigger --sync " + data_partition['journal_dev']) - c.sh("ceph-disk --verbose trigger --sync " + lockbox_partition['path']) - c.wait_for_osd_up(osd_uuid) - c.destroy_osd(osd_uuid) - - def test_trigger_dmcrypt_data_lockbox(self): - c = CephDisk() - osd_uuid = self.activate_dmcrypt('ceph-disk') - data_partition = c.get_osd_partition(osd_uuid) - lockbox_partition = c.get_lockbox() - c.deactivate_osd(osd_uuid) - c.wait_for_osd_down(osd_uuid) - with pytest.raises(subprocess.CalledProcessError): - # fails because the lockbox is not mounted yet - c.sh("ceph-disk --verbose trigger --sync " + data_partition['path']) - c.sh("ceph-disk --verbose trigger --sync " + lockbox_partition['path']) - c.wait_for_osd_up(osd_uuid) - c.destroy_osd(osd_uuid) - - def test_trigger_dmcrypt_lockbox(self): - c = CephDisk() - osd_uuid = self.activate_dmcrypt('ceph-disk') - data_partition = c.get_osd_partition(osd_uuid) - lockbox_partition = c.get_lockbox() - c.deactivate_osd(osd_uuid) - c.wait_for_osd_down(osd_uuid) - c.sh("ceph-disk --verbose trigger --sync " + lockbox_partition['path']) - c.wait_for_osd_up(osd_uuid) - c.destroy_osd(osd_uuid) - - def test_activate_no_journal(self): - c = CephDisk() - disk = c.unused_disks()[0] - osd_uuid = str(uuid.uuid1()) - c.sh("ceph-disk --verbose zap " + disk) - c.conf['global']['osd objectstore'] = 'memstore' - c.save_conf() - c.sh("ceph-disk --verbose prepare --filestore --osd-uuid " + osd_uuid + - " " + disk) - c.wait_for_osd_up(osd_uuid) - device = json.loads(c.sh("ceph-disk list --format json " + disk))[0] - assert len(device['partitions']) == 1 - partition = device['partitions'][0] - assert partition['type'] == 'data' - assert partition['state'] == 'active' - assert 'journal_dev' not in partition - c.helper("pool_read_write") - c.destroy_osd(osd_uuid) - c.save_conf() - - def test_activate_with_journal_dev_no_symlink(self): - c = CephDisk() - disk = c.unused_disks()[0] - osd_uuid = str(uuid.uuid1()) - c.sh("ceph-disk --verbose zap " + disk) - c.sh("ceph-disk --verbose prepare --filestore --osd-uuid " + osd_uuid + - " " + disk) - c.wait_for_osd_up(osd_uuid) - device = json.loads(c.sh("ceph-disk list --format json " + disk))[0] - assert len(device['partitions']) == 2 - c.check_osd_status(osd_uuid, 'journal') - c.helper("pool_read_write") - c.destroy_osd(osd_uuid) - - def test_activate_bluestore(self): - c = CephDisk() - disk = c.unused_disks()[0] - osd_uuid = str(uuid.uuid1()) - c.sh("ceph-disk --verbose zap " + disk) - c.conf['global']['osd objectstore'] = 'bluestore' - c.save_conf() - c.sh("ceph-disk --verbose prepare --bluestore --osd-uuid " + osd_uuid + - " " + disk) - c.wait_for_osd_up(osd_uuid) - device = json.loads(c.sh("ceph-disk list --format json " + disk))[0] - assert len(device['partitions']) == 2 - c.check_osd_status(osd_uuid, 'block') - c.helper("pool_read_write") - c.destroy_osd(osd_uuid) - c.sh("ceph-disk --verbose zap " + disk) - - def test_activate_bluestore_seperated_block_db_wal(self): - c = CephDisk() - disk1 = c.unused_disks()[0] - disk2 = c.unused_disks()[1] - osd_uuid = str(uuid.uuid1()) - c.sh("ceph-disk --verbose zap " + disk1 + " " + disk2) - c.conf['global']['osd objectstore'] = 'bluestore' - c.save_conf() - c.sh("ceph-disk --verbose prepare --bluestore --osd-uuid " + osd_uuid + - " " + disk1 + " --block.db " + disk2 + " --block.wal " + disk2) - c.wait_for_osd_up(osd_uuid) - device = json.loads(c.sh("ceph-disk list --format json " + disk1))[0] - assert len(device['partitions']) == 2 - device = json.loads(c.sh("ceph-disk list --format json " + disk2))[0] - assert len(device['partitions']) == 2 - c.check_osd_status(osd_uuid, 'block') - c.check_osd_status(osd_uuid, 'block.wal') - c.check_osd_status(osd_uuid, 'block.db') - c.helper("pool_read_write") - c.destroy_osd(osd_uuid) - c.sh("ceph-disk --verbose zap " + disk1 + " " + disk2) - - def test_activate_bluestore_reuse_db_wal_partition(self): - c = CephDisk() - disks = c.unused_disks() - block_disk = disks[0] - db_wal_disk = disks[1] - # - # Create an OSD with two disks (one for block, - # the other for block.db and block.wal ) and then destroy osd. - # - osd_uuid1 = str(uuid.uuid1()) - c.sh("ceph-disk --verbose zap " + block_disk + " " + db_wal_disk) - c.conf['global']['osd objectstore'] = 'bluestore' - c.save_conf() - c.sh("ceph-disk --verbose prepare --bluestore --osd-uuid " + - osd_uuid1 + " " + block_disk + " --block.db " + db_wal_disk + - " --block.wal " + db_wal_disk) - c.wait_for_osd_up(osd_uuid1) - blockdb_partition = c.get_blockdb_partition(osd_uuid1) - blockdb_path = blockdb_partition['path'] - blockwal_partition = c.get_blockwal_partition(osd_uuid1) - blockwal_path = blockwal_partition['path'] - c.destroy_osd(osd_uuid1) - c.sh("ceph-disk --verbose zap " + block_disk) - # - # Create another OSD with the block.db and block.wal partition - # of the previous OSD - # - osd_uuid2 = str(uuid.uuid1()) - c.sh("ceph-disk --verbose prepare --bluestore --osd-uuid " + - osd_uuid2 + " " + block_disk + " --block.db " + blockdb_path + - " --block.wal " + blockwal_path) - c.wait_for_osd_up(osd_uuid2) - device = json.loads(c.sh("ceph-disk list --format json " + block_disk))[0] - assert len(device['partitions']) == 2 - device = json.loads(c.sh("ceph-disk list --format json " + db_wal_disk))[0] - assert len(device['partitions']) == 2 - c.check_osd_status(osd_uuid2, 'block') - c.check_osd_status(osd_uuid2, 'block.wal') - c.check_osd_status(osd_uuid2, 'block.db') - blockdb_partition = c.get_blockdb_partition(osd_uuid2) - blockwal_partition = c.get_blockwal_partition(osd_uuid2) - # - # Verify the previous OSD partition has been reused - # - assert blockdb_partition['path'] == blockdb_path - assert blockwal_partition['path'] == blockwal_path - c.destroy_osd(osd_uuid2) - c.sh("ceph-disk --verbose zap " + block_disk + " " + db_wal_disk) - - def test_activate_with_journal_dev_is_symlink(self): - c = CephDisk() - disk = c.unused_disks()[0] - osd_uuid = str(uuid.uuid1()) - tempdir = tempfile.mkdtemp() - symlink = os.path.join(tempdir, 'osd') - os.symlink(disk, symlink) - c.sh("ceph-disk --verbose zap " + symlink) - c.sh("ceph-disk --verbose prepare --filestore --osd-uuid " + osd_uuid + - " " + symlink) - c.wait_for_osd_up(osd_uuid) - device = json.loads(c.sh("ceph-disk list --format json " + symlink))[0] - assert len(device['partitions']) == 2 - data_partition = c.get_osd_partition(osd_uuid) - assert data_partition['type'] == 'data' - assert data_partition['state'] == 'active' - journal_partition = c.get_journal_partition(osd_uuid) - assert journal_partition - c.helper("pool_read_write") - c.destroy_osd(osd_uuid) - c.sh("ceph-disk --verbose zap " + symlink) - os.unlink(symlink) - os.rmdir(tempdir) - - def test_activate_journal_file(self): - c = CephDisk() - disks = c.unused_disks() - data_disk = disks[0] - # - # /var/lib/ceph/osd is required otherwise it may violate - # restrictions enforced by systemd regarding the directories - # which ceph-osd is allowed to read/write - # - tempdir = tempfile.mkdtemp(dir='/var/lib/ceph/osd') - c.sh("chown ceph:ceph " + tempdir + " || true") - journal_file = os.path.join(tempdir, 'journal') - osd_uuid = str(uuid.uuid1()) - c.sh("ceph-disk --verbose prepare --filestore --osd-uuid " + osd_uuid + - " " + data_disk + " " + journal_file) - c.wait_for_osd_up(osd_uuid) - device = json.loads( - c.sh("ceph-disk list --format json " + data_disk))[0] - assert len(device['partitions']) == 1 - partition = device['partitions'][0] - assert journal_file == os.readlink( - os.path.join(partition['mount'], 'journal')) - c.check_osd_status(osd_uuid) - c.helper("pool_read_write 1") # 1 == pool size - c.destroy_osd(osd_uuid) - c.sh("ceph-disk --verbose zap " + data_disk) - os.unlink(journal_file) - os.rmdir(tempdir) - - def test_activate_separated_journal(self): - c = CephDisk() - disks = c.unused_disks() - data_disk = disks[0] - journal_disk = disks[1] - osd_uuid = self.activate_separated_journal(data_disk, journal_disk) - c.helper("pool_read_write 1") # 1 == pool size - c.destroy_osd(osd_uuid) - c.sh("ceph-disk --verbose zap " + data_disk + " " + journal_disk) - - def test_activate_separated_journal_dev_is_symlink(self): - c = CephDisk() - disks = c.unused_disks() - data_disk = disks[0] - journal_disk = disks[1] - tempdir = tempfile.mkdtemp() - data_symlink = os.path.join(tempdir, 'osd') - os.symlink(data_disk, data_symlink) - journal_symlink = os.path.join(tempdir, 'journal') - os.symlink(journal_disk, journal_symlink) - osd_uuid = self.activate_separated_journal( - data_symlink, journal_symlink) - c.helper("pool_read_write 1") # 1 == pool size - c.destroy_osd(osd_uuid) - c.sh("ceph-disk --verbose zap " + data_symlink + " " + journal_symlink) - os.unlink(data_symlink) - os.unlink(journal_symlink) - os.rmdir(tempdir) - - def activate_separated_journal(self, data_disk, journal_disk): - c = CephDisk() - osd_uuid = str(uuid.uuid1()) - c.sh("ceph-disk --verbose prepare --filestore --osd-uuid " + osd_uuid + - " " + data_disk + " " + journal_disk) - c.wait_for_osd_up(osd_uuid) - device = json.loads( - c.sh("ceph-disk list --format json " + data_disk))[0] - assert len(device['partitions']) == 1 - c.check_osd_status(osd_uuid, 'journal') - return osd_uuid - - # - # Create an OSD and get a journal partition from a disk that - # already contains a journal partition which is in use. Updates of - # the kernel partition table may behave differently when a - # partition is in use. See http://tracker.ceph.com/issues/7334 for - # more information. - # - def test_activate_two_separated_journal(self): - c = CephDisk() - disks = c.unused_disks() - data_disk = disks[0] - other_data_disk = disks[1] - journal_disk = disks[2] - osd_uuid = self.activate_separated_journal(data_disk, journal_disk) - other_osd_uuid = self.activate_separated_journal( - other_data_disk, journal_disk) - # - # read/write can only succeed if the two osds are up because - # the pool needs two OSD - # - c.helper("pool_read_write 2") # 2 == pool size - c.destroy_osd(osd_uuid) - c.destroy_osd(other_osd_uuid) - c.sh("ceph-disk --verbose zap " + data_disk + " " + - journal_disk + " " + other_data_disk) - - # - # Create an OSD and reuse an existing journal partition - # - def test_activate_reuse_journal(self): - c = CephDisk() - disks = c.unused_disks() - data_disk = disks[0] - journal_disk = disks[1] - # - # Create an OSD with a separated journal and destroy it. - # - osd_uuid = self.activate_separated_journal(data_disk, journal_disk) - journal_partition = c.get_journal_partition(osd_uuid) - journal_path = journal_partition['path'] - c.destroy_osd(osd_uuid) - c.sh("ceph-disk --verbose zap " + data_disk) - osd_uuid = str(uuid.uuid1()) - # - # Create another OSD with the journal partition of the previous OSD - # - c.sh("ceph-disk --verbose prepare --filestore --osd-uuid " + osd_uuid + - " " + data_disk + " " + journal_path) - c.helper("pool_read_write 1") # 1 == pool size - c.wait_for_osd_up(osd_uuid) - device = json.loads( - c.sh("ceph-disk list --format json " + data_disk))[0] - assert len(device['partitions']) == 1 - c.check_osd_status(osd_uuid) - journal_partition = c.get_journal_partition(osd_uuid) - # - # Verify the previous OSD partition has been reused - # - assert journal_partition['path'] == journal_path - c.destroy_osd(osd_uuid) - c.sh("ceph-disk --verbose zap " + data_disk + " " + journal_disk) - - def test_activate_multipath(self): - c = CephDisk() - if c.sh("lsb_release -si").strip() != 'CentOS': - pytest.skip( - "see issue https://bugs.launchpad.net/ubuntu/+source/multipath-tools/+bug/1488688") - c.ensure_sd() - # - # Figure out the name of the multipath device - # - disk = c.unused_disks('sd.')[0] - c.sh("mpathconf --enable || true") - c.sh("multipath " + disk) - holders = os.listdir( - "/sys/block/" + os.path.basename(disk) + "/holders") - assert 1 == len(holders) - name = open("/sys/block/" + holders[0] + "/dm/name").read() - multipath = "/dev/mapper/" + name - # - # Prepare the multipath device - # - osd_uuid = str(uuid.uuid1()) - c.sh("ceph-disk --verbose zap " + multipath) - c.sh("ceph-disk --verbose prepare --filestore --osd-uuid " + osd_uuid + - " " + multipath) - c.wait_for_osd_up(osd_uuid) - device = json.loads( - c.sh("ceph-disk list --format json " + multipath))[0] - assert len(device['partitions']) == 2 - data_partition = c.get_osd_partition(osd_uuid) - assert data_partition['type'] == 'data' - assert data_partition['state'] == 'active' - journal_partition = c.get_journal_partition(osd_uuid) - assert journal_partition - c.helper("pool_read_write") - c.destroy_osd(osd_uuid) - c.sh("udevadm settle") - c.sh("multipath -F") - c.unload_scsi_debug() - - -class CephDiskTest(CephDisk): - - def main(self, argv): - parser = argparse.ArgumentParser( - 'ceph-disk-test', - ) - parser.add_argument( - '-v', '--verbose', - action='store_true', default=None, - help='be more verbose', - ) - parser.add_argument( - '--destroy-osd', - help='stop, umount and destroy', - ) - args = parser.parse_args(argv) - - if args.verbose: - logging.basicConfig(level=logging.DEBUG) - - if args.destroy_osd: - dump = json.loads(CephDisk.sh("ceph osd dump -f json")) - osd_uuid = None - for osd in dump['osds']: - if str(osd['osd']) == args.destroy_osd: - osd_uuid = osd['uuid'] - if osd_uuid: - self.destroy_osd(osd_uuid) - else: - raise Exception("cannot find OSD " + args.destroy_osd + - " ceph osd dump -f json") - return - -if __name__ == '__main__': - sys.exit(CephDiskTest().main(sys.argv[1:]))