From 669bbb9f16a7d0b0a2b282ba1a1e401c68d83d67 Mon Sep 17 00:00:00 2001 From: Willem Jan Withagen Date: Sun, 20 Nov 2016 21:30:12 +0100 Subject: [PATCH] FreeBSD: changes to ceph-disk to get it working and passing tests - It currently only supports running with filestore - Testing is executed while running on a ZFS partition - All disktypes and naming is different on FreeBSD - Partitioning and tools are not workable on FreeBSD - add diagnostic timeout Signed-off-by: Willem Jan Withagen --- src/ceph-disk/ceph_disk/main.py | 94 +++++++++++++++++++++-------- src/ceph-disk/tests/ceph-disk.sh | 31 +++++++--- src/ceph-disk/tests/test_prepare.py | 3 + 3 files changed, 95 insertions(+), 33 deletions(-) diff --git a/src/ceph-disk/ceph_disk/main.py b/src/ceph-disk/ceph_disk/main.py index 5283484ab00..321dcf6e63c 100755 --- a/src/ceph-disk/ceph_disk/main.py +++ b/src/ceph-disk/ceph_disk/main.py @@ -208,6 +208,13 @@ class Ptype(object): DEFAULT_FS_TYPE = 'xfs' SYSFS = '/sys' +if platform.system() == 'FreeBSD': + FREEBSD = True + PROCDIR = '/compat/linux/proc' +else: + FREEBSD = False + PROCDIR = '/proc' + """ OSD STATUS Definition """ @@ -224,6 +231,7 @@ MOUNT_OPTIONS = dict( # that user_xattr helped ext4='noatime,user_xattr', xfs='noatime,inode64', + zfs='atime=off', ) MKFS_ARGS = dict( @@ -248,6 +256,7 @@ INIT_SYSTEMS = [ 'sysvinit', 'systemd', 'openrc', + 'bsdrc', 'auto', 'none', ] @@ -366,7 +375,7 @@ def is_systemd(): """ Detect whether systemd is running """ - with open('/proc/1/comm', 'r') as f: + with open(PROCDIR + '/1/comm', 'r') as f: return 'systemd' in f.read() @@ -506,25 +515,33 @@ def platform_distro(): def platform_information(): - distro, release, codename = platform.linux_distribution() - # this could be an empty string in Debian - if not codename and 'debian' in distro.lower(): - debian_codenames = { - '8': 'jessie', - '7': 'wheezy', - '6': 'squeeze', - } - major_version = release.split('.')[0] - codename = debian_codenames.get(major_version, '') - - # In order to support newer jessie/sid or wheezy/sid strings we test - # this if sid is buried in the minor, we should use sid anyway. - if not codename and '/' in release: - major, minor = release.split('/') - if minor == 'sid': - codename = minor - else: - codename = major + if FREEBSD: + distro = platform.system() + release = platform.version().split()[1] + codename = platform.version().split()[3] + version = platform.version().split('-')[0] + major_version = version.split('.')[0] + major, minor = release.split('.') + else: + distro, release, codename = platform.linux_distribution() + # this could be an empty string in Debian + if not codename and 'debian' in distro.lower(): + debian_codenames = { + '8': 'jessie', + '7': 'wheezy', + '6': 'squeeze', + } + major_version = release.split('.')[0] + codename = debian_codenames.get(major_version, '') + + # In order to support newer jessie/sid, wheezy/sid strings we test + # this if sid is buried in the minor, we should use sid anyway. + if not codename and '/' in release: + major, minor = release.split('/') + if minor == 'sid': + codename = minor + else: + codename = major return ( str(distro).strip(), @@ -562,6 +579,8 @@ def platform_information(): def block_path(dev): + if FREEBSD: + return dev path = os.path.realpath(dev) rdev = os.stat(path).st_rdev (M, m) = (os.major(rdev), os.minor(rdev)) @@ -582,6 +601,8 @@ def is_mpath(dev): """ True if the path is managed by multipath """ + if FREEBSD: + return True uuid = get_dm_uuid(dev) return (uuid and (re.match('part\d+-mpath-', uuid) or @@ -800,7 +821,7 @@ def is_mounted(dev): Check if the given device is mounted. """ dev = os.path.realpath(dev) - with open('/proc/mounts', 'rb') as proc_mounts: + with open(PROCDIR + '/mounts', 'rb') as proc_mounts: for line in proc_mounts: fields = line.split() if len(fields) < 3: @@ -3110,9 +3131,21 @@ def start_daemon( 'start', ], ) + elif os.path.exists(os.path.join(path, 'bsdrc')): + base_script = '/usr/local/etc/rc.d/ceph' + osd_script = '{base} start osd.{osd_id}'.format( + base=base_script, + osd_id=osd_id + ) + command_check_call( + [ + osd_script, + ], + ) else: - raise Error('{cluster} osd.{osd_id} is not tagged ' - 'with an init system'.format( + raise Error('{cluster} osd.{osd_id} ' + 'is not tagged with an init system' + .format( cluster=cluster, osd_id=osd_id, )) @@ -3175,9 +3208,18 @@ def stop_daemon( 'stop', ], ) + elif os.path.exists(os.path.join(path, 'bsdrc')): + command_check_call( + [ + '/usr/local/etc/rc.d/ceph stop osd.{osd_id}' + .format(osd_id=osd_id), + 'stop', + ], + ) else: - raise Error('{cluster} osd.{osd_id} is not tagged with an init ' - ' system'.format(cluster=cluster, osd_id=osd_id)) + raise Error('{cluster} osd.{osd_id} ' + 'is not tagged with an init system' + .format(cluster=cluster, osd_id=osd_id)) except subprocess.CalledProcessError as e: raise Error('ceph osd stop failed', e) @@ -4029,7 +4071,7 @@ def main_activate_all(args): def is_swap(dev): dev = os.path.realpath(dev) - with open('/proc/swaps', 'rb') as proc_swaps: + with open(PROCDIR + '/swaps', 'rb') as proc_swaps: for line in proc_swaps.readlines()[1:]: fields = line.split() if len(fields) < 3: diff --git a/src/ceph-disk/tests/ceph-disk.sh b/src/ceph-disk/tests/ceph-disk.sh index e685caff027..454ec444151 100755 --- a/src/ceph-disk/tests/ceph-disk.sh +++ b/src/ceph-disk/tests/ceph-disk.sh @@ -38,6 +38,11 @@ CEPH_DISK_ARGS= CEPH_DISK_ARGS+=" --verbose" CEPH_DISK_ARGS+=" --prepend-to-path=" TIMEOUT=360 +if [ `uname` != FreeBSD ]; then + PROCDIR="" +else + PROCDIR="/compat/linux" +fi cat=$(which cat) timeout=$(which timeout) @@ -59,11 +64,12 @@ function teardown() { return fi kill_daemons $dir - if [ $(stat -f -c '%T' .) == "btrfs" ]; then + if [ `uname` != FreeBSD ] && \ + [ $(stat -f -c '%T' .) == "btrfs" ]; then rm -fr $dir/*/*db __teardown_btrfs $dir fi - grep " $(pwd)/$dir/" < /proc/mounts | while read mounted rest ; do + grep " $(pwd)/$dir/" < ${PROCDIR}/proc/mounts | while read mounted rest ; do umount $mounted done rm -fr $dir @@ -150,7 +156,7 @@ function test_path() { function test_no_path() { local dir=$1 shift - ( export PATH=../ceph-detect-init/virtualenv/bin:virtualenv/bin:$CEPH_BIN:/usr/bin:/bin ; test_activate_dir $dir) || return 1 + ( export PATH=../ceph-detect-init/virtualenv/bin:virtualenv/bin:$CEPH_BIN:/usr/bin:/bin:/usr/local/bin ; test_activate_dir $dir) || return 1 } function test_mark_init() { @@ -169,7 +175,7 @@ function test_mark_init() { ${CEPH_DISK} $CEPH_DISK_ARGS \ prepare --osd-uuid $osd_uuid $osd_data || return 1 - $timeout $TIMEOUT ${CEPH_DISK} $CEPH_DISK_ARGS \ + ${CEPH_DISK} $CEPH_DISK_ARGS \ --verbose \ activate \ --mark-init=auto \ @@ -255,11 +261,20 @@ function test_activate() { local to_prepare=$1 local to_activate=$2 local osd_uuid=$($uuidgen) + local timeoutcmd + + if [ `uname` = FreeBSD ]; then + # for unknown reasons FreeBSD timeout does not return here + # So we run without timeout + timeoutcmd="" + else + timeoutcmd="${timeout} $TIMEOUT" + fi ${CEPH_DISK} $CEPH_DISK_ARGS \ prepare --osd-uuid $osd_uuid $to_prepare || return 1 - $timeout $TIMEOUT ${CEPH_DISK} $CEPH_DISK_ARGS \ + $timeoutcmd ${CEPH_DISK} $CEPH_DISK_ARGS \ activate \ --mark-init=none \ $to_activate || return 1 @@ -381,9 +396,11 @@ function run() { default_actions+="test_activate_dir_magic " default_actions+="test_activate_dir " default_actions+="test_keyring_path " - default_actions+="test_mark_init " + [ `uname` != FreeBSD ] && \ + default_actions+="test_mark_init " default_actions+="test_zap " - default_actions+="test_activate_dir_bluestore " + [ `uname` != FreeBSD ] && \ + default_actions+="test_activate_dir_bluestore " default_actions+="test_ceph_osd_mkfs " local actions=${@:-$default_actions} for action in $actions ; do diff --git a/src/ceph-disk/tests/test_prepare.py b/src/ceph-disk/tests/test_prepare.py index 2e475832d8d..6ab8ca49a40 100644 --- a/src/ceph-disk/tests/test_prepare.py +++ b/src/ceph-disk/tests/test_prepare.py @@ -16,6 +16,7 @@ import argparse import configobj import mock import os +import platform import pytest import shutil import tempfile @@ -133,6 +134,8 @@ class TestDevice(Base): m_update_partition, m_get_free_partition_index, m_is_partition): + if platform.system() == 'FreeBSD': + return m_is_partition.return_value = False partition_number = 1 m_get_free_partition_index.return_value = partition_number -- 2.39.5