diff --git a/.gitignore b/.gitignore
index 05c434708..b25c15b81 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,12 +1 @@
*~
-.#*
-## the next line needs to start with a backslash to avoid looking like
-## a comment
-\#*#
-.*.swp
-
-*.pyc
-*.pyo
-
-/*.egg-info
-/virtualenv
diff --git a/README b/README
new file mode 100644
index 000000000..e865c17a7
--- /dev/null
+++ b/README
@@ -0,0 +1,43 @@
+ceph-qa-suite
+-------------
+
+clusters/ - some predefined cluster layouts
+suites/ - sets of collections
+
+We have several collections, each a subdirectory within suites/*/.
+Each collection directory consists of a set facets. The basic idea is
+that, for each collection, the set of tests to run consists of all
+combinations of taking one yaml fragment from each facet.
+
+For example, given the files
+
+ suite/collection/
+ suite/collection/foo/
+ suite/collection/foo/clusters/
+ suite/collection/foo/clusters/fixed-3.yaml
+ suite/collection/foo/clusters/fixed-9.yaml
+ suite/collection/foo/tasks/
+ suite/collection/foo/tasks/a
+ suite/collection/foo/tasks/b
+ suite/collection/foo/tasks/c
+ suite/collection/bar/
+ suite/collection/bar/clusters/fixed-3.yaml
+ suite/collection/bar/tasks/
+ suite/collection/bar/tasks/d
+ suite/collection/bar/tasks/e
+
+teuthology-suite would run tasks a, b, and c on both fixed-3 and
+fixed-9 clusters. It would also run tasks d and e on the fixed-3
+cluster.
+
+Note that the 'clusters' and 'tasks' terminology is actually
+meaningless here. All teuthology-suite does is stick the yaml
+fragments together (one from each facet) and run teuthology on the
+result (optionally combined with any additional fragments passed on
+the command line).
+
+In practice, we can keep common/shared task and cluster definitions in
+the top-level clusters/ (which are otherwise ignored), and symlink to
+them from the collections that want to use them.
+
+The teuthology code can be found in https://github.com/ceph/teuthology.git
diff --git a/README.rst b/README.rst
deleted file mode 100644
index 91bbb55c8..000000000
--- a/README.rst
+++ /dev/null
@@ -1,499 +0,0 @@
-==================================================
- `Teuthology` -- The Ceph integration test runner
-==================================================
-
-The Ceph project needs automated tests. Because Ceph is a highly
-distributed system, and has active kernel development, its testing
-requirements are quite different from e.g. typical LAMP web
-applications. Nothing out there seemed to handle our requirements,
-so we wrote our own framework, called `Teuthology`.
-
-
-Overview
-========
-
-Teuthology runs a given set of Python functions (`tasks`), with an SSH
-connection to every host participating in the test. The SSH connection
-uses `Paramiko `__, a native Python
-client for the SSH2 protocol, and this allows us to e.g. run multiple
-commands inside a single SSH connection, to speed up test
-execution. Tests can use `gevent `__ to
-perform actions concurrently or in the background.
-
-
-Build
-=====
-``teuthology`` is not meant to be distributed as a library, therefore we depend
-on the pinned dependencies listed in ``requirements.txt``, the ``setup.py``
-will not list any and will only be there to install the package entry points
-(a.k.a teuthology's scripts).
-
-
-``bootstrap`` for Ubuntu Systems
---------------------------------
-A ``boostrap`` script is provided for automated builds/execution of teuthology
-itself. You can run it directly **only if you are using Ubuntu**.
-
-Teuthology uses several Python packages that are not in the standard
-library. To make the dependencies easier to get right, we use a
-`virtualenv` to manage them. To get started, ensure you have the
-``virtualenv`` and ``pip`` programs installed; e.g. on Debian/Ubuntu::
-
- sudo apt-get install python-dev python-virtualenv python-pip libevent-dev
-
-and then run::
-
- ./bootstrap
-
-
-osx
----
-
-.. note:: These instructions assume you are using `homebrew `_
-
-As always, create a ``virtualenv`` specific to ``teuthology`` and make sure it
-is activated before proceeding (location doesn't matter, we use an example
-location)::
-
- mkdir ~/.virtualenvs
- virtualenv ~/.virtualenvs/teuthology
- source ~/.virtualenvs/teuthology/bin/activate
-
-Install the system dependencies::
-
- brew install libvirt mysql libevent
-
-``libvirt`` does not link the python bindings so you need to do this step
-manually::
-
- $ cd /Library/Python/{pyversion}/site-packages
- $ sudo ln -s /usr/local/Cellar/libvirt/{version}/lib/python{pyversion}/site-packages/* .
-
-Make sure you are able to import ``libvirt`` without error::
-
- python -c "import libvirt"
-
-Finally, install the teuthology package and ``requirements.txt``::
-
- $ python setup.py develop
- $ pip install -r requirements.txt
-
-
-Generic install
----------------
-These instructions should help get ``teuthology`` installed properly in
-a system that is not OSX or Debian-based.
-
-Install all the system dependencies needed:
-
-* mysql client
-* libevent
-* libvirt (with the Python bindings)
-
-Install Python packaging tools:
-
-* pip
-* virtualenv
-
-In some cases, depending on the OS, you will need a python development package
-with some build helpers that are required to build packages. In Ubuntu, this is
-the ``python-dev`` package.
-
-With a dedicated ``virtualenv`` activated, install the teuthology package and
-``requirements.txt``::
-
- $ python setup.py develop
- $ pip install -r requirements.txt
-
-
-Test configuration
-==================
-
-An integration test run takes three items of configuration:
-
-- ``targets``: what hosts to run on; this is a dictionary mapping
- hosts to ssh host keys, like:
- "username@hostname.example.com: ssh-rsa long_hostkey_here"
-- ``roles``: how to use the hosts; this is a list of lists, where each
- entry lists all the roles to be run on a single host; for example, a
- single entry might say ``[mon.1, osd.1]``
-- ``tasks``: how to set up the cluster and what tests to run on it;
- see below for examples
-
-The format for this configuration is `YAML `__, a
-structured data format that is still human-readable and editable.
-
-For example, a full config for a test run that sets up a three-machine
-cluster, mounts Ceph via ``ceph-fuse``, and leaves you at an interactive
-Python prompt for manual exploration (and enabling you to SSH in to
-the nodes & use the live cluster ad hoc), might look like this::
-
- roles:
- - [mon.0, mds.0, osd.0]
- - [mon.1, osd.1]
- - [mon.2, client.0]
- targets:
- ubuntu@host07.example.com: ssh-rsa host07_ssh_key
- ubuntu@host08.example.com: ssh-rsa host08_ssh_key
- ubuntu@host09.example.com: ssh-rsa host09_ssh_key
- tasks:
- - install:
- - ceph:
- - ceph-fuse: [client.0]
- - interactive:
-
-The number of entries under ``roles`` and ``targets`` must match.
-
-Note the colon after every task name in the ``tasks`` section.
-
-The ``install`` task needs to precede all other tasks.
-
-The listed targets need resolvable hostnames. If you do not have a DNS server
-running, you can add entries to ``/etc/hosts``. You also need to be able to SSH
-in to the listed targets without passphrases, and the remote user needs to have
-passphraseless `sudo` access. Note that the ssh keys at the end of the
-``targets`` entries are the public ssh keys for the hosts. On Ubuntu, these
-are located at /etc/ssh/ssh_host_rsa_key.pub
-
-If you'd save the above file as ``example.yaml``, you could run
-teuthology on it by saying::
-
- ./virtualenv/bin/teuthology example.yaml
-
-You can also pass the ``-v`` option, for more verbose execution. See
-``teuthology --help`` for more.
-
-
-Multiple config files
----------------------
-
-You can pass multiple files as arguments to ``teuthology``. Each one
-will be read as a config file, and their contents will be merged. This
-allows you to e.g. share definitions of what a "simple 3 node cluster"
-is. The source tree comes with ``roles/3-simple.yaml``, so we could
-skip the ``roles`` section in the above ``example.yaml`` and then
-run::
-
- ./virtualenv/bin/teuthology roles/3-simple.yaml example.yaml
-
-
-Reserving target machines
--------------------------
-
-Before locking machines will work, you must create a .teuthology.yaml
-file in your home directory that sets a lock_server, i.e.::
-
- lock_server: http://host.example.com:8080/lock
-
-Teuthology automatically locks nodes for you if you specify the
-``--lock`` option. Without this option, you must specify machines to
-run on in a ``targets.yaml`` file, and lock them using
-teuthology-lock.
-
-Note that the default owner of a machine is ``USER@HOST``.
-You can override this with the ``--owner`` option when running
-teuthology or teuthology-lock.
-
-With teuthology-lock, you can also add a description, so you can
-remember which tests you were running on them. This can be done when
-locking or unlocking machines, or as a separate action with the
-``--update`` option. To lock 3 machines and set a description, run::
-
- ./virtualenv/bin/teuthology-lock --lock-many 3 --desc 'test foo'
-
-If machines become unusable for some reason, you can mark them down::
-
- ./virtualenv/bin/teuthology-lock --update --status down machine1 machine2
-
-To see the status of all machines, use the ``--list`` option. This can
-be restricted to particular machines as well::
-
- ./virtualenv/bin/teuthology-lock --list machine1 machine2
-
-
-Tasks
-=====
-
-A task is a Python module in the ``teuthology.task`` package, with a
-callable named ``task``. It gets the following arguments:
-
-- ``ctx``: a context that is available through the lifetime of the
- test run, and has useful attributes such as ``cluster``, letting the
- task access the remote hosts. Tasks can also store their internal
- state here. (TODO beware namespace collisions.)
-- ``config``: the data structure after the colon in the config file,
- e.g. for the above ``ceph-fuse`` example, it would be a list like
- ``["client.0"]``.
-
-Tasks can be simple functions, called once in the order they are
-listed in ``tasks``. But sometimes, it makes sense for a task to be
-able to clean up after itself; for example, unmounting the filesystem
-after a test run. A task callable that returns a Python `context
-manager
-`__
-will have the manager added to a stack, and the stack will be unwound
-at the end of the run. This means the cleanup actions are run in
-reverse order, both on success and failure. A nice way of writing
-context managers is the ``contextlib.contextmanager`` decorator; look
-for that string in the existing tasks to see examples, and note where
-they use ``yield``.
-
-Further details on some of the more complex tasks such as install or workunit
-can be obtained via python help. For example::
-
- >>> import teuthology.task.workunit
- >>> help(teuthology.task.workunit)
-
-displays a page of more documentation and more concrete examples.
-
-Some of the more important / commonly used tasks include:
-
-* ``chef``: Run the chef task.
-* ``install``: by default, the install task goes to gitbuilder and installs the results of the latest build. You can, however, add additional parameters to the test configuration to cause it to install any branch, SHA, archive or URL. The following are valid parameters.
-
-- ``branch``: specify a branch (bobtail, cuttlefish...)
-- ``flavor``: specify a flavor (next, unstable...). Flavors can be thought of as
- subsets of branches. Sometimes (unstable, for example) they may have
- a predefined meaning.
-- ``project``: specify a project (ceph, samba...)
-- ``sha1``: install the build with this sha1 value.
-- ``tag``: specify a tag/identifying text for this build (v47.2, v48.1...)
-* ``ceph``: Bring up Ceph
-
-* ``overrides``: override behavior. Typically, this includes sub-tasks being overridden. Sub-tasks can nest further information. For example, overrides of install tasks are project specific, so the following section of a yaml file would cause all ceph installation to default into using the cuttlefish branch::
-
- overrides:
- install:
- ceph:
- branch: cuttlefish
-
-* ``workunit``: workunits are a way of grouping tasks and behavior on targets.
-* ``sequential``: group the sub-tasks into a unit where the sub-tasks run sequentially as listed.
-* ``parallel``: group the sub-tasks into a unit where the sub-task all run in parallel.
-
-Sequential and parallel tasks can be nested. Tasks run sequentially if not specified.
-
-The above list is a very incomplete description of the tasks available on
-teuthology. The teuthology/task subdirectory contains all the python files
-that implement tasks.
-Many of these tasks are used to run shell scripts that are defined in the
-ceph/ceph-qa-suite.
-
-Troubleshooting
-===============
-
-Sometimes when a bug triggers, instead of automatic cleanup, you want
-to explore the system as is. Adding a top-level::
-
- interactive-on-error: true
-
-as a config file for ``teuthology`` will make that possible. With that
-option, any *task* that fails, will have the ``interactive`` task
-called after it. This means that before any cleanup happens, you get a
-chance to inspect the system -- both through Teuthology and via extra
-SSH connections -- and the cleanup completes only when you choose so.
-Just exit the interactive Python session to continue the cleanup.
-
-Note that this only catches exceptions *between* the tasks. If a task
-calls multiple subtasks, e.g. with ``contextutil.nested``, those
-cleanups *will* be performed. Later on, we can let tasks communicate
-the subtasks they wish to invoke to the top-level runner, avoiding
-this issue.
-
-Test Sandbox Directory
-======================
-
-Teuthology currently places most test files and mount points in a sandbox
-directory, defaulting to ``/tmp/cephtest/{rundir}``. The ``{rundir}`` is the
-name of the run (as given by ``--name``) or if no name is specified,
-``user@host-timestamp`` is used. To change the location of the sandbox
-directory, the following options can be specified in
-``$HOME/.teuthology.yaml``::
-
- base_test_dir:
-
-The ``base_test_dir`` option will set the base directory to use for the individual
-run directories. If not specified, this defaults to: ``/tmp/cephtest``.
-
- test_path:
-
-The ``test_path`` option will set the complete path to use for the test directory.
-This allows for the old behavior, where ``/tmp/cephtest`` was used as the sandbox
-directory.
-
-
-VIRTUAL MACHINE SUPPORT
-=======================
-
-Teuthology also supports virtual machines, which can function like
-physical machines but differ in the following ways:
-
-VPSHOST:
---------
-
-A new entry, vpshost, has been added to the teuthology database of
-available machines. For physical machines, this value is null. For
-virtual machines, this entry is the name of the physical machine that
-that virtual machine resides on.
-
-There are fixed "slots" for virtual machines that appear in the teuthology
-database. These slots have a machine type of vps and can be locked like
-any other machine. The existence of a vpshost field is how teuthology
-knows whether or not a database entry represents a physical or a virtual
-machine.
-
-The following needs to be set in ~/.libvirt/libvirt.conf in order to get the
-right virtual machine associations for the Inktank lab::
-
- uri_aliases = [
- 'mira001=qemu+ssh://ubuntu@mira001.front.sepia.ceph.com/system?no_tty',
- 'mira003=qemu+ssh://ubuntu@mira003.front.sepia.ceph.com/system?no_tty',
- 'mira004=qemu+ssh://ubuntu@mira004.front.sepia.ceph.com/system?no_tty',
- 'mira006=qemu+ssh://ubuntu@mira006.front.sepia.ceph.com/system?no_tty',
- 'mira007=qemu+ssh://ubuntu@mira007.front.sepia.ceph.com/system?no_tty',
- 'mira008=qemu+ssh://ubuntu@mira008.front.sepia.ceph.com/system?no_tty',
- 'mira009=qemu+ssh://ubuntu@mira009.front.sepia.ceph.com/system?no_tty',
- 'mira010=qemu+ssh://ubuntu@mira010.front.sepia.ceph.com/system?no_tty',
- 'mira011=qemu+ssh://ubuntu@mira011.front.sepia.ceph.com/system?no_tty',
- 'mira013=qemu+ssh://ubuntu@mira013.front.sepia.ceph.com/system?no_tty',
- 'mira014=qemu+ssh://ubuntu@mira014.front.sepia.ceph.com/system?no_tty',
- 'mira015=qemu+ssh://ubuntu@mira015.front.sepia.ceph.com/system?no_tty',
- 'mira017=qemu+ssh://ubuntu@mira017.front.sepia.ceph.com/system?no_tty',
- 'mira018=qemu+ssh://ubuntu@mira018.front.sepia.ceph.com/system?no_tty',
- 'mira020=qemu+ssh://ubuntu@mira020.front.sepia.ceph.com/system?no_tty',
- 'vercoi01=qemu+ssh://ubuntu@vercoi01.front.sepia.ceph.com/system?no_tty',
- 'vercoi02=qemu+ssh://ubuntu@vercoi02.front.sepia.ceph.com/system?no_tty',
- 'vercoi03=qemu+ssh://ubuntu@vercoi03.front.sepia.ceph.com/system?no_tty',
- 'vercoi04=qemu+ssh://ubuntu@vercoi04.front.sepia.ceph.com/system?no_tty',
- 'vercoi05=qemu+ssh://ubuntu@vercoi05.front.sepia.ceph.com/system?no_tty',
- 'vercoi06=qemu+ssh://ubuntu@vercoi06.front.sepia.ceph.com/system?no_tty',
- 'vercoi07=qemu+ssh://ubuntu@vercoi07.front.sepia.ceph.com/system?no_tty',
- 'vercoi08=qemu+ssh://ubuntu@vercoi08.front.sepia.ceph.com/system?no_tty',
- 'senta01=qemu+ssh://ubuntu@senta01.front.sepia.ceph.com/system?no_tty',
- 'senta02=qemu+ssh://ubuntu@senta02.front.sepia.ceph.com/system?no_tty',
- 'senta03=qemu+ssh://ubuntu@senta03.front.sepia.ceph.com/system?no_tty',
- 'senta04=qemu+ssh://ubuntu@senta04.front.sepia.ceph.com/system?no_tty',
- ]
-
-DOWNBURST:
-----------
-
-When a virtual machine is locked, downburst is run on that machine to
-install a new image. This allows the user to set different virtual
-OSes to be installed on the newly created virtual machine. Currently
-the default virtual machine is ubuntu (precise). A different vm installation
-can be set using the ``--os-type`` option in ``teuthology.lock``.
-
-When a virtual machine is unlocked, downburst destroys the image on the
-machine.
-
-Temporary yaml files are used to downburst a virtual machine. A typical
-yaml file will look like this::
-
- downburst:
- cpus: 1
- disk-size: 30G
- distro: centos
- networks:
- - {source: front}
- ram: 4G
-
-These values are used by downburst to create the virtual machine.
-
-HOST KEYS:
-----------
-
-Because teuthology reinstalls a new machine, a new hostkey is generated. After
-locking, once a connection is established to the new machine,
-``teuthology-lock`` with the ``--list`` or ``--list-targets`` options will
-display the new keys. When vps machines are locked using the ``--lock-many``
-option, a message is displayed indicating that ``--list-targets`` should be run
-later.
-
-CEPH-QA-CHEF:
--------------
-
-Once teuthology starts after a new vm is installed, teuthology
-checks for the existence of ``/ceph-qa-ready``. If this file is not
-present, ``ceph-qa-chef`` is run when teuthology first comes up.
-
-ASSUMPTIONS:
-------------
-
-It is assumed that downburst is on the user's ``$PATH``.
-
-
-Test Suites
-===========
-
-Most of the current teuthology test suite execution scripts automatically
-download their tests from the master branch of the appropriate github
-repository. People who want to run experimental test suites usually modify
-the download method in the ``teuthology/task`` script to use some other branch
-or repository. This should be generalized in later teuthology releases.
-Teuthology QA suites can be found in ``src/ceph-qa-suite``. Make sure that this
-directory exists in your source tree before running the test suites.
-
-Each suite name is determined by the name of the directory in ``ceph-qa-suite``
-that contains that suite. The directory contains subdirectories and yaml files,
-which, when assembled, produce valid tests that can be run. The test suite
-application generates combinations of these files and thus ends up running
-a set of tests based off the data in the directory for the suite.
-
-To run a suite, enter::
-
- ./schedule_suite.sh
-
-where:
-
-* ``suite``: the name of the suite (the directory in ceph-qa-suite).
-* ``ceph``: ceph branch to be used.
-* ``kernel``: version of the kernel to be used.
-* ``email``: email address to send the results to.
-* ``flavor``: flavor of the test
-* ``teuth``: version of teuthology to run
-* ``mtype``: machine type of the run
-* ``templates``: template file used for further modifying the suite (optional)
-
-For example, consider::
-
- schedule_suite.sh rbd wip-fix cuttlefish bob.smith@foo.com master cuttlefish plana
-
-The above command runs the rbd suite using wip-fix as the ceph branch,
-a straight cuttlefish kernel, and the master flavor of cuttlefish teuthology.
-It will run on plana machines.
-
-In order for a queued task to be run, a teuthworker thread on
-``teuthology.front.sepia.ceph.com`` needs to remove the task from the queue.
-On ``teuthology.front.sepia.ceph.com``, run ``ps aux | grep teuthology-worker``
-to view currently running tasks. If no processes are reading from the test
-version that you are running, additonal teuthworker tasks need to be started.
-To start these tasks:
-* copy your build tree to ``/home/teuthworker`` on ``teuthology.front.sepia.ceph.com``.
-* Give it a unique name (in this example, xxx)
-* start up some number of worker threads (as many as machines you are testing
-with, there are 60 running for the default queue)::
-
- /home/virtualenv/bin/python
- /var/lib/teuthworker/xxx/virtualenv/bin/teuthworker
- /var/lib/teuthworker/archive --tube xxx
- --log-dir /var/lib/teuthworker/archive/worker_logs
-
- Note: The threads on teuthology.front.sepia.ceph.com are started via
- ~/teuthworker/start.sh. You can use that file as a model for your
- own threads, or add to this file if you want your threads to be
- more permanent.
-
-Once the suite completes, an email message is sent to the users specified, and
-a large amount of information is left on ``teuthology.front.sepia.ceph.com`` in
-``/var/lib/teuthworker/archive``.
-
-This is symbolically linked to /a for convenience. A new directory is created
-whose name consists of a concatenation of the date and time that the suite was
-started, the name of the suite, the ceph branch tested, the kernel used, and
-the flavor. For every test run there is a directory whose name is the pid
-number of the pid of that test. Each of these directory contains a copy of
-the ``teuthology.log`` for that process. Other information from the suite is
-stored in files in the directory, and task-specific yaml files and other logs
-are saved in the subdirectories.
-
diff --git a/bootstrap b/bootstrap
deleted file mode 100755
index 695180621..000000000
--- a/bootstrap
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/sh
-set -e
-
-for package in python-dev python-pip python-virtualenv libevent-dev python-libvirt libmysqlclient-dev; do
- if [ "$(dpkg --status -- $package|sed -n 's/^Status: //p')" != "install ok installed" ]; then
- # add a space after old values
- missing="${missing:+$missing }$package"
- fi
-done
-if [ -n "$missing" ]; then
- echo "$0: missing required packages, please install them:" 1>&2
- echo "sudo apt-get install $missing"
- exit 1
-fi
-
-# site packages needed because libvirt python bindings are not nicely
-# packaged
-virtualenv --system-site-packages --distribute virtualenv
-
-# avoid pip bugs
-./virtualenv/bin/pip install --upgrade pip
-
-./virtualenv/bin/pip install -r requirements.txt
-
-# forbid setuptools from using the network because it'll try to use
-# easy_install, and we really wanted pip; next line will fail if pip
-# requirements.txt does not match setup.py requirements -- sucky but
-# good enough for now
-./virtualenv/bin/python setup.py develop \
- --allow-hosts None
diff --git a/build_qemu_image.sh b/build_qemu_image.sh
deleted file mode 100755
index 614f519aa..000000000
--- a/build_qemu_image.sh
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/bin/sh -x
-set -e
-
-IMAGE_URL=http://cloud-images.ubuntu.com/releases/precise/release/ubuntu-12.04-server-cloudimg-amd64-disk1.img
-
-wget -O base.qcow2 $IMAGE_URL
-
-image=base.raw
-qemu-img convert -O raw base.qcow2 $image
-rm -f base.qcow2
-
-# Note: this assumes that sector size is 512, and that there's only one
-# partition. very brittle.
-START_SECT=$(fdisk -lu $image | grep ^$image | awk '{print $3}')
-START_BYTE=$(echo "$START_SECT * 512" | bc)
-
-root=/tmp/$$
-
-cleanup() {
- sudo chroot $root rm -f /etc/resolv.conf || true
- sudo chroot $root ln -s ../run/resolvconf/resolv.conf /etc/resolv.conf || true
- sudo umount $root/proc || true
- sudo umount $root/sys || true
- sudo umount $root/dev/pts || true
- sudo umount $root
- sudo rmdir $root
-}
-trap cleanup INT TERM EXIT
-
-sudo mkdir $root
-sudo mount -o loop,offset=$START_BYTE $image $root
-
-# set up chroot
-sudo mount -t proc proc $root/proc
-sudo mount -t sysfs sysfs $root/sys
-sudo mount -t devpts devptr $root/dev/pts
-
-# set up network access
-sudo chroot $root rm /etc/resolv.conf
-sudo cp /etc/resolv.conf $root/etc/resolv.conf
-
-# packages
-# These should be kept in sync with ceph-qa-chef.git/cookbooks/ceph-qa/default.rb
-sudo chroot $root apt-get -y --force-yes install iozone3 bonnie++ dbench \
- tiobench build-essential attr libtool automake gettext uuid-dev \
- libacl1-dev bc xfsdump dmapi xfslibs-dev
-
-# install ltp without ltp-network-test, so we don't pull in xinetd and
-# a bunch of other unnecessary stuff
-sudo chroot $root apt-get -y --force-yes --no-install-recommends install ltp-kernel-test
-
-# add 9p fs support
-sudo chroot $root apt-get -y --force-yes install linux-image-extra-virtual
-
-cleanup
-trap - INT TERM EXIT
-
-qemu-img convert -O qcow2 $image output.qcow2
-rm -f $image
-
-exit 0
diff --git a/check-syntax.sh b/check-syntax.sh
deleted file mode 100755
index f63586f18..000000000
--- a/check-syntax.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/bash
-
-which pyflakes > /dev/null
-if test $? != 0; then
- echo "$0 requires pyflakes (sudo apt-get install pyflakes)"
- exit 1
-fi
-
-d=$(dirname $0)
-for f in $(find ${d}/teuthology | grep py$); do
- if test -n "${V}"; then
- echo "checking ${f}"
- fi
- pyflakes ${f} > >( \
- grep -v "'Lock' imported but unused" | \
- grep -v "'MachineLock' imported but unused" \
- )
-done
diff --git a/cleanup-and-unlock.sh b/cleanup-and-unlock.sh
deleted file mode 100755
index 7b30a2b02..000000000
--- a/cleanup-and-unlock.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh -ex
-
-bin/teuthology-nuke -t $1 -r --owner $2
-bin/teuthology-lock --unlock -t $1 --owner $2
diff --git a/cleanup-run.sh b/cleanup-run.sh
deleted file mode 100755
index 50bc74d13..000000000
--- a/cleanup-run.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-#!/bin/sh -ex
-
-owner=`teuthology-lock -a --list --desc-pattern /$1/ --status up | grep locked_by | head -1 | awk '{print $2}' | sed 's/"//g' | sed 's/,//'`
-teuthology-lock --list-targets --desc-pattern /$1/ --status up --owner $owner > /tmp/$$
-teuthology-nuke --unlock -t /tmp/$$ -r --owner $owner
-rm /tmp/$$
-
diff --git a/cleanup-user.sh b/cleanup-user.sh
deleted file mode 100755
index 91d12b17d..000000000
--- a/cleanup-user.sh
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/sh -ex
-
-teuthology-lock --list-targets --owner $1 --status up > /tmp/$$
-teuthology-nuke --unlock -t /tmp/$$ -r --owner $1
-rm /tmp/$$
-
diff --git a/clusters/extra-client.yaml b/clusters/extra-client.yaml
new file mode 100644
index 000000000..70ccbd028
--- /dev/null
+++ b/clusters/extra-client.yaml
@@ -0,0 +1,5 @@
+roles:
+- [mon.a, mon.c, osd.0, osd.1, osd.2]
+- [mon.b, mds.a, osd.3, osd.4, osd.5]
+- [client.0]
+- [client.1]
diff --git a/clusters/fixed-1.yaml b/clusters/fixed-1.yaml
new file mode 100644
index 000000000..8ec132330
--- /dev/null
+++ b/clusters/fixed-1.yaml
@@ -0,0 +1,2 @@
+roles:
+- [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1, osd.2, client.0]
diff --git a/clusters/fixed-2.yaml b/clusters/fixed-2.yaml
new file mode 100644
index 000000000..6298ff23c
--- /dev/null
+++ b/clusters/fixed-2.yaml
@@ -0,0 +1,3 @@
+roles:
+- [mon.a, mon.c, osd.0, osd.1, osd.2]
+- [mon.b, mds.a, osd.3, osd.4, osd.5, client.0]
diff --git a/clusters/fixed-3.yaml b/clusters/fixed-3.yaml
new file mode 100644
index 000000000..0038432af
--- /dev/null
+++ b/clusters/fixed-3.yaml
@@ -0,0 +1,4 @@
+roles:
+- [mon.a, mon.c, osd.0, osd.1, osd.2]
+- [mon.b, mds.a, osd.3, osd.4, osd.5]
+- [client.0]
diff --git a/coverage/cov-analyze.sh b/coverage/cov-analyze.sh
deleted file mode 100755
index 9b309e2bd..000000000
--- a/coverage/cov-analyze.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/bash
-set -e
-
-usage () {
- printf '%s: usage: %s -d WORKING_DIR -o OUT_BASENAME -t TEST_DIR\n' "$(basename "$0")" "$(basename "$0")" 1>&2
- echo <&2
- exit 1
-}
-
-TEST_DIR=$1
-OUTPUT_DIR=$2
-CEPH_TARBALL=$3
-
-if [ -z "$TEST_DIR" ] || [ -z "$OUTPUT_DIR" ] || [ -z "$CEPH_TARBALL" ]; then
- usage
-fi
-
-SHA1=`cat $TEST_DIR/ceph-sha1`
-
-mkdir -p $OUTPUT_DIR/ceph
-
-echo "Retrieving source and .gcno files..."
-wget -q -O- "https://github.com/ceph/ceph/tarball/$SHA1" | tar xzf - --strip-components=1 -C $OUTPUT_DIR/ceph
-tar zxf $CEPH_TARBALL -C $OUTPUT_DIR
-cp $OUTPUT_DIR/usr/local/lib/ceph/coverage/*.gcno $OUTPUT_DIR/ceph/src
-mkdir $OUTPUT_DIR/ceph/src/.libs
-cp $OUTPUT_DIR/usr/local/lib/ceph/coverage/.libs/*.gcno $OUTPUT_DIR/ceph/src/.libs
-rm -rf $OUTPUT_DIR/usr
-# leave ceph tarball around in case we need to inspect core files
-
-echo "Initializing lcov files..."
-lcov -d $OUTPUT_DIR/ceph/src -z
-lcov -d $OUTPUT_DIR/ceph/src -c -i -o $OUTPUT_DIR/base_full.lcov
-lcov -r $OUTPUT_DIR/base_full.lcov /usr/include\* -o $OUTPUT_DIR/base.lcov
-rm $OUTPUT_DIR/base_full.lcov
-echo "Done."
diff --git a/distros/centos_6.3.yaml b/distros/centos_6.3.yaml
new file mode 100644
index 000000000..32187d6da
--- /dev/null
+++ b/distros/centos_6.3.yaml
@@ -0,0 +1,2 @@
+os_type: centos
+os_version: "6.3"
diff --git a/distros/centos_6.4.yaml b/distros/centos_6.4.yaml
new file mode 100644
index 000000000..02383cd5f
--- /dev/null
+++ b/distros/centos_6.4.yaml
@@ -0,0 +1,2 @@
+os_type: centos
+os_version: "6.4"
diff --git a/distros/debian_6.0.yaml b/distros/debian_6.0.yaml
new file mode 100644
index 000000000..6820fa3c7
--- /dev/null
+++ b/distros/debian_6.0.yaml
@@ -0,0 +1,2 @@
+os_type: debian
+os_version: "6.0"
diff --git a/distros/debian_7.0.yaml b/distros/debian_7.0.yaml
new file mode 100644
index 000000000..8100dc41e
--- /dev/null
+++ b/distros/debian_7.0.yaml
@@ -0,0 +1,2 @@
+os_type: debian
+os_version: "7.0"
diff --git a/distros/fedora_17.yaml b/distros/fedora_17.yaml
new file mode 100644
index 000000000..801053af0
--- /dev/null
+++ b/distros/fedora_17.yaml
@@ -0,0 +1,2 @@
+os_type: fedora
+os_version: "17"
diff --git a/distros/fedora_18.yaml b/distros/fedora_18.yaml
new file mode 100644
index 000000000..07872aa7e
--- /dev/null
+++ b/distros/fedora_18.yaml
@@ -0,0 +1,2 @@
+os_type: fedora
+os_version: "18"
diff --git a/distros/fedora_19.yaml b/distros/fedora_19.yaml
new file mode 100644
index 000000000..5bac8acee
--- /dev/null
+++ b/distros/fedora_19.yaml
@@ -0,0 +1,2 @@
+os_type: fedora
+os_version: "19"
diff --git a/distros/opensuse_12.2.yaml b/distros/opensuse_12.2.yaml
new file mode 100644
index 000000000..ee9f877a2
--- /dev/null
+++ b/distros/opensuse_12.2.yaml
@@ -0,0 +1,2 @@
+os_type: opensuse
+os_version: "12.2"
diff --git a/distros/rhel_6.3.yaml b/distros/rhel_6.3.yaml
new file mode 100644
index 000000000..6a8edcd56
--- /dev/null
+++ b/distros/rhel_6.3.yaml
@@ -0,0 +1,2 @@
+os_type: rhel
+os_version: "6.3"
diff --git a/distros/rhel_6.4.yaml b/distros/rhel_6.4.yaml
new file mode 100644
index 000000000..522549583
--- /dev/null
+++ b/distros/rhel_6.4.yaml
@@ -0,0 +1,2 @@
+os_type: rhel
+os_version: "6.4"
diff --git a/distros/sles_11-sp2.yaml b/distros/sles_11-sp2.yaml
new file mode 100644
index 000000000..df9c3ca01
--- /dev/null
+++ b/distros/sles_11-sp2.yaml
@@ -0,0 +1,2 @@
+os_type: sles
+os_version: "11-sp2"
diff --git a/distros/ubuntu_12.04.yaml b/distros/ubuntu_12.04.yaml
new file mode 100644
index 000000000..dbc3a8d9c
--- /dev/null
+++ b/distros/ubuntu_12.04.yaml
@@ -0,0 +1,2 @@
+os_type: ubuntu
+os_version: "12.04"
diff --git a/distros/ubuntu_12.10.yaml b/distros/ubuntu_12.10.yaml
new file mode 100644
index 000000000..ab655676e
--- /dev/null
+++ b/distros/ubuntu_12.10.yaml
@@ -0,0 +1,2 @@
+os_type: ubuntu
+os_version: "12.10"
diff --git a/examples/3node_ceph.yaml b/examples/3node_ceph.yaml
deleted file mode 100644
index 16544f341..000000000
--- a/examples/3node_ceph.yaml
+++ /dev/null
@@ -1,15 +0,0 @@
-roles:
-- [mon.0, mds.0, osd.0]
-- [mon.1, osd.1]
-- [mon.2, client.0]
-
-tasks:
-- install:
-- ceph:
-- kclient: [client.0]
-- interactive:
-
-targets:
- ubuntu@: ssh-rsa
- ubuntu@: ssh-rsa
- ubuntu@: ssh-rsa
diff --git a/examples/3node_rgw.yaml b/examples/3node_rgw.yaml
deleted file mode 100644
index a21dab01f..000000000
--- a/examples/3node_rgw.yaml
+++ /dev/null
@@ -1,24 +0,0 @@
-interactive-on-error: true
-overrides:
- ceph:
- branch: master
- fs: xfs
-roles:
-- - mon.a
- - mon.c
- - osd.0
-- - mon.b
- - mds.a
- - osd.1
-- - client.0
-tasks:
-- install:
-- ceph: null
-- rgw:
- - client.0
-- interactive:
-
-targets:
- ubuntu@: ssh-rsa
- ubuntu@: ssh-rsa
- ubuntu@: ssh-rsa
diff --git a/examples/parallel_example.yaml b/examples/parallel_example.yaml
deleted file mode 100644
index d1491358b..000000000
--- a/examples/parallel_example.yaml
+++ /dev/null
@@ -1,20 +0,0 @@
-interactive-on-error: true
-overrides:
-roles:
-- - test0
- - test1
-- - test0
- - test1
-- - test0
-tasks:
-- install:
-- parallel_example:
- - test0
- - test1
-
-targets:
- ubuntu@: ssh-rsa
- ubuntu@: ssh-rsa
- ubuntu@: ssh-rsa
-
-
diff --git a/hammer.sh b/hammer.sh
deleted file mode 100755
index 30af3f375..000000000
--- a/hammer.sh
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/bin/sh -ex
-
-if [ $1 = "-a" ]; then
- shift
- job=$1
- log="--archive $job.out"
-else
- job=$1
- log=""
-fi
-
-test -e $1
-
-teuthology-nuke -t $job
-
-title() {
- echo '\[\033]0;hammer '$job' '$N' passes\007\]'
-}
-
-N=0
-title
-[ -n "$log" ] && [ -d $job.out ] && rm -rf $job.out
-while teuthology $log $job $2 $3 $4
-do
- date
- N=$(($N+1))
- echo "$job: $N passes"
- [ -n "$log" ] && rm -rf $job.out
- title
-done
-echo "$job: $N passes, then failure."
diff --git a/overrides/whitelist_wrongly_marked_down.yaml b/overrides/whitelist_wrongly_marked_down.yaml
new file mode 100644
index 000000000..5cf329fa0
--- /dev/null
+++ b/overrides/whitelist_wrongly_marked_down.yaml
@@ -0,0 +1,10 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - wrongly marked me down
+ conf:
+ mds:
+ debug mds: 20
+ debug ms: 1
+ client:
+ debug client: 10
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
deleted file mode 100644
index 8c5b8d0ec..000000000
--- a/requirements.txt
+++ /dev/null
@@ -1,18 +0,0 @@
-# 0.14 switches to libev, that means bootstrap needs to change too
-gevent == 0.13.6
-# 1.7.7 has AES-128-CBC support for SSH keys, that's needed
-MySQL-python == 1.2.3
-PyYAML
-argparse >= 1.2.1
-beanstalkc >= 0.2.0
-boto >= 2.0b4
-bunch >= 1.0.0
-configobj
-httplib2
-paramiko >= 1.7.7
-pexpect
-requests == 0.14.0
-
-# Test Dependencies
-# nose >=1.0.0
-# fudge >=1.0.3
diff --git a/roles/3-simple.yaml b/roles/3-simple.yaml
deleted file mode 100644
index ac2b3917a..000000000
--- a/roles/3-simple.yaml
+++ /dev/null
@@ -1,4 +0,0 @@
-roles:
-- [mon.a, mds.a, osd.0]
-- [mon.b, mds.a-s, osd.1]
-- [mon.c, client.0]
diff --git a/roles/overrides.yaml b/roles/overrides.yaml
deleted file mode 100644
index 2a28b3332..000000000
--- a/roles/overrides.yaml
+++ /dev/null
@@ -1,10 +0,0 @@
-nuke-on-error: true
-kernel:
- branch: master
-overrides:
- ceph:
- branch: BRANCH_NAME
- log-whitelist:
- - 'clocks not synchronized'
-tasks:
-- chef:
diff --git a/schedule_suite.sh b/schedule_suite.sh
deleted file mode 100755
index ca620556c..000000000
--- a/schedule_suite.sh
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/bin/sh -e
-
-suite=$1
-ceph=$2
-kernel=$3
-email=$4
-flavor=$5
-teuthology_branch=$6
-mtype=$7
-template=$8
-distro=$9
-
-if [ -z "$email" ]; then
- echo "usage: $0 [flavor] [teuthology-branch] [machinetype] [template] [distro]"
- echo " flavor can be 'basic', 'gcov', 'notcmalloc'."
- exit 1
-fi
-
-[ -z "$flavor" ] && flavor='basic'
-
-[ -z "$distro" ] && distro='ubuntu'
-
-if [ "$kernel" = "-" ]
-then
- kernelvalue=""
-else
- KERNEL_SHA1=`wget http://gitbuilder.ceph.com/kernel-deb-precise-x86_64-basic/ref/$kernel/sha1 -O- 2>/dev/null`
- [ -z "$KERNEL_SHA1" ] && echo "kernel branch $kernel dne" && exit 1
- kernelvalue="kernel:
- kdb: true
- sha1: $KERNEL_SHA1"
-fi
-##
-test ! -d ~/src/ceph-qa-suite && echo "error: expects to find ~/src/ceph-qa-suite" && exit 1
-test ! -d ~/src/teuthology/virtualenv/bin && echo "error: expects to find ~/src/teuthology/virtualenv/bin" && exit 1
-
-## get sha1
-CEPH_SHA1=`wget http://gitbuilder.ceph.com/ceph-deb-precise-x86_64-$flavor/ref/$ceph/sha1 -O- 2>/dev/null`
-
-[ -z "$CEPH_SHA1" ] && echo "ceph branch $ceph dne" && exit 1
-
-
-if [ -n "$teuthology_branch" ] && wget http://github.com/ceph/s3-tests/tree/$teuthology_branch -O- 2>/dev/null >/dev/null ; then
- s3branch=$teuthology_branch
-elif wget http://github.com/ceph/s3-tests/tree/$ceph -O- 2>/dev/null >/dev/null ; then
- s3branch=$ceph
-else
- echo "branch $ceph not in s3-tests.git; will use master for s3tests"
- s3branch='master'
-fi
-echo "s3branch $s3branch"
-
-if [ -z "$teuthology_branch" ]; then
- if wget http://github.com/ceph/teuthology/tree/$ceph -O- 2>/dev/null >/dev/null ; then
- teuthology_branch=$ceph
- else
- echo "branch $ceph not in teuthology.git; will use master for teuthology"
- teuthology_branch='master'
- fi
-fi
-echo "teuthology branch $teuthology_branch"
-
-[ -z "$mtype" ] && mtype="plana"
-
-## always include this
-fn="/tmp/schedule.suite.$$"
-trap "rm $fn" EXIT
-cat < $fn
-teuthology_branch: $teuthology_branch
-$kernelvalue
-nuke-on-error: true
-machine_type: $mtype
-os_type: $distro
-tasks:
-- chef:
-- clock.check:
-overrides:
- workunit:
- sha1: $CEPH_SHA1
- s3tests:
- branch: $s3branch
- install:
- ceph:
- sha1: $CEPH_SHA1
- ceph:
- sha1: $CEPH_SHA1
- conf:
- mon:
- debug ms: 1
- debug mon: 20
- debug paxos: 20
- log-whitelist:
- - slow request
- ceph-deploy:
- branch:
- dev: $ceph
- conf:
- mon:
- debug mon: 1
- debug paxos: 20
- debug ms: 20
- client:
- log file: /var/log/ceph/ceph-\$name.\$pid.log
- admin_socket:
- branch: $ceph
-EOF
-
-if [ "$flavor" = "gcov" ]; then
- cat <> $fn
- coverage: yes
-EOF
-fi
-
-## template, too?
-if [ -n "$template" ]; then
- sed s/CEPH_SHA1/$CEPH_SHA1/ $template | sed s/KERNEL_SHA1/$KERNEL_SHA1/ >> $fn
-fi
-
-##
-stamp=`date +%Y-%m-%d_%H:%M:%S`
-name=`whoami`"-$stamp-$suite-$ceph-$kernel-$flavor-$mtype"
-
-echo "name $name"
-
-~/src/teuthology/virtualenv/bin/teuthology-suite -v $fn \
- --collections ~/src/ceph-qa-suite/suites/$suite/* \
- --email $email \
- --timeout 36000 \
- --name $name \
- --worker $mtype
diff --git a/setup.py b/setup.py
deleted file mode 100644
index 7fe4d1e41..000000000
--- a/setup.py
+++ /dev/null
@@ -1,32 +0,0 @@
-from setuptools import setup, find_packages
-
-setup(
- name='teuthology',
- version='0.0.1',
- packages=find_packages(),
-
- author='Tommi Virtanen',
- author_email='tommi.virtanen@dreamhost.com',
- description='Ceph test runner',
- license='MIT',
- keywords='ceph testing ssh cluster',
-
- # to find the code associated with entry point
- # A.B:foo first cd into directory A, open file B
- # and find sub foo
- entry_points={
- 'console_scripts': [
- 'teuthology = teuthology.run:main',
- 'teuthology-nuke = teuthology.nuke:main',
- 'teuthology-suite = teuthology.suite:main',
- 'teuthology-ls = teuthology.suite:ls',
- 'teuthology-worker = teuthology.queue:worker',
- 'teuthology-lock = teuthology.lock:main',
- 'teuthology-schedule = teuthology.run:schedule',
- 'teuthology-updatekeys = teuthology.lock:update_hostkeys',
- 'teuthology-coverage = teuthology.coverage:analyze',
- 'teuthology-results = teuthology.suite:results',
- ],
- },
-
- )
diff --git a/teuthology/__init__.py b/suites/big/rados-thrash/%
similarity index 100%
rename from teuthology/__init__.py
rename to suites/big/rados-thrash/%
diff --git a/suites/big/rados-thrash/ceph/ceph.yaml b/suites/big/rados-thrash/ceph/ceph.yaml
new file mode 100644
index 000000000..2030acb90
--- /dev/null
+++ b/suites/big/rados-thrash/ceph/ceph.yaml
@@ -0,0 +1,3 @@
+tasks:
+- install:
+- ceph:
diff --git a/suites/big/rados-thrash/clusters/big.yaml b/suites/big/rados-thrash/clusters/big.yaml
new file mode 100644
index 000000000..18197ad85
--- /dev/null
+++ b/suites/big/rados-thrash/clusters/big.yaml
@@ -0,0 +1,68 @@
+roles:
+- [osd.0, osd.1, osd.2, client.0, mon.a]
+- [osd.3, osd.4, osd.5, client.1, mon.b]
+- [osd.6, osd.7, osd.8, client.2, mon.c]
+- [osd.9, osd.10, osd.11, client.3, mon.d]
+- [osd.12, osd.13, osd.14, client.4, mon.e]
+- [osd.15, osd.16, osd.17, client.5]
+- [osd.18, osd.19, osd.20, client.6]
+- [osd.21, osd.22, osd.23, client.7]
+- [osd.24, osd.25, osd.26, client.8]
+- [osd.27, osd.28, osd.29, client.9]
+- [osd.30, osd.31, osd.32, client.10]
+- [osd.33, osd.34, osd.35, client.11]
+- [osd.36, osd.37, osd.38, client.12]
+- [osd.39, osd.40, osd.41, client.13]
+- [osd.42, osd.43, osd.44, client.14]
+- [osd.45, osd.46, osd.47, client.15]
+- [osd.48, osd.49, osd.50, client.16]
+- [osd.51, osd.52, osd.53, client.17]
+- [osd.54, osd.55, osd.56, client.18]
+- [osd.57, osd.58, osd.59, client.19]
+- [osd.60, osd.61, osd.62, client.20]
+- [osd.63, osd.64, osd.65, client.21]
+- [osd.66, osd.67, osd.68, client.22]
+- [osd.69, osd.70, osd.71, client.23]
+- [osd.72, osd.73, osd.74, client.24]
+- [osd.75, osd.76, osd.77, client.25]
+- [osd.78, osd.79, osd.80, client.26]
+- [osd.81, osd.82, osd.83, client.27]
+- [osd.84, osd.85, osd.86, client.28]
+- [osd.87, osd.88, osd.89, client.29]
+- [osd.90, osd.91, osd.92, client.30]
+- [osd.93, osd.94, osd.95, client.31]
+- [osd.96, osd.97, osd.98, client.32]
+- [osd.99, osd.100, osd.101, client.33]
+- [osd.102, osd.103, osd.104, client.34]
+- [osd.105, osd.106, osd.107, client.35]
+- [osd.108, osd.109, osd.110, client.36]
+- [osd.111, osd.112, osd.113, client.37]
+- [osd.114, osd.115, osd.116, client.38]
+- [osd.117, osd.118, osd.119, client.39]
+- [osd.120, osd.121, osd.122, client.40]
+- [osd.123, osd.124, osd.125, client.41]
+- [osd.126, osd.127, osd.128, client.42]
+- [osd.129, osd.130, osd.131, client.43]
+- [osd.132, osd.133, osd.134, client.44]
+- [osd.135, osd.136, osd.137, client.45]
+- [osd.138, osd.139, osd.140, client.46]
+- [osd.141, osd.142, osd.143, client.47]
+- [osd.144, osd.145, osd.146, client.48]
+- [osd.147, osd.148, osd.149, client.49]
+- [osd.150, osd.151, osd.152, client.50]
+#- [osd.153, osd.154, osd.155, client.51]
+#- [osd.156, osd.157, osd.158, client.52]
+#- [osd.159, osd.160, osd.161, client.53]
+#- [osd.162, osd.163, osd.164, client.54]
+#- [osd.165, osd.166, osd.167, client.55]
+#- [osd.168, osd.169, osd.170, client.56]
+#- [osd.171, osd.172, osd.173, client.57]
+#- [osd.174, osd.175, osd.176, client.58]
+#- [osd.177, osd.178, osd.179, client.59]
+#- [osd.180, osd.181, osd.182, client.60]
+#- [osd.183, osd.184, osd.185, client.61]
+#- [osd.186, osd.187, osd.188, client.62]
+#- [osd.189, osd.190, osd.191, client.63]
+#- [osd.192, osd.193, osd.194, client.64]
+#- [osd.195, osd.196, osd.197, client.65]
+#- [osd.198, osd.199, osd.200, client.66]
diff --git a/suites/big/rados-thrash/clusters/medium.yaml b/suites/big/rados-thrash/clusters/medium.yaml
new file mode 100644
index 000000000..48b66dd5c
--- /dev/null
+++ b/suites/big/rados-thrash/clusters/medium.yaml
@@ -0,0 +1,22 @@
+roles:
+- [osd.0, osd.1, osd.2, client.0, mon.a]
+- [osd.3, osd.4, osd.5, client.1, mon.b]
+- [osd.6, osd.7, osd.8, client.2, mon.c]
+- [osd.9, osd.10, osd.11, client.3, mon.d]
+- [osd.12, osd.13, osd.14, client.4, mon.e]
+- [osd.15, osd.16, osd.17, client.5]
+- [osd.18, osd.19, osd.20, client.6]
+- [osd.21, osd.22, osd.23, client.7]
+- [osd.24, osd.25, osd.26, client.8]
+- [osd.27, osd.28, osd.29, client.9]
+- [osd.30, osd.31, osd.32, client.10]
+- [osd.33, osd.34, osd.35, client.11]
+- [osd.36, osd.37, osd.38, client.12]
+- [osd.39, osd.40, osd.41, client.13]
+- [osd.42, osd.43, osd.44, client.14]
+- [osd.45, osd.46, osd.47, client.15]
+- [osd.48, osd.49, osd.50, client.16]
+- [osd.51, osd.52, osd.53, client.17]
+- [osd.54, osd.55, osd.56, client.18]
+- [osd.57, osd.58, osd.59, client.19]
+- [osd.60, osd.61, osd.62, client.20]
diff --git a/suites/big/rados-thrash/clusters/small.yaml b/suites/big/rados-thrash/clusters/small.yaml
new file mode 100644
index 000000000..b5a79906c
--- /dev/null
+++ b/suites/big/rados-thrash/clusters/small.yaml
@@ -0,0 +1,6 @@
+roles:
+- [osd.0, osd.1, osd.2, client.0, mon.a]
+- [osd.3, osd.4, osd.5, client.1, mon.b]
+- [osd.6, osd.7, osd.8, client.2, mon.c]
+- [osd.9, osd.10, osd.11, client.3, mon.d]
+- [osd.12, osd.13, osd.14, client.4, mon.e]
diff --git a/suites/big/rados-thrash/thrashers/default.yaml b/suites/big/rados-thrash/thrashers/default.yaml
new file mode 100644
index 000000000..7fc179a59
--- /dev/null
+++ b/suites/big/rados-thrash/thrashers/default.yaml
@@ -0,0 +1,11 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+tasks:
+- thrashosds:
+ thrash_primary_affinity: false
+ timeout: 1200
+ chance_pgnum_grow: 1
+ chance_pgpnum_fix: 1
diff --git a/suites/big/rados-thrash/workloads/snaps-few-objects.yaml b/suites/big/rados-thrash/workloads/snaps-few-objects.yaml
new file mode 100644
index 000000000..ee696eb76
--- /dev/null
+++ b/suites/big/rados-thrash/workloads/snaps-few-objects.yaml
@@ -0,0 +1,12 @@
+tasks:
+- rados:
+ ops: 4000
+ max_seconds: 3600
+ objects: 50
+ op_weights:
+ read: 100
+ write: 100
+ delete: 50
+ snap_create: 50
+ snap_remove: 50
+ rollback: 50
diff --git a/teuthology/orchestra/__init__.py b/suites/ceph-deploy/fs/%
similarity index 100%
rename from teuthology/orchestra/__init__.py
rename to suites/ceph-deploy/fs/%
diff --git a/suites/ceph-deploy/fs/distro/centos_6.4.yaml b/suites/ceph-deploy/fs/distro/centos_6.4.yaml
new file mode 120000
index 000000000..822e83005
--- /dev/null
+++ b/suites/ceph-deploy/fs/distro/centos_6.4.yaml
@@ -0,0 +1 @@
+../../../../distros/centos_6.4.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/fs/distro/debian_7.0.yaml b/suites/ceph-deploy/fs/distro/debian_7.0.yaml
new file mode 120000
index 000000000..a0462d83c
--- /dev/null
+++ b/suites/ceph-deploy/fs/distro/debian_7.0.yaml
@@ -0,0 +1 @@
+../../../../distros/debian_7.0.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/fs/distro/fedora_18.yaml b/suites/ceph-deploy/fs/distro/fedora_18.yaml
new file mode 120000
index 000000000..6c838b574
--- /dev/null
+++ b/suites/ceph-deploy/fs/distro/fedora_18.yaml
@@ -0,0 +1 @@
+../../../../distros/fedora_18.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/fs/distro/rhel_6.3.yaml b/suites/ceph-deploy/fs/distro/rhel_6.3.yaml
new file mode 120000
index 000000000..5a5a123c9
--- /dev/null
+++ b/suites/ceph-deploy/fs/distro/rhel_6.3.yaml
@@ -0,0 +1 @@
+../../../../distros/rhel_6.3.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/fs/distro/ubuntu_12.04.yaml b/suites/ceph-deploy/fs/distro/ubuntu_12.04.yaml
new file mode 120000
index 000000000..249af2a1a
--- /dev/null
+++ b/suites/ceph-deploy/fs/distro/ubuntu_12.04.yaml
@@ -0,0 +1 @@
+../../../../distros/ubuntu_12.04.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/fs/tasks/cfuse_workunit_suites_blogbench.yaml b/suites/ceph-deploy/fs/tasks/cfuse_workunit_suites_blogbench.yaml
new file mode 100644
index 000000000..e5f00bc2b
--- /dev/null
+++ b/suites/ceph-deploy/fs/tasks/cfuse_workunit_suites_blogbench.yaml
@@ -0,0 +1,17 @@
+roles:
+- - mon.a
+ - mds.0
+ - osd.0
+- - mon.b
+ - osd.1
+- - client.0
+tasks:
+- install:
+ extras: yes
+- ssh_keys:
+- ceph-deploy:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - suites/blogbench.sh
diff --git a/suites/ceph-deploy/fs/tasks/cfuse_workunit_suites_dbench.yaml b/suites/ceph-deploy/fs/tasks/cfuse_workunit_suites_dbench.yaml
new file mode 100644
index 000000000..a76ee42a6
--- /dev/null
+++ b/suites/ceph-deploy/fs/tasks/cfuse_workunit_suites_dbench.yaml
@@ -0,0 +1,17 @@
+roles:
+- - mon.a
+ - mds.0
+ - osd.0
+- - mon.b
+ - osd.1
+- - client.0
+tasks:
+- install:
+ extras: yes
+- ssh_keys:
+- ceph-deploy:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - suites/dbench.sh
diff --git a/suites/ceph-deploy/fs/tasks/cfuse_workunit_suites_fsstress.yaml b/suites/ceph-deploy/fs/tasks/cfuse_workunit_suites_fsstress.yaml
new file mode 100644
index 000000000..b9de17851
--- /dev/null
+++ b/suites/ceph-deploy/fs/tasks/cfuse_workunit_suites_fsstress.yaml
@@ -0,0 +1,17 @@
+roles:
+- - mon.a
+ - mds.0
+ - osd.0
+- - mon.b
+ - osd.1
+- - client.0
+tasks:
+- install:
+ extras: yes
+- ssh_keys:
+- ceph-deploy:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - suites/fsstress.sh
diff --git a/teuthology/orchestra/test/__init__.py b/suites/ceph-deploy/rados/%
similarity index 100%
rename from teuthology/orchestra/test/__init__.py
rename to suites/ceph-deploy/rados/%
diff --git a/suites/ceph-deploy/rados/distro/centos_6.4.yaml b/suites/ceph-deploy/rados/distro/centos_6.4.yaml
new file mode 120000
index 000000000..822e83005
--- /dev/null
+++ b/suites/ceph-deploy/rados/distro/centos_6.4.yaml
@@ -0,0 +1 @@
+../../../../distros/centos_6.4.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/rados/distro/debian_7.0.yaml b/suites/ceph-deploy/rados/distro/debian_7.0.yaml
new file mode 120000
index 000000000..a0462d83c
--- /dev/null
+++ b/suites/ceph-deploy/rados/distro/debian_7.0.yaml
@@ -0,0 +1 @@
+../../../../distros/debian_7.0.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/rados/distro/fedora_18.yaml b/suites/ceph-deploy/rados/distro/fedora_18.yaml
new file mode 120000
index 000000000..6c838b574
--- /dev/null
+++ b/suites/ceph-deploy/rados/distro/fedora_18.yaml
@@ -0,0 +1 @@
+../../../../distros/fedora_18.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/rados/distro/rhel_6.3.yaml b/suites/ceph-deploy/rados/distro/rhel_6.3.yaml
new file mode 120000
index 000000000..5a5a123c9
--- /dev/null
+++ b/suites/ceph-deploy/rados/distro/rhel_6.3.yaml
@@ -0,0 +1 @@
+../../../../distros/rhel_6.3.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/rados/distro/ubuntu_12.04.yaml b/suites/ceph-deploy/rados/distro/ubuntu_12.04.yaml
new file mode 120000
index 000000000..249af2a1a
--- /dev/null
+++ b/suites/ceph-deploy/rados/distro/ubuntu_12.04.yaml
@@ -0,0 +1 @@
+../../../../distros/ubuntu_12.04.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/rados/tasks/rados_api_tests.yaml b/suites/ceph-deploy/rados/tasks/rados_api_tests.yaml
new file mode 100644
index 000000000..16f98fd95
--- /dev/null
+++ b/suites/ceph-deploy/rados/tasks/rados_api_tests.yaml
@@ -0,0 +1,18 @@
+roles:
+- - mon.a
+ - mds.0
+ - osd.0
+ - osd.1
+- - mon.b
+ - osd.2
+ - osd.3
+- - client.0
+tasks:
+- install:
+ extras: yes
+- ssh_keys:
+- ceph-deploy:
+- workunit:
+ clients:
+ client.0:
+ - rados/test.sh
diff --git a/suites/ceph-deploy/rados/tasks/rados_python.yaml b/suites/ceph-deploy/rados/tasks/rados_python.yaml
new file mode 100644
index 000000000..d3819ce87
--- /dev/null
+++ b/suites/ceph-deploy/rados/tasks/rados_python.yaml
@@ -0,0 +1,19 @@
+roles:
+- - mon.a
+ - mds.0
+ - osd.0
+ - osd.1
+- - mon.b
+ - osd.2
+ - osd.3
+- - client.0
+tasks:
+- install:
+ extras: yes
+- ssh_keys:
+- ceph-deploy:
+- workunit:
+ clients:
+ client.0:
+ - rados/test_python.sh
+
diff --git a/suites/ceph-deploy/rados/tasks/rados_workunit_loadgen_big.yaml b/suites/ceph-deploy/rados/tasks/rados_workunit_loadgen_big.yaml
new file mode 100644
index 000000000..a4633b7a0
--- /dev/null
+++ b/suites/ceph-deploy/rados/tasks/rados_workunit_loadgen_big.yaml
@@ -0,0 +1,19 @@
+roles:
+- - mon.a
+ - mds.0
+ - osd.0
+ - osd.1
+- - mon.b
+ - osd.2
+ - osd.3
+- - client.0
+tasks:
+- install:
+ extras: yes
+- ssh_keys:
+- ceph-deploy:
+- workunit:
+ clients:
+ all:
+ - rados/load-gen-big.sh
+
diff --git a/teuthology/task/__init__.py b/suites/ceph-deploy/rbd/%
similarity index 100%
rename from teuthology/task/__init__.py
rename to suites/ceph-deploy/rbd/%
diff --git a/suites/ceph-deploy/rbd/distro/centos_6.4.yaml b/suites/ceph-deploy/rbd/distro/centos_6.4.yaml
new file mode 120000
index 000000000..822e83005
--- /dev/null
+++ b/suites/ceph-deploy/rbd/distro/centos_6.4.yaml
@@ -0,0 +1 @@
+../../../../distros/centos_6.4.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/rbd/distro/debian_7.0.yaml b/suites/ceph-deploy/rbd/distro/debian_7.0.yaml
new file mode 120000
index 000000000..a0462d83c
--- /dev/null
+++ b/suites/ceph-deploy/rbd/distro/debian_7.0.yaml
@@ -0,0 +1 @@
+../../../../distros/debian_7.0.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/rbd/distro/fedora_18.yaml b/suites/ceph-deploy/rbd/distro/fedora_18.yaml
new file mode 120000
index 000000000..6c838b574
--- /dev/null
+++ b/suites/ceph-deploy/rbd/distro/fedora_18.yaml
@@ -0,0 +1 @@
+../../../../distros/fedora_18.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/rbd/distro/rhel_6.3.yaml b/suites/ceph-deploy/rbd/distro/rhel_6.3.yaml
new file mode 120000
index 000000000..5a5a123c9
--- /dev/null
+++ b/suites/ceph-deploy/rbd/distro/rhel_6.3.yaml
@@ -0,0 +1 @@
+../../../../distros/rhel_6.3.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/rbd/distro/ubuntu_12.04.yaml b/suites/ceph-deploy/rbd/distro/ubuntu_12.04.yaml
new file mode 120000
index 000000000..249af2a1a
--- /dev/null
+++ b/suites/ceph-deploy/rbd/distro/ubuntu_12.04.yaml
@@ -0,0 +1 @@
+../../../../distros/ubuntu_12.04.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/rbd/tasks/rbd_api_tests_old_format.yaml b/suites/ceph-deploy/rbd/tasks/rbd_api_tests_old_format.yaml
new file mode 100644
index 000000000..cb4906fdb
--- /dev/null
+++ b/suites/ceph-deploy/rbd/tasks/rbd_api_tests_old_format.yaml
@@ -0,0 +1,16 @@
+roles:
+- - mon.a
+ - mds.0
+ - osd.0
+- - mon.b
+ - osd.1
+- - client.0
+tasks:
+- install:
+ extras: yes
+- ssh_keys:
+- ceph-deploy:
+- workunit:
+ clients:
+ client.0:
+ - rbd/test_librbd.sh
diff --git a/suites/ceph-deploy/rbd/tasks/rbd_cli_tests.yaml b/suites/ceph-deploy/rbd/tasks/rbd_cli_tests.yaml
new file mode 100644
index 000000000..3b33295cc
--- /dev/null
+++ b/suites/ceph-deploy/rbd/tasks/rbd_cli_tests.yaml
@@ -0,0 +1,16 @@
+roles:
+- - mon.a
+ - mds.0
+ - osd.0
+- - mon.b
+ - osd.1
+- - client.0
+tasks:
+- install:
+ extras: yes
+- ssh_keys:
+- ceph-deploy:
+- workunit:
+ clients:
+ client.0:
+ - rbd/run_cli_tests.sh
diff --git a/suites/ceph-deploy/rbd/tasks/rbd_cls_test.yaml b/suites/ceph-deploy/rbd/tasks/rbd_cls_test.yaml
new file mode 100644
index 000000000..db9bf1797
--- /dev/null
+++ b/suites/ceph-deploy/rbd/tasks/rbd_cls_test.yaml
@@ -0,0 +1,16 @@
+roles:
+- - mon.a
+ - mds.0
+ - osd.0
+- - mon.b
+ - osd.1
+- - client.0
+tasks:
+- install:
+ extras: yes
+- ssh_keys:
+- ceph-deploy:
+- workunit:
+ clients:
+ client.0:
+ - cls/test_cls_rbd.sh
diff --git a/suites/ceph-deploy/rbd/tasks/rbd_python_api_tests.yaml b/suites/ceph-deploy/rbd/tasks/rbd_python_api_tests.yaml
new file mode 100644
index 000000000..32cf6dba3
--- /dev/null
+++ b/suites/ceph-deploy/rbd/tasks/rbd_python_api_tests.yaml
@@ -0,0 +1,17 @@
+roles:
+- - mon.a
+ - mds.0
+ - osd.0
+ - osd.1
+- - mon.b
+ - osd.2
+- - client.0
+tasks:
+- install:
+ extras: yes
+- ssh_keys:
+- ceph-deploy:
+- workunit:
+ clients:
+ client.0:
+ - rbd/test_librbd_python.sh
diff --git a/teuthology/task_util/__init__.py b/suites/ceph-deploy/singleton/%
similarity index 100%
rename from teuthology/task_util/__init__.py
rename to suites/ceph-deploy/singleton/%
diff --git a/suites/ceph-deploy/singleton/all/basic-test.yaml b/suites/ceph-deploy/singleton/all/basic-test.yaml
new file mode 100644
index 000000000..4b228f5d1
--- /dev/null
+++ b/suites/ceph-deploy/singleton/all/basic-test.yaml
@@ -0,0 +1,20 @@
+roles:
+- - mon.a
+ - mds.0
+ - osd.0
+ - osd.1
+- - mon.b
+ - osd.2
+ - osd.3
+- - client.0
+
+tasks:
+- install:
+ extras: yes
+- ssh_keys:
+- ceph-deploy:
+- workunit:
+ clients:
+ client.0:
+ - suites/blogbench.sh
+
diff --git a/suites/ceph-deploy/singleton/distro/centos_6.4.yaml b/suites/ceph-deploy/singleton/distro/centos_6.4.yaml
new file mode 120000
index 000000000..822e83005
--- /dev/null
+++ b/suites/ceph-deploy/singleton/distro/centos_6.4.yaml
@@ -0,0 +1 @@
+../../../../distros/centos_6.4.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/singleton/distro/debian_7.0.yaml b/suites/ceph-deploy/singleton/distro/debian_7.0.yaml
new file mode 120000
index 000000000..a0462d83c
--- /dev/null
+++ b/suites/ceph-deploy/singleton/distro/debian_7.0.yaml
@@ -0,0 +1 @@
+../../../../distros/debian_7.0.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/singleton/distro/fedora_18.yaml b/suites/ceph-deploy/singleton/distro/fedora_18.yaml
new file mode 120000
index 000000000..6c838b574
--- /dev/null
+++ b/suites/ceph-deploy/singleton/distro/fedora_18.yaml
@@ -0,0 +1 @@
+../../../../distros/fedora_18.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/singleton/distro/rhel_6.3.yaml b/suites/ceph-deploy/singleton/distro/rhel_6.3.yaml
new file mode 120000
index 000000000..5a5a123c9
--- /dev/null
+++ b/suites/ceph-deploy/singleton/distro/rhel_6.3.yaml
@@ -0,0 +1 @@
+../../../../distros/rhel_6.3.yaml
\ No newline at end of file
diff --git a/suites/ceph-deploy/singleton/distro/ubuntu_12.04.yaml b/suites/ceph-deploy/singleton/distro/ubuntu_12.04.yaml
new file mode 120000
index 000000000..249af2a1a
--- /dev/null
+++ b/suites/ceph-deploy/singleton/distro/ubuntu_12.04.yaml
@@ -0,0 +1 @@
+../../../../distros/ubuntu_12.04.yaml
\ No newline at end of file
diff --git a/teuthology/test/__init__.py b/suites/experimental/multimds/%
similarity index 100%
rename from teuthology/test/__init__.py
rename to suites/experimental/multimds/%
diff --git a/suites/experimental/multimds/clusters/7-multimds.yaml b/suites/experimental/multimds/clusters/7-multimds.yaml
new file mode 100644
index 000000000..17cfd7b3d
--- /dev/null
+++ b/suites/experimental/multimds/clusters/7-multimds.yaml
@@ -0,0 +1,8 @@
+roles:
+- [mon.a, mds.a, mds.a-s]
+- [mon.b, mds.b, mds.b-s]
+- [mon.c, mds.c, mds.c-s]
+- [osd.0]
+- [osd.1]
+- [osd.2]
+- [client.0]
diff --git a/suites/experimental/multimds/tasks/fsstress_thrash_subtrees.yaml b/suites/experimental/multimds/tasks/fsstress_thrash_subtrees.yaml
new file mode 100644
index 000000000..bee01a835
--- /dev/null
+++ b/suites/experimental/multimds/tasks/fsstress_thrash_subtrees.yaml
@@ -0,0 +1,15 @@
+tasks:
+- install:
+- ceph:
+ conf:
+ mds:
+ mds thrash exports: 1
+ mds debug subtrees: 1
+ mds debug scatterstat: 1
+ mds verify scatter: 1
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - suites/fsstress.sh
+
diff --git a/suites/fs/basic/% b/suites/fs/basic/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/fs/basic/clusters/fixed-3.yaml b/suites/fs/basic/clusters/fixed-3.yaml
new file mode 120000
index 000000000..a3ac9fc4d
--- /dev/null
+++ b/suites/fs/basic/clusters/fixed-3.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-3.yaml
\ No newline at end of file
diff --git a/suites/fs/basic/fs/btrfs.yaml b/suites/fs/basic/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/fs/basic/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/fs/basic/overrides/whitelist_wrongly_marked_down.yaml b/suites/fs/basic/overrides/whitelist_wrongly_marked_down.yaml
new file mode 120000
index 000000000..08f746bf8
--- /dev/null
+++ b/suites/fs/basic/overrides/whitelist_wrongly_marked_down.yaml
@@ -0,0 +1 @@
+../../../../overrides/whitelist_wrongly_marked_down.yaml
\ No newline at end of file
diff --git a/suites/fs/basic/tasks/cfuse_workunit_kernel_untar_build.yaml b/suites/fs/basic/tasks/cfuse_workunit_kernel_untar_build.yaml
new file mode 100644
index 000000000..b44bcea8d
--- /dev/null
+++ b/suites/fs/basic/tasks/cfuse_workunit_kernel_untar_build.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - kernel_untar_build.sh
diff --git a/suites/fs/basic/tasks/cfuse_workunit_misc.yaml b/suites/fs/basic/tasks/cfuse_workunit_misc.yaml
new file mode 100644
index 000000000..84dbe5db3
--- /dev/null
+++ b/suites/fs/basic/tasks/cfuse_workunit_misc.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - misc
diff --git a/suites/fs/basic/tasks/cfuse_workunit_misc_test_o_trunc.yaml b/suites/fs/basic/tasks/cfuse_workunit_misc_test_o_trunc.yaml
new file mode 100644
index 000000000..5afb84d66
--- /dev/null
+++ b/suites/fs/basic/tasks/cfuse_workunit_misc_test_o_trunc.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - fs/test_o_trunc.sh
diff --git a/suites/fs/basic/tasks/cfuse_workunit_suites_blogbench.yaml b/suites/fs/basic/tasks/cfuse_workunit_suites_blogbench.yaml
new file mode 100644
index 000000000..ed9d92d5b
--- /dev/null
+++ b/suites/fs/basic/tasks/cfuse_workunit_suites_blogbench.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/blogbench.sh
diff --git a/suites/fs/basic/tasks/cfuse_workunit_suites_dbench.yaml b/suites/fs/basic/tasks/cfuse_workunit_suites_dbench.yaml
new file mode 100644
index 000000000..e678ed47c
--- /dev/null
+++ b/suites/fs/basic/tasks/cfuse_workunit_suites_dbench.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/dbench.sh
diff --git a/suites/fs/basic/tasks/cfuse_workunit_suites_ffsb.yaml b/suites/fs/basic/tasks/cfuse_workunit_suites_ffsb.yaml
new file mode 100644
index 000000000..652a3a62f
--- /dev/null
+++ b/suites/fs/basic/tasks/cfuse_workunit_suites_ffsb.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+- ceph:
+ conf:
+ osd:
+ filestore flush min: 0
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/ffsb.sh
diff --git a/suites/fs/basic/tasks/cfuse_workunit_suites_fsstress.yaml b/suites/fs/basic/tasks/cfuse_workunit_suites_fsstress.yaml
new file mode 100644
index 000000000..b58487c07
--- /dev/null
+++ b/suites/fs/basic/tasks/cfuse_workunit_suites_fsstress.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/fsstress.sh
diff --git a/suites/fs/basic/tasks/cfuse_workunit_suites_fsx.yaml b/suites/fs/basic/tasks/cfuse_workunit_suites_fsx.yaml
new file mode 100644
index 000000000..9b0c61492
--- /dev/null
+++ b/suites/fs/basic/tasks/cfuse_workunit_suites_fsx.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/fsx.sh
diff --git a/suites/fs/basic/tasks/cfuse_workunit_suites_fsync.yaml b/suites/fs/basic/tasks/cfuse_workunit_suites_fsync.yaml
new file mode 100644
index 000000000..c1cd14c8f
--- /dev/null
+++ b/suites/fs/basic/tasks/cfuse_workunit_suites_fsync.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/fsync-tester.sh
diff --git a/suites/fs/basic/tasks/cfuse_workunit_suites_iogen.yaml b/suites/fs/basic/tasks/cfuse_workunit_suites_iogen.yaml
new file mode 100644
index 000000000..8221c44b2
--- /dev/null
+++ b/suites/fs/basic/tasks/cfuse_workunit_suites_iogen.yaml
@@ -0,0 +1,9 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/iogen.sh
+
diff --git a/suites/fs/basic/tasks/cfuse_workunit_suites_iozone.yaml b/suites/fs/basic/tasks/cfuse_workunit_suites_iozone.yaml
new file mode 100644
index 000000000..dc6df2f70
--- /dev/null
+++ b/suites/fs/basic/tasks/cfuse_workunit_suites_iozone.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse: [client.0]
+- workunit:
+ clients:
+ all:
+ - suites/iozone.sh
diff --git a/suites/fs/basic/tasks/cfuse_workunit_suites_pjd.yaml b/suites/fs/basic/tasks/cfuse_workunit_suites_pjd.yaml
new file mode 100644
index 000000000..b3ebffb2c
--- /dev/null
+++ b/suites/fs/basic/tasks/cfuse_workunit_suites_pjd.yaml
@@ -0,0 +1,15 @@
+tasks:
+- install:
+- ceph:
+ conf:
+ client:
+ debug ms: 1
+ debug client: 20
+ mds:
+ debug ms: 1
+ debug mds: 20
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/pjd.sh
diff --git a/suites/fs/basic/tasks/cfuse_workunit_suites_tiobench.yaml b/suites/fs/basic/tasks/cfuse_workunit_suites_tiobench.yaml
new file mode 100644
index 000000000..d819e47b9
--- /dev/null
+++ b/suites/fs/basic/tasks/cfuse_workunit_suites_tiobench.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/tiobench.sh
diff --git a/suites/fs/basic/tasks/cfuse_workunit_suites_truncate_delay.yaml b/suites/fs/basic/tasks/cfuse_workunit_suites_truncate_delay.yaml
new file mode 100644
index 000000000..3aa5f8825
--- /dev/null
+++ b/suites/fs/basic/tasks/cfuse_workunit_suites_truncate_delay.yaml
@@ -0,0 +1,15 @@
+tasks:
+- install:
+- ceph:
+ conf:
+ client:
+ ms_inject_delay_probability: 1
+ ms_inject_delay_type: osd
+ ms_inject_delay_max: 5
+ client_oc_max_dirty_age: 1
+- ceph-fuse:
+- exec:
+ client.0:
+ - dd if=/dev/zero of=./foo count=100
+ - sleep 2
+ - truncate --size 0 ./foo
diff --git a/suites/fs/basic/tasks/cfuse_workunit_trivial_sync.yaml b/suites/fs/basic/tasks/cfuse_workunit_trivial_sync.yaml
new file mode 100644
index 000000000..1515491a7
--- /dev/null
+++ b/suites/fs/basic/tasks/cfuse_workunit_trivial_sync.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all: [misc/trivial_sync.sh]
diff --git a/suites/fs/basic/tasks/libcephfs_interface_tests.yaml b/suites/fs/basic/tasks/libcephfs_interface_tests.yaml
new file mode 100644
index 000000000..22d1f1421
--- /dev/null
+++ b/suites/fs/basic/tasks/libcephfs_interface_tests.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - libcephfs/test.sh
diff --git a/suites/fs/basic/tasks/libcephfs_java.yaml b/suites/fs/basic/tasks/libcephfs_java.yaml
new file mode 100644
index 000000000..b391ae6d2
--- /dev/null
+++ b/suites/fs/basic/tasks/libcephfs_java.yaml
@@ -0,0 +1,13 @@
+overrides:
+ install:
+ ceph:
+ extra_packages: [libcephfs1, libcephfs-java, libcephfs-jni]
+
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - libcephfs-java/test.sh
diff --git a/suites/fs/multiclient/% b/suites/fs/multiclient/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/fs/multiclient/clusters/three_clients.yaml b/suites/fs/multiclient/clusters/three_clients.yaml
new file mode 100644
index 000000000..fd2535fd4
--- /dev/null
+++ b/suites/fs/multiclient/clusters/three_clients.yaml
@@ -0,0 +1,5 @@
+roles:
+- [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1, osd.2]
+- [client.2]
+- [client.1]
+- [client.0]
diff --git a/suites/fs/multiclient/clusters/two_clients.yaml b/suites/fs/multiclient/clusters/two_clients.yaml
new file mode 100644
index 000000000..2258befd8
--- /dev/null
+++ b/suites/fs/multiclient/clusters/two_clients.yaml
@@ -0,0 +1,4 @@
+roles:
+- [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1, osd.2]
+- [client.1]
+- [client.0]
diff --git a/suites/fs/multiclient/fs/btrfs.yaml b/suites/fs/multiclient/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/fs/multiclient/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/fs/multiclient/mount/ceph-fuse.yaml b/suites/fs/multiclient/mount/ceph-fuse.yaml
new file mode 100644
index 000000000..37ac5b69e
--- /dev/null
+++ b/suites/fs/multiclient/mount/ceph-fuse.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
diff --git a/suites/fs/multiclient/mount/kclient.yaml.disabled b/suites/fs/multiclient/mount/kclient.yaml.disabled
new file mode 100644
index 000000000..c18db8f5e
--- /dev/null
+++ b/suites/fs/multiclient/mount/kclient.yaml.disabled
@@ -0,0 +1,4 @@
+tasks:
+- install:
+- ceph:
+- kclient:
diff --git a/suites/fs/multiclient/tasks/fsx-mpi.yaml.disabled b/suites/fs/multiclient/tasks/fsx-mpi.yaml.disabled
new file mode 100644
index 000000000..255a68795
--- /dev/null
+++ b/suites/fs/multiclient/tasks/fsx-mpi.yaml.disabled
@@ -0,0 +1,16 @@
+tasks:
+- pexec:
+ clients:
+ - cd $TESTDIR
+ - wget http://ceph.com/qa/fsx-mpi.c
+ - mpicc fsx-mpi.c -o fsx-mpi
+ - rm fsx-mpi.c
+ - ln -s $TESTDIR/mnt.* $TESTDIR/gmnt
+- ssh_keys:
+- mpi:
+ exec: $TESTDIR/fsx-mpi 1MB -N 50000 -p 10000 -l 1048576
+ workdir: $TESTDIR/gmnt
+- pexec:
+ all:
+ - rm $TESTDIR/gmnt
+ - rm $TESTDIR/fsx-mpi
diff --git a/suites/fs/multiclient/tasks/ior-shared-file.yaml b/suites/fs/multiclient/tasks/ior-shared-file.yaml
new file mode 100644
index 000000000..56795781d
--- /dev/null
+++ b/suites/fs/multiclient/tasks/ior-shared-file.yaml
@@ -0,0 +1,22 @@
+tasks:
+- pexec:
+ clients:
+ - cd $TESTDIR
+ - wget http://ceph.com/qa/ior.tbz2
+ - tar xvfj ior.tbz2
+ - cd ior
+ - ./configure
+ - make
+ - make install DESTDIR=$TESTDIR/binary/
+ - cd $TESTDIR/
+ - rm ior.tbz2
+ - rm -r ior
+ - ln -s $TESTDIR/mnt.* $TESTDIR/gmnt
+- ssh_keys:
+- mpi:
+ exec: $TESTDIR/binary/usr/local/bin/ior -e -w -r -W -b 10m -a POSIX -o $TESTDIR/gmnt/ior.testfile
+- pexec:
+ all:
+ - rm -f $TESTDIR/gmnt/ior.testfile
+ - rm -f $TESTDIR/gmnt
+ - rm -rf $TESTDIR/binary
diff --git a/suites/fs/multiclient/tasks/mdtest.yaml b/suites/fs/multiclient/tasks/mdtest.yaml
new file mode 100644
index 000000000..0d1aee08b
--- /dev/null
+++ b/suites/fs/multiclient/tasks/mdtest.yaml
@@ -0,0 +1,19 @@
+tasks:
+- pexec:
+ clients:
+ - cd $TESTDIR
+ - wget http://ceph.com/qa/mdtest-1.9.3.tgz
+ - mkdir mdtest-1.9.3
+ - cd mdtest-1.9.3
+ - tar xvfz $TESTDIR/mdtest-1.9.3.tgz
+ - rm $TESTDIR/mdtest-1.9.3.tgz
+ - MPI_CC=mpicc make
+ - ln -s $TESTDIR/mnt.* $TESTDIR/gmnt
+- ssh_keys:
+- mpi:
+ exec: $TESTDIR/mdtest-1.9.3/mdtest -d $TESTDIR/gmnt -I 20 -z 5 -b 2 -R
+- pexec:
+ all:
+ - rm -f $TESTDIR/gmnt
+ - rm -rf $TESTDIR/mdtest-1.9.3
+ - rm -rf $TESTDIR/._mdtest-1.9.3
\ No newline at end of file
diff --git a/suites/fs/samba/% b/suites/fs/samba/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/fs/samba/clusters/samba-basic.yaml b/suites/fs/samba/clusters/samba-basic.yaml
new file mode 100644
index 000000000..caced4a26
--- /dev/null
+++ b/suites/fs/samba/clusters/samba-basic.yaml
@@ -0,0 +1,3 @@
+roles:
+- [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1]
+- [samba.0, client.0, client.1]
diff --git a/suites/fs/samba/fs/btrfs.yaml b/suites/fs/samba/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/fs/samba/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/fs/samba/install/install.yaml b/suites/fs/samba/install/install.yaml
new file mode 100644
index 000000000..12f1e8522
--- /dev/null
+++ b/suites/fs/samba/install/install.yaml
@@ -0,0 +1,6 @@
+tasks:
+- install:
+- install:
+ project: samba
+ extra_packages: ['samba']
+- ceph:
diff --git a/suites/fs/samba/mount/fuse.yaml b/suites/fs/samba/mount/fuse.yaml
new file mode 100644
index 000000000..d00ffdb48
--- /dev/null
+++ b/suites/fs/samba/mount/fuse.yaml
@@ -0,0 +1,6 @@
+tasks:
+- ceph-fuse: [client.0]
+- samba:
+ samba.0:
+ ceph: "{testdir}/mnt.0"
+
diff --git a/suites/fs/samba/mount/kclient.yaml b/suites/fs/samba/mount/kclient.yaml
new file mode 100644
index 000000000..56590adcb
--- /dev/null
+++ b/suites/fs/samba/mount/kclient.yaml
@@ -0,0 +1,6 @@
+tasks:
+- kclient: [client.0]
+- samba:
+ samba.0:
+ ceph: "{testdir}/mnt.0"
+
diff --git a/suites/fs/samba/mount/native.yaml b/suites/fs/samba/mount/native.yaml
new file mode 100644
index 000000000..09b8c1c4e
--- /dev/null
+++ b/suites/fs/samba/mount/native.yaml
@@ -0,0 +1,2 @@
+tasks:
+- samba:
diff --git a/suites/fs/samba/mount/noceph.yaml b/suites/fs/samba/mount/noceph.yaml
new file mode 100644
index 000000000..3cad4740d
--- /dev/null
+++ b/suites/fs/samba/mount/noceph.yaml
@@ -0,0 +1,5 @@
+tasks:
+- localdir: [client.0]
+- samba:
+ samba.0:
+ ceph: "{testdir}/mnt.0"
diff --git a/suites/fs/samba/workload/cifs-dbench.yaml b/suites/fs/samba/workload/cifs-dbench.yaml
new file mode 100644
index 000000000..c13c1c099
--- /dev/null
+++ b/suites/fs/samba/workload/cifs-dbench.yaml
@@ -0,0 +1,8 @@
+tasks:
+- cifs-mount:
+ client.1:
+ share: ceph
+- workunit:
+ clients:
+ client.1:
+ - suites/dbench.sh
diff --git a/suites/fs/samba/workload/cifs-fsstress.yaml b/suites/fs/samba/workload/cifs-fsstress.yaml
new file mode 100644
index 000000000..ff003af34
--- /dev/null
+++ b/suites/fs/samba/workload/cifs-fsstress.yaml
@@ -0,0 +1,8 @@
+tasks:
+- cifs-mount:
+ client.1:
+ share: ceph
+- workunit:
+ clients:
+ client.1:
+ - suites/fsstress.sh
diff --git a/suites/fs/samba/workload/cifs-kernel-build.yaml.disabled b/suites/fs/samba/workload/cifs-kernel-build.yaml.disabled
new file mode 100644
index 000000000..ab9ff8ac7
--- /dev/null
+++ b/suites/fs/samba/workload/cifs-kernel-build.yaml.disabled
@@ -0,0 +1,9 @@
+tasks:
+- cifs-mount:
+ client.1:
+ share: ceph
+- workunit:
+ clients:
+ client.1:
+ - kernel_untar_build.sh
+
diff --git a/suites/fs/samba/workload/cifs-tiobench.yaml b/suites/fs/samba/workload/cifs-tiobench.yaml
new file mode 100644
index 000000000..aed757201
--- /dev/null
+++ b/suites/fs/samba/workload/cifs-tiobench.yaml
@@ -0,0 +1,8 @@
+tasks:
+- cifs-mount:
+ client.1:
+ share: ceph
+- workunit:
+ clients:
+ client.1:
+ - suites/tiobench.sh
diff --git a/suites/fs/samba/workload/smbtorture.yaml b/suites/fs/samba/workload/smbtorture.yaml
new file mode 100644
index 000000000..a1355fa1e
--- /dev/null
+++ b/suites/fs/samba/workload/smbtorture.yaml
@@ -0,0 +1,39 @@
+tasks:
+- pexec:
+ client.1:
+# - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.lock
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.fdpass
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.unlink
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.attr
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.trans2
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.negnowait
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.dir1
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.deny1
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.deny2
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.deny3
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.denydos
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.ntdeny1
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.ntdeny2
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.tcon
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.tcondev
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.vuid
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.rw1
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.open
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.defer_open
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.xcopy
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.rename
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.properties
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.mangle
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.openattr
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.chkpath
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.secleak
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.disconnect
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.samba3error
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.smb
+# - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.bench-holdcon
+# - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.bench-holdopen
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.bench-readwrite
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.bench-torture
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.scan-pipe_number
+ - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.scan-ioctl
+# - /usr/local/samba/bin/smbtorture --password=ubuntu //localhost/ceph base.scan-maxfid
diff --git a/suites/fs/thrash/% b/suites/fs/thrash/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/fs/thrash/ceph-thrash/default.yaml b/suites/fs/thrash/ceph-thrash/default.yaml
new file mode 100644
index 000000000..aefdf826c
--- /dev/null
+++ b/suites/fs/thrash/ceph-thrash/default.yaml
@@ -0,0 +1,2 @@
+tasks:
+- mds_thrash:
diff --git a/suites/fs/thrash/ceph/base.yaml b/suites/fs/thrash/ceph/base.yaml
new file mode 100644
index 000000000..2030acb90
--- /dev/null
+++ b/suites/fs/thrash/ceph/base.yaml
@@ -0,0 +1,3 @@
+tasks:
+- install:
+- ceph:
diff --git a/suites/fs/thrash/clusters/mds-1active-1standby.yaml b/suites/fs/thrash/clusters/mds-1active-1standby.yaml
new file mode 100644
index 000000000..7e951b958
--- /dev/null
+++ b/suites/fs/thrash/clusters/mds-1active-1standby.yaml
@@ -0,0 +1,4 @@
+roles:
+- [mon.a, mon.c, osd.0, osd.1, osd.2]
+- [mon.b, mds.a, osd.3, osd.4, osd.5]
+- [client.0, mds.b-s-a]
diff --git a/suites/fs/thrash/fs/btrfs.yaml b/suites/fs/thrash/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/fs/thrash/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/fs/thrash/msgr-failures/none.yaml b/suites/fs/thrash/msgr-failures/none.yaml
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/fs/thrash/msgr-failures/osd-mds-delay.yaml b/suites/fs/thrash/msgr-failures/osd-mds-delay.yaml
new file mode 100644
index 000000000..adcebc0ba
--- /dev/null
+++ b/suites/fs/thrash/msgr-failures/osd-mds-delay.yaml
@@ -0,0 +1,8 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 2500
+ mds inject delay type: osd mds
+ ms inject delay probability: .005
+ ms inject delay max: 1
diff --git a/suites/fs/thrash/overrides/whitelist_wrongly_marked_down.yaml b/suites/fs/thrash/overrides/whitelist_wrongly_marked_down.yaml
new file mode 120000
index 000000000..08f746bf8
--- /dev/null
+++ b/suites/fs/thrash/overrides/whitelist_wrongly_marked_down.yaml
@@ -0,0 +1 @@
+../../../../overrides/whitelist_wrongly_marked_down.yaml
\ No newline at end of file
diff --git a/suites/fs/thrash/tasks/cfuse_workunit_suites_fsstress.yaml b/suites/fs/thrash/tasks/cfuse_workunit_suites_fsstress.yaml
new file mode 100644
index 000000000..5908d951b
--- /dev/null
+++ b/suites/fs/thrash/tasks/cfuse_workunit_suites_fsstress.yaml
@@ -0,0 +1,6 @@
+tasks:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/fsstress.sh
diff --git a/suites/fs/thrash/tasks/cfuse_workunit_suites_pjd.yaml b/suites/fs/thrash/tasks/cfuse_workunit_suites_pjd.yaml
new file mode 100644
index 000000000..930bf4a67
--- /dev/null
+++ b/suites/fs/thrash/tasks/cfuse_workunit_suites_pjd.yaml
@@ -0,0 +1,6 @@
+tasks:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/pjd.sh
diff --git a/suites/fs/thrash/tasks/cfuse_workunit_trivial_sync.yaml b/suites/fs/thrash/tasks/cfuse_workunit_trivial_sync.yaml
new file mode 100644
index 000000000..cd729e0f6
--- /dev/null
+++ b/suites/fs/thrash/tasks/cfuse_workunit_trivial_sync.yaml
@@ -0,0 +1,5 @@
+tasks:
+- ceph-fuse:
+- workunit:
+ clients:
+ all: [misc/trivial_sync.sh]
diff --git a/suites/fs/traceless/% b/suites/fs/traceless/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/fs/traceless/clusters/fixed-3.yaml b/suites/fs/traceless/clusters/fixed-3.yaml
new file mode 120000
index 000000000..a3ac9fc4d
--- /dev/null
+++ b/suites/fs/traceless/clusters/fixed-3.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-3.yaml
\ No newline at end of file
diff --git a/suites/fs/traceless/fs/btrfs.yaml b/suites/fs/traceless/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/fs/traceless/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/fs/traceless/overrides/whitelist_wrongly_marked_down.yaml b/suites/fs/traceless/overrides/whitelist_wrongly_marked_down.yaml
new file mode 120000
index 000000000..08f746bf8
--- /dev/null
+++ b/suites/fs/traceless/overrides/whitelist_wrongly_marked_down.yaml
@@ -0,0 +1 @@
+../../../../overrides/whitelist_wrongly_marked_down.yaml
\ No newline at end of file
diff --git a/suites/fs/traceless/tasks/cfuse_workunit_suites_blogbench.yaml b/suites/fs/traceless/tasks/cfuse_workunit_suites_blogbench.yaml
new file mode 100644
index 000000000..ed9d92d5b
--- /dev/null
+++ b/suites/fs/traceless/tasks/cfuse_workunit_suites_blogbench.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/blogbench.sh
diff --git a/suites/fs/traceless/tasks/cfuse_workunit_suites_dbench.yaml b/suites/fs/traceless/tasks/cfuse_workunit_suites_dbench.yaml
new file mode 100644
index 000000000..e678ed47c
--- /dev/null
+++ b/suites/fs/traceless/tasks/cfuse_workunit_suites_dbench.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/dbench.sh
diff --git a/suites/fs/traceless/tasks/cfuse_workunit_suites_ffsb.yaml b/suites/fs/traceless/tasks/cfuse_workunit_suites_ffsb.yaml
new file mode 100644
index 000000000..652a3a62f
--- /dev/null
+++ b/suites/fs/traceless/tasks/cfuse_workunit_suites_ffsb.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+- ceph:
+ conf:
+ osd:
+ filestore flush min: 0
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/ffsb.sh
diff --git a/suites/fs/traceless/tasks/cfuse_workunit_suites_fsstress.yaml b/suites/fs/traceless/tasks/cfuse_workunit_suites_fsstress.yaml
new file mode 100644
index 000000000..b58487c07
--- /dev/null
+++ b/suites/fs/traceless/tasks/cfuse_workunit_suites_fsstress.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/fsstress.sh
diff --git a/suites/fs/traceless/tasks/cfuse_workunit_suites_tiobench.yaml b/suites/fs/traceless/tasks/cfuse_workunit_suites_tiobench.yaml
new file mode 100644
index 000000000..d819e47b9
--- /dev/null
+++ b/suites/fs/traceless/tasks/cfuse_workunit_suites_tiobench.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/tiobench.sh
diff --git a/suites/fs/traceless/traceless/50pc.yaml b/suites/fs/traceless/traceless/50pc.yaml
new file mode 100644
index 000000000..e0418bcb2
--- /dev/null
+++ b/suites/fs/traceless/traceless/50pc.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ mds:
+ mds inject traceless reply probability: .5
diff --git a/suites/fs/verify/% b/suites/fs/verify/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/fs/verify/clusters/fixed-3.yaml b/suites/fs/verify/clusters/fixed-3.yaml
new file mode 120000
index 000000000..a3ac9fc4d
--- /dev/null
+++ b/suites/fs/verify/clusters/fixed-3.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-3.yaml
\ No newline at end of file
diff --git a/suites/fs/verify/fs/btrfs.yaml b/suites/fs/verify/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/fs/verify/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/fs/verify/overrides/whitelist_wrongly_marked_down.yaml b/suites/fs/verify/overrides/whitelist_wrongly_marked_down.yaml
new file mode 120000
index 000000000..08f746bf8
--- /dev/null
+++ b/suites/fs/verify/overrides/whitelist_wrongly_marked_down.yaml
@@ -0,0 +1 @@
+../../../../overrides/whitelist_wrongly_marked_down.yaml
\ No newline at end of file
diff --git a/suites/fs/verify/tasks/cfuse_workunit_suites_dbench.yaml b/suites/fs/verify/tasks/cfuse_workunit_suites_dbench.yaml
new file mode 100644
index 000000000..73319776f
--- /dev/null
+++ b/suites/fs/verify/tasks/cfuse_workunit_suites_dbench.yaml
@@ -0,0 +1,12 @@
+tasks:
+- install:
+- ceph:
+ conf:
+ client:
+ debug client: 1/20
+ debug ms: 0/10
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/dbench.sh
diff --git a/suites/fs/verify/tasks/cfuse_workunit_suites_fsstress.yaml b/suites/fs/verify/tasks/cfuse_workunit_suites_fsstress.yaml
new file mode 100644
index 000000000..b58487c07
--- /dev/null
+++ b/suites/fs/verify/tasks/cfuse_workunit_suites_fsstress.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/fsstress.sh
diff --git a/suites/fs/verify/tasks/libcephfs_interface_tests.yaml b/suites/fs/verify/tasks/libcephfs_interface_tests.yaml
new file mode 100644
index 000000000..22d1f1421
--- /dev/null
+++ b/suites/fs/verify/tasks/libcephfs_interface_tests.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - libcephfs/test.sh
diff --git a/suites/fs/verify/validater/lockdep.yaml b/suites/fs/verify/validater/lockdep.yaml
new file mode 100644
index 000000000..25f84355c
--- /dev/null
+++ b/suites/fs/verify/validater/lockdep.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ lockdep: true
diff --git a/suites/fs/verify/validater/valgrind.yaml b/suites/fs/verify/validater/valgrind.yaml
new file mode 100644
index 000000000..c3d3aed48
--- /dev/null
+++ b/suites/fs/verify/validater/valgrind.yaml
@@ -0,0 +1,12 @@
+overrides:
+ install:
+ ceph:
+ flavor: notcmalloc
+ ceph:
+ valgrind:
+ mon: [--tool=memcheck, --leak-check=full, --show-reachable=yes]
+ osd: [--tool=memcheck]
+ mds: [--tool=memcheck]
+ ceph-fuse:
+ client.0:
+ valgrind: [--tool=memcheck, --leak-check=full, --show-reachable=yes]
diff --git a/suites/hadoop/basic/% b/suites/hadoop/basic/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/hadoop/basic/clusters/fixed-3.yaml b/suites/hadoop/basic/clusters/fixed-3.yaml
new file mode 100644
index 000000000..708d75117
--- /dev/null
+++ b/suites/hadoop/basic/clusters/fixed-3.yaml
@@ -0,0 +1,5 @@
+roles:
+- [mon.0, mds.0, osd.0, hadoop.master.0]
+- [mon.1, osd.1, hadoop.slave.0]
+- [mon.2, hadoop.slave.1, client.0]
+
diff --git a/suites/hadoop/basic/tasks/hadoop-internal.yaml b/suites/hadoop/basic/tasks/hadoop-internal.yaml
new file mode 100644
index 000000000..d131415aa
--- /dev/null
+++ b/suites/hadoop/basic/tasks/hadoop-internal.yaml
@@ -0,0 +1,13 @@
+overrides:
+ install:
+ ceph:
+ extra_packages: [libcephfs1, libcephfs-java, libcephfs-jni]
+
+tasks:
+- ssh_keys:
+- install:
+- ceph:
+- hadoop:
+- workunit:
+ clients:
+ client.0: [hadoop-internal-tests]
diff --git a/suites/hadoop/basic/tasks/wordcount.yaml b/suites/hadoop/basic/tasks/wordcount.yaml
new file mode 100644
index 000000000..bea6cb762
--- /dev/null
+++ b/suites/hadoop/basic/tasks/wordcount.yaml
@@ -0,0 +1,13 @@
+overrides:
+ install:
+ ceph:
+ extra_packages: [libcephfs1, libcephfs-java, libcephfs-jni]
+
+tasks:
+- ssh_keys:
+- install:
+- ceph:
+- hadoop:
+- workunit:
+ clients:
+ client.0: [hadoop-wordcount]
diff --git a/suites/kcephfs/cephfs/% b/suites/kcephfs/cephfs/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/kcephfs/cephfs/clusters/fixed-3.yaml b/suites/kcephfs/cephfs/clusters/fixed-3.yaml
new file mode 120000
index 000000000..a3ac9fc4d
--- /dev/null
+++ b/suites/kcephfs/cephfs/clusters/fixed-3.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-3.yaml
\ No newline at end of file
diff --git a/suites/kcephfs/cephfs/fs/btrfs.yaml b/suites/kcephfs/cephfs/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/kcephfs/cephfs/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/kcephfs/cephfs/tasks/kclient_workunit_direct_io.yaml b/suites/kcephfs/cephfs/tasks/kclient_workunit_direct_io.yaml
new file mode 100644
index 000000000..018a71f78
--- /dev/null
+++ b/suites/kcephfs/cephfs/tasks/kclient_workunit_direct_io.yaml
@@ -0,0 +1,9 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - direct_io
+
diff --git a/suites/kcephfs/cephfs/tasks/kclient_workunit_kclient.yaml b/suites/kcephfs/cephfs/tasks/kclient_workunit_kclient.yaml
new file mode 100644
index 000000000..d36ce74c7
--- /dev/null
+++ b/suites/kcephfs/cephfs/tasks/kclient_workunit_kclient.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all: [kclient]
diff --git a/suites/kcephfs/cephfs/tasks/kclient_workunit_kernel_untar_build.yaml b/suites/kcephfs/cephfs/tasks/kclient_workunit_kernel_untar_build.yaml
new file mode 100644
index 000000000..d969e5561
--- /dev/null
+++ b/suites/kcephfs/cephfs/tasks/kclient_workunit_kernel_untar_build.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - kernel_untar_build.sh
diff --git a/suites/kcephfs/cephfs/tasks/kclient_workunit_misc.yaml b/suites/kcephfs/cephfs/tasks/kclient_workunit_misc.yaml
new file mode 100644
index 000000000..02c67126b
--- /dev/null
+++ b/suites/kcephfs/cephfs/tasks/kclient_workunit_misc.yaml
@@ -0,0 +1,12 @@
+tasks:
+- install:
+- ceph:
+ conf:
+ mds:
+ debug mds: 20
+ debug ms: 1
+- kclient:
+- workunit:
+ clients:
+ all:
+ - misc
diff --git a/suites/kcephfs/cephfs/tasks/kclient_workunit_o_trunc.yaml b/suites/kcephfs/cephfs/tasks/kclient_workunit_o_trunc.yaml
new file mode 100644
index 000000000..6ec5e36cd
--- /dev/null
+++ b/suites/kcephfs/cephfs/tasks/kclient_workunit_o_trunc.yaml
@@ -0,0 +1,9 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - fs/test_o_trunc.sh
+
diff --git a/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_dbench.yaml b/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_dbench.yaml
new file mode 100644
index 000000000..77d045e87
--- /dev/null
+++ b/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_dbench.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - suites/dbench.sh
diff --git a/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_ffsb.yaml b/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_ffsb.yaml
new file mode 100644
index 000000000..2b88af692
--- /dev/null
+++ b/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_ffsb.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+- ceph:
+ conf:
+ osd:
+ filestore flush min: 0
+- kclient:
+- workunit:
+ clients:
+ all:
+ - suites/ffsb.sh
diff --git a/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_fsstress.yaml b/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_fsstress.yaml
new file mode 100644
index 000000000..10b84b8af
--- /dev/null
+++ b/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_fsstress.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - suites/fsstress.sh
diff --git a/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_fsync.yaml b/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_fsync.yaml
new file mode 100644
index 000000000..1b3f4d555
--- /dev/null
+++ b/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_fsync.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - suites/fsync-tester.sh
diff --git a/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_iozone.yaml b/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_iozone.yaml
new file mode 100644
index 000000000..bfe25f2f8
--- /dev/null
+++ b/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_iozone.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - suites/iozone.sh
diff --git a/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_pjd.yaml b/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_pjd.yaml
new file mode 100644
index 000000000..305de51e9
--- /dev/null
+++ b/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_pjd.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - suites/pjd.sh
diff --git a/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_tiobench.yaml b/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_tiobench.yaml
new file mode 100644
index 000000000..e4c342d95
--- /dev/null
+++ b/suites/kcephfs/cephfs/tasks/kclient_workunit_suites_tiobench.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - suites/tiobench.sh
diff --git a/suites/kcephfs/cephfs/tasks/kclient_workunit_trivial_sync.yaml b/suites/kcephfs/cephfs/tasks/kclient_workunit_trivial_sync.yaml
new file mode 100644
index 000000000..fc7931533
--- /dev/null
+++ b/suites/kcephfs/cephfs/tasks/kclient_workunit_trivial_sync.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all: [misc/trivial_sync.sh]
diff --git a/suites/kcephfs/thrash/% b/suites/kcephfs/thrash/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/kcephfs/thrash/clusters/fixed-3.yaml b/suites/kcephfs/thrash/clusters/fixed-3.yaml
new file mode 120000
index 000000000..a3ac9fc4d
--- /dev/null
+++ b/suites/kcephfs/thrash/clusters/fixed-3.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-3.yaml
\ No newline at end of file
diff --git a/suites/kcephfs/thrash/fs/btrfs.yaml b/suites/kcephfs/thrash/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/kcephfs/thrash/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/kcephfs/thrash/thrashers/default.yaml b/suites/kcephfs/thrash/thrashers/default.yaml
new file mode 100644
index 000000000..b822d7422
--- /dev/null
+++ b/suites/kcephfs/thrash/thrashers/default.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+- thrashosds:
+ thrash_primary_affinity: false
diff --git a/suites/kcephfs/thrash/thrashers/mon-thrasher.yaml b/suites/kcephfs/thrash/thrashers/mon-thrasher.yaml
new file mode 100644
index 000000000..90612f218
--- /dev/null
+++ b/suites/kcephfs/thrash/thrashers/mon-thrasher.yaml
@@ -0,0 +1,6 @@
+tasks:
+- install:
+- ceph:
+- mon_thrash:
+ revive_delay: 20
+ thrash_delay: 1
diff --git a/suites/kcephfs/thrash/workloads/kclient_workunit_suites_ffsb.yaml b/suites/kcephfs/thrash/workloads/kclient_workunit_suites_ffsb.yaml
new file mode 100644
index 000000000..0c4a1528d
--- /dev/null
+++ b/suites/kcephfs/thrash/workloads/kclient_workunit_suites_ffsb.yaml
@@ -0,0 +1,11 @@
+overrides:
+ ceph:
+ conf:
+ osd:
+ filestore flush min: 0
+tasks:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - suites/ffsb.sh
diff --git a/suites/kcephfs/thrash/workloads/kclient_workunit_suites_iozone.yaml b/suites/kcephfs/thrash/workloads/kclient_workunit_suites_iozone.yaml
new file mode 100644
index 000000000..832e0241b
--- /dev/null
+++ b/suites/kcephfs/thrash/workloads/kclient_workunit_suites_iozone.yaml
@@ -0,0 +1,6 @@
+tasks:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - suites/iozone.sh
diff --git a/suites/krbd/rbd-nomount/% b/suites/krbd/rbd-nomount/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/krbd/rbd-nomount/clusters/fixed-3.yaml b/suites/krbd/rbd-nomount/clusters/fixed-3.yaml
new file mode 120000
index 000000000..a3ac9fc4d
--- /dev/null
+++ b/suites/krbd/rbd-nomount/clusters/fixed-3.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-3.yaml
\ No newline at end of file
diff --git a/suites/krbd/rbd-nomount/fs/btrfs.yaml b/suites/krbd/rbd-nomount/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/krbd/rbd-nomount/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/krbd/rbd-nomount/install/ceph.yaml b/suites/krbd/rbd-nomount/install/ceph.yaml
new file mode 100644
index 000000000..2030acb90
--- /dev/null
+++ b/suites/krbd/rbd-nomount/install/ceph.yaml
@@ -0,0 +1,3 @@
+tasks:
+- install:
+- ceph:
diff --git a/suites/krbd/rbd-nomount/msgr-failures/few.yaml b/suites/krbd/rbd-nomount/msgr-failures/few.yaml
new file mode 100644
index 000000000..0de320d46
--- /dev/null
+++ b/suites/krbd/rbd-nomount/msgr-failures/few.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 5000
diff --git a/suites/krbd/rbd-nomount/msgr-failures/many.yaml b/suites/krbd/rbd-nomount/msgr-failures/many.yaml
new file mode 100644
index 000000000..86f8dde8a
--- /dev/null
+++ b/suites/krbd/rbd-nomount/msgr-failures/many.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 500
diff --git a/suites/krbd/rbd-nomount/tasks/rbd_concurrent.yaml b/suites/krbd/rbd-nomount/tasks/rbd_concurrent.yaml
new file mode 100644
index 000000000..675b98e73
--- /dev/null
+++ b/suites/krbd/rbd-nomount/tasks/rbd_concurrent.yaml
@@ -0,0 +1,10 @@
+tasks:
+- workunit:
+ clients:
+ all:
+ - rbd/concurrent.sh
+# Options for rbd/concurrent.sh (default values shown)
+# env:
+# RBD_CONCURRENT_ITER: 100
+# RBD_CONCURRENT_COUNT: 5
+# RBD_CONCURRENT_DELAY: 5
diff --git a/suites/krbd/rbd-nomount/tasks/rbd_image_read.yaml b/suites/krbd/rbd-nomount/tasks/rbd_image_read.yaml
new file mode 100644
index 000000000..e5017e118
--- /dev/null
+++ b/suites/krbd/rbd-nomount/tasks/rbd_image_read.yaml
@@ -0,0 +1,15 @@
+tasks:
+- workunit:
+ clients:
+ all:
+ - rbd/image_read.sh
+# Options for rbd/image_read.sh (default values shown)
+# env:
+# IMAGE_READ_LOCAL_FILES: 'false'
+# IMAGE_READ_FORMAT: '2'
+# IMAGE_READ_VERBOSE: 'true'
+# IMAGE_READ_PAGE_SIZE: '4096'
+# IMAGE_READ_OBJECT_ORDER: '22'
+# IMAGE_READ_TEST_CLONES: 'true'
+# IMAGE_READ_DOUBLE_ORDER: 'true'
+# IMAGE_READ_HALF_ORDER: 'false'
diff --git a/suites/krbd/rbd-nomount/tasks/rbd_kernel.yaml b/suites/krbd/rbd-nomount/tasks/rbd_kernel.yaml
new file mode 100644
index 000000000..aa155827c
--- /dev/null
+++ b/suites/krbd/rbd-nomount/tasks/rbd_kernel.yaml
@@ -0,0 +1,5 @@
+tasks:
+- workunit:
+ clients:
+ all:
+ - rbd/kernel.sh
diff --git a/suites/krbd/rbd-nomount/tasks/rbd_map_snapshot_io.yaml b/suites/krbd/rbd-nomount/tasks/rbd_map_snapshot_io.yaml
new file mode 100644
index 000000000..c1529398b
--- /dev/null
+++ b/suites/krbd/rbd-nomount/tasks/rbd_map_snapshot_io.yaml
@@ -0,0 +1,5 @@
+tasks:
+- workunit:
+ clients:
+ all:
+ - rbd/map-snapshot-io.sh
diff --git a/suites/krbd/rbd-nomount/tasks/rbd_map_unmap.yaml b/suites/krbd/rbd-nomount/tasks/rbd_map_unmap.yaml
new file mode 100644
index 000000000..c2160997c
--- /dev/null
+++ b/suites/krbd/rbd-nomount/tasks/rbd_map_unmap.yaml
@@ -0,0 +1,5 @@
+tasks:
+- workunit:
+ clients:
+ all:
+ - rbd/map-unmap.sh
diff --git a/suites/krbd/rbd-nomount/tasks/rbd_simple_big.yaml b/suites/krbd/rbd-nomount/tasks/rbd_simple_big.yaml
new file mode 100644
index 000000000..c493cfaf4
--- /dev/null
+++ b/suites/krbd/rbd-nomount/tasks/rbd_simple_big.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ clients:
+ all:
+ - rbd/simple_big.sh
+
diff --git a/suites/krbd/rbd/% b/suites/krbd/rbd/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/krbd/rbd/clusters/fixed-3.yaml b/suites/krbd/rbd/clusters/fixed-3.yaml
new file mode 120000
index 000000000..a3ac9fc4d
--- /dev/null
+++ b/suites/krbd/rbd/clusters/fixed-3.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-3.yaml
\ No newline at end of file
diff --git a/suites/krbd/rbd/fs/btrfs.yaml b/suites/krbd/rbd/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/krbd/rbd/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/krbd/rbd/msgr-failures/few.yaml b/suites/krbd/rbd/msgr-failures/few.yaml
new file mode 100644
index 000000000..0de320d46
--- /dev/null
+++ b/suites/krbd/rbd/msgr-failures/few.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 5000
diff --git a/suites/krbd/rbd/msgr-failures/many.yaml b/suites/krbd/rbd/msgr-failures/many.yaml
new file mode 100644
index 000000000..86f8dde8a
--- /dev/null
+++ b/suites/krbd/rbd/msgr-failures/many.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 500
diff --git a/suites/krbd/rbd/tasks/rbd_workunit_kernel_untar_build.yaml b/suites/krbd/rbd/tasks/rbd_workunit_kernel_untar_build.yaml
new file mode 100644
index 000000000..ef2a35dcc
--- /dev/null
+++ b/suites/krbd/rbd/tasks/rbd_workunit_kernel_untar_build.yaml
@@ -0,0 +1,9 @@
+tasks:
+- install:
+- ceph:
+- rbd:
+ all:
+- workunit:
+ clients:
+ all:
+ - kernel_untar_build.sh
diff --git a/suites/krbd/rbd/tasks/rbd_workunit_suites_dbench.yaml b/suites/krbd/rbd/tasks/rbd_workunit_suites_dbench.yaml
new file mode 100644
index 000000000..d779eea23
--- /dev/null
+++ b/suites/krbd/rbd/tasks/rbd_workunit_suites_dbench.yaml
@@ -0,0 +1,9 @@
+tasks:
+- install:
+- ceph:
+- rbd:
+ all:
+- workunit:
+ clients:
+ all:
+ - suites/dbench.sh
diff --git a/suites/krbd/rbd/tasks/rbd_workunit_suites_ffsb.yaml b/suites/krbd/rbd/tasks/rbd_workunit_suites_ffsb.yaml
new file mode 100644
index 000000000..5204bb87f
--- /dev/null
+++ b/suites/krbd/rbd/tasks/rbd_workunit_suites_ffsb.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+- ceph:
+- rbd:
+ all:
+ image_size: 20480
+- workunit:
+ clients:
+ all:
+ - suites/ffsb.sh
diff --git a/suites/krbd/rbd/tasks/rbd_workunit_suites_fsstress.yaml b/suites/krbd/rbd/tasks/rbd_workunit_suites_fsstress.yaml
new file mode 100644
index 000000000..f9d62fefc
--- /dev/null
+++ b/suites/krbd/rbd/tasks/rbd_workunit_suites_fsstress.yaml
@@ -0,0 +1,9 @@
+tasks:
+- install:
+- ceph:
+- rbd:
+ all:
+- workunit:
+ clients:
+ all:
+ - suites/fsstress.sh
diff --git a/suites/krbd/rbd/tasks/rbd_workunit_suites_fsstress_btrfs.yaml b/suites/krbd/rbd/tasks/rbd_workunit_suites_fsstress_btrfs.yaml
new file mode 100644
index 000000000..f3930a898
--- /dev/null
+++ b/suites/krbd/rbd/tasks/rbd_workunit_suites_fsstress_btrfs.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+- ceph:
+- rbd:
+ all:
+ fs_type: btrfs
+- workunit:
+ clients:
+ all:
+ - suites/fsstress.sh
diff --git a/suites/krbd/rbd/tasks/rbd_workunit_suites_fsstress_ext4.yaml b/suites/krbd/rbd/tasks/rbd_workunit_suites_fsstress_ext4.yaml
new file mode 100644
index 000000000..f765b74a6
--- /dev/null
+++ b/suites/krbd/rbd/tasks/rbd_workunit_suites_fsstress_ext4.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+- ceph:
+- rbd:
+ all:
+ fs_type: ext4
+- workunit:
+ clients:
+ all:
+ - suites/fsstress.sh
diff --git a/suites/krbd/rbd/tasks/rbd_workunit_suites_fsx.yaml b/suites/krbd/rbd/tasks/rbd_workunit_suites_fsx.yaml
new file mode 100644
index 000000000..98c0849c5
--- /dev/null
+++ b/suites/krbd/rbd/tasks/rbd_workunit_suites_fsx.yaml
@@ -0,0 +1,9 @@
+tasks:
+- install:
+- ceph:
+- rbd:
+ all:
+- workunit:
+ clients:
+ all:
+ - suites/fsx.sh
diff --git a/suites/krbd/rbd/tasks/rbd_workunit_suites_iozone.yaml b/suites/krbd/rbd/tasks/rbd_workunit_suites_iozone.yaml
new file mode 100644
index 000000000..eb8f18d60
--- /dev/null
+++ b/suites/krbd/rbd/tasks/rbd_workunit_suites_iozone.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+- ceph:
+- rbd:
+ all:
+ image_size: 20480
+- workunit:
+ clients:
+ all:
+ - suites/iozone.sh
diff --git a/suites/krbd/rbd/tasks/rbd_workunit_suites_tiobench.yaml b/suites/krbd/rbd/tasks/rbd_workunit_suites_tiobench.yaml
new file mode 100644
index 000000000..18eb9962f
--- /dev/null
+++ b/suites/krbd/rbd/tasks/rbd_workunit_suites_tiobench.yaml
@@ -0,0 +1,9 @@
+tasks:
+- install:
+- ceph:
+- rbd:
+ all:
+- workunit:
+ clients:
+ all:
+ - suites/tiobench.sh
diff --git a/suites/krbd/rbd/tasks/rbd_workunit_trivial_sync.yaml b/suites/krbd/rbd/tasks/rbd_workunit_trivial_sync.yaml
new file mode 100644
index 000000000..89afeea2a
--- /dev/null
+++ b/suites/krbd/rbd/tasks/rbd_workunit_trivial_sync.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- rbd:
+ all:
+- workunit:
+ clients:
+ all: [misc/trivial_sync.sh]
diff --git a/suites/krbd/singleton/% b/suites/krbd/singleton/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/krbd/singleton/fs/btrfs.yaml b/suites/krbd/singleton/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/krbd/singleton/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/krbd/singleton/msgr-failures/few.yaml b/suites/krbd/singleton/msgr-failures/few.yaml
new file mode 100644
index 000000000..0de320d46
--- /dev/null
+++ b/suites/krbd/singleton/msgr-failures/few.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 5000
diff --git a/suites/krbd/singleton/msgr-failures/many.yaml b/suites/krbd/singleton/msgr-failures/many.yaml
new file mode 100644
index 000000000..86f8dde8a
--- /dev/null
+++ b/suites/krbd/singleton/msgr-failures/many.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 500
diff --git a/suites/krbd/singleton/tasks/rbd_xfstests.yaml b/suites/krbd/singleton/tasks/rbd_xfstests.yaml
new file mode 100644
index 000000000..2adb17c47
--- /dev/null
+++ b/suites/krbd/singleton/tasks/rbd_xfstests.yaml
@@ -0,0 +1,22 @@
+roles:
+- [mon.a, mon.c, osd.0, osd.1, osd.2]
+- [mon.b, mds.a, osd.3, osd.4, osd.5]
+- [client.0]
+- [client.1]
+- [client.2]
+tasks:
+- install:
+- ceph:
+- rbd.xfstests:
+ client.0:
+ tests: 1-9 11-15 17 19-21 26-29 31-34 41 46-54 56 61 63-67 69-70 74-76 78-79 84-89 91
+ test_image: 'test_image-0'
+ scratch_image: 'scratch_image-0'
+ client.1:
+ tests: 92 100 103 105 108 110 116-121 124 126 129-132
+ test_image: 'test_image-1'
+ scratch_image: 'scratch_image-1'
+ client.2:
+ tests: 133-135 137-141 164-167 184 187-190 192 194 196 199 201 203 214-216 220-227 234 236-238 241 243-249 253 257-259 261-262 269 273 275 277-278
+ test_image: 'test_image-2'
+ scratch_image: 'scratch_image-2'
diff --git a/suites/krbd/thrash/% b/suites/krbd/thrash/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/krbd/thrash/clusters/fixed-3.yaml b/suites/krbd/thrash/clusters/fixed-3.yaml
new file mode 120000
index 000000000..a3ac9fc4d
--- /dev/null
+++ b/suites/krbd/thrash/clusters/fixed-3.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-3.yaml
\ No newline at end of file
diff --git a/suites/krbd/thrash/fs/btrfs.yaml b/suites/krbd/thrash/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/krbd/thrash/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/krbd/thrash/thrashers/default.yaml b/suites/krbd/thrash/thrashers/default.yaml
new file mode 100644
index 000000000..b822d7422
--- /dev/null
+++ b/suites/krbd/thrash/thrashers/default.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+- thrashosds:
+ thrash_primary_affinity: false
diff --git a/suites/krbd/thrash/thrashers/mon-thrasher.yaml b/suites/krbd/thrash/thrashers/mon-thrasher.yaml
new file mode 100644
index 000000000..90612f218
--- /dev/null
+++ b/suites/krbd/thrash/thrashers/mon-thrasher.yaml
@@ -0,0 +1,6 @@
+tasks:
+- install:
+- ceph:
+- mon_thrash:
+ revive_delay: 20
+ thrash_delay: 1
diff --git a/suites/krbd/thrash/workloads/rbd_workunit_suites_ffsb.yaml b/suites/krbd/thrash/workloads/rbd_workunit_suites_ffsb.yaml
new file mode 100644
index 000000000..4ae7d6909
--- /dev/null
+++ b/suites/krbd/thrash/workloads/rbd_workunit_suites_ffsb.yaml
@@ -0,0 +1,8 @@
+tasks:
+- rbd:
+ all:
+ image_size: 20480
+- workunit:
+ clients:
+ all:
+ - suites/ffsb.sh
diff --git a/suites/krbd/thrash/workloads/rbd_workunit_suites_iozone.yaml.disabled b/suites/krbd/thrash/workloads/rbd_workunit_suites_iozone.yaml.disabled
new file mode 100644
index 000000000..d61ede1bd
--- /dev/null
+++ b/suites/krbd/thrash/workloads/rbd_workunit_suites_iozone.yaml.disabled
@@ -0,0 +1,8 @@
+tasks:
+- rbd:
+ all:
+ image_size: 20480
+- workunit:
+ clients:
+ all:
+ - suites/iozone.sh
diff --git a/suites/marginal/basic/% b/suites/marginal/basic/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/marginal/basic/clusters/fixed-3.yaml b/suites/marginal/basic/clusters/fixed-3.yaml
new file mode 100644
index 000000000..0038432af
--- /dev/null
+++ b/suites/marginal/basic/clusters/fixed-3.yaml
@@ -0,0 +1,4 @@
+roles:
+- [mon.a, mon.c, osd.0, osd.1, osd.2]
+- [mon.b, mds.a, osd.3, osd.4, osd.5]
+- [client.0]
diff --git a/suites/marginal/basic/fs/btrfs.yaml b/suites/marginal/basic/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/marginal/basic/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/marginal/basic/tasks/kclient_workunit_suites_blogbench.yaml b/suites/marginal/basic/tasks/kclient_workunit_suites_blogbench.yaml
new file mode 100644
index 000000000..4f25d8063
--- /dev/null
+++ b/suites/marginal/basic/tasks/kclient_workunit_suites_blogbench.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - suites/blogbench.sh
diff --git a/suites/marginal/basic/tasks/kclient_workunit_suites_fsx.yaml b/suites/marginal/basic/tasks/kclient_workunit_suites_fsx.yaml
new file mode 100644
index 000000000..a0d2e765b
--- /dev/null
+++ b/suites/marginal/basic/tasks/kclient_workunit_suites_fsx.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - suites/fsx.sh
diff --git a/suites/marginal/fs-misc/% b/suites/marginal/fs-misc/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/marginal/fs-misc/clusters/two_clients.yaml b/suites/marginal/fs-misc/clusters/two_clients.yaml
new file mode 100644
index 000000000..2258befd8
--- /dev/null
+++ b/suites/marginal/fs-misc/clusters/two_clients.yaml
@@ -0,0 +1,4 @@
+roles:
+- [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1, osd.2]
+- [client.1]
+- [client.0]
diff --git a/suites/marginal/fs-misc/fs/btrfs.yaml b/suites/marginal/fs-misc/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/marginal/fs-misc/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/marginal/fs-misc/tasks/locktest.yaml b/suites/marginal/fs-misc/tasks/locktest.yaml
new file mode 100644
index 000000000..444bb1f19
--- /dev/null
+++ b/suites/marginal/fs-misc/tasks/locktest.yaml
@@ -0,0 +1,5 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- locktest: [client.0, client.1]
diff --git a/suites/marginal/mds_restart/% b/suites/marginal/mds_restart/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/marginal/mds_restart/clusters/one_mds.yaml b/suites/marginal/mds_restart/clusters/one_mds.yaml
new file mode 100644
index 000000000..9e11c02a3
--- /dev/null
+++ b/suites/marginal/mds_restart/clusters/one_mds.yaml
@@ -0,0 +1,4 @@
+roles:
+- [mon.a, mon.b, mon.c, osd.0, osd.1, osd.2]
+- [mds.a]
+- [client.0]
diff --git a/suites/marginal/mds_restart/tasks/restart-workunit-backtraces.yaml b/suites/marginal/mds_restart/tasks/restart-workunit-backtraces.yaml
new file mode 100644
index 000000000..d086d4cf8
--- /dev/null
+++ b/suites/marginal/mds_restart/tasks/restart-workunit-backtraces.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+- ceph:
+ conf:
+ mds:
+ mds log segment size: 16384
+ mds log max segments: 1
+- restart:
+ exec:
+ client.0:
+ - test-backtraces.py
diff --git a/suites/marginal/multimds/% b/suites/marginal/multimds/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/marginal/multimds/clusters/3-node-3-mds.yaml b/suites/marginal/multimds/clusters/3-node-3-mds.yaml
new file mode 100644
index 000000000..088d9f0d3
--- /dev/null
+++ b/suites/marginal/multimds/clusters/3-node-3-mds.yaml
@@ -0,0 +1,5 @@
+roles:
+- [mon.a, mon.c, mds.a, osd.0, osd.1, osd.2]
+- [mon.b, mds.b, mds.c, osd.3, osd.4, osd.5]
+- [client.0]
+- [client.1]
diff --git a/suites/marginal/multimds/clusters/3-node-9-mds.yaml b/suites/marginal/multimds/clusters/3-node-9-mds.yaml
new file mode 100644
index 000000000..be824f0f5
--- /dev/null
+++ b/suites/marginal/multimds/clusters/3-node-9-mds.yaml
@@ -0,0 +1,5 @@
+roles:
+- [mon.a, mon.c, mds.a, mds.b, mds.c, mds.d, osd.0, osd.1, osd.2]
+- [mon.b, mds.e, mds.f, mds.g, mds.h, mds.i, osd.3, osd.4, osd.5]
+- [client.0]
+- [client.1]
diff --git a/suites/marginal/multimds/fs/btrfs.yaml b/suites/marginal/multimds/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/marginal/multimds/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/marginal/multimds/mounts/ceph-fuse.yaml b/suites/marginal/multimds/mounts/ceph-fuse.yaml
new file mode 100644
index 000000000..37ac5b69e
--- /dev/null
+++ b/suites/marginal/multimds/mounts/ceph-fuse.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
diff --git a/suites/marginal/multimds/mounts/kclient.yaml b/suites/marginal/multimds/mounts/kclient.yaml
new file mode 100644
index 000000000..c18db8f5e
--- /dev/null
+++ b/suites/marginal/multimds/mounts/kclient.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install:
+- ceph:
+- kclient:
diff --git a/suites/marginal/multimds/tasks/workunit_misc.yaml b/suites/marginal/multimds/tasks/workunit_misc.yaml
new file mode 100644
index 000000000..f1235e7a8
--- /dev/null
+++ b/suites/marginal/multimds/tasks/workunit_misc.yaml
@@ -0,0 +1,5 @@
+tasks:
+- workunit:
+ clients:
+ all:
+ - misc
diff --git a/suites/marginal/multimds/tasks/workunit_suites_blogbench.yaml b/suites/marginal/multimds/tasks/workunit_suites_blogbench.yaml
new file mode 100644
index 000000000..4c1fcc11e
--- /dev/null
+++ b/suites/marginal/multimds/tasks/workunit_suites_blogbench.yaml
@@ -0,0 +1,5 @@
+tasks:
+- workunit:
+ clients:
+ all:
+ - suites/blogbench.sh
diff --git a/suites/marginal/multimds/tasks/workunit_suites_dbench.yaml b/suites/marginal/multimds/tasks/workunit_suites_dbench.yaml
new file mode 100644
index 000000000..41b2bc8ed
--- /dev/null
+++ b/suites/marginal/multimds/tasks/workunit_suites_dbench.yaml
@@ -0,0 +1,5 @@
+tasks:
+- workunit:
+ clients:
+ all:
+ - suites/dbench.sh
diff --git a/suites/marginal/multimds/tasks/workunit_suites_fsstress.yaml b/suites/marginal/multimds/tasks/workunit_suites_fsstress.yaml
new file mode 100644
index 000000000..ddb18fb79
--- /dev/null
+++ b/suites/marginal/multimds/tasks/workunit_suites_fsstress.yaml
@@ -0,0 +1,5 @@
+tasks:
+- workunit:
+ clients:
+ all:
+ - suites/fsstress.sh
diff --git a/suites/marginal/multimds/tasks/workunit_suites_fsync.yaml b/suites/marginal/multimds/tasks/workunit_suites_fsync.yaml
new file mode 100644
index 000000000..7efa1adb8
--- /dev/null
+++ b/suites/marginal/multimds/tasks/workunit_suites_fsync.yaml
@@ -0,0 +1,5 @@
+tasks:
+- workunit:
+ clients:
+ all:
+ - suites/fsync-tester.sh
diff --git a/suites/marginal/multimds/tasks/workunit_suites_pjd.yaml b/suites/marginal/multimds/tasks/workunit_suites_pjd.yaml
new file mode 100644
index 000000000..e8882134c
--- /dev/null
+++ b/suites/marginal/multimds/tasks/workunit_suites_pjd.yaml
@@ -0,0 +1,5 @@
+tasks:
+- workunit:
+ clients:
+ all:
+ - suites/pjd.sh
diff --git a/suites/marginal/multimds/tasks/workunit_suites_truncate_delay.yaml b/suites/marginal/multimds/tasks/workunit_suites_truncate_delay.yaml
new file mode 100644
index 000000000..3aa5f8825
--- /dev/null
+++ b/suites/marginal/multimds/tasks/workunit_suites_truncate_delay.yaml
@@ -0,0 +1,15 @@
+tasks:
+- install:
+- ceph:
+ conf:
+ client:
+ ms_inject_delay_probability: 1
+ ms_inject_delay_type: osd
+ ms_inject_delay_max: 5
+ client_oc_max_dirty_age: 1
+- ceph-fuse:
+- exec:
+ client.0:
+ - dd if=/dev/zero of=./foo count=100
+ - sleep 2
+ - truncate --size 0 ./foo
diff --git a/suites/marginal/multimds/thrash/exports.yaml b/suites/marginal/multimds/thrash/exports.yaml
new file mode 100644
index 000000000..240b46dfd
--- /dev/null
+++ b/suites/marginal/multimds/thrash/exports.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ mds:
+ mds thrash exports: 1
diff --git a/suites/marginal/multimds/thrash/normal.yaml b/suites/marginal/multimds/thrash/normal.yaml
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/nfs/basic/% b/suites/nfs/basic/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/nfs/basic/clusters/extra-client.yaml b/suites/nfs/basic/clusters/extra-client.yaml
new file mode 120000
index 000000000..1582e3089
--- /dev/null
+++ b/suites/nfs/basic/clusters/extra-client.yaml
@@ -0,0 +1 @@
+../../../../clusters/extra-client.yaml
\ No newline at end of file
diff --git a/suites/nfs/basic/debug/mds.yaml b/suites/nfs/basic/debug/mds.yaml
new file mode 100644
index 000000000..9b3c8bd4d
--- /dev/null
+++ b/suites/nfs/basic/debug/mds.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ conf:
+ mds:
+ debug ms: 1
+ debug mds: 20
diff --git a/suites/nfs/basic/fs/btrfs.yaml b/suites/nfs/basic/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/nfs/basic/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/nfs/basic/tasks/nfs_workunit_misc.yaml b/suites/nfs/basic/tasks/nfs_workunit_misc.yaml
new file mode 100644
index 000000000..b7f6e37ea
--- /dev/null
+++ b/suites/nfs/basic/tasks/nfs_workunit_misc.yaml
@@ -0,0 +1,19 @@
+tasks:
+- install:
+- ceph:
+- kclient: [client.0]
+- knfsd: [client.0]
+- nfs:
+ client.1:
+ server: client.0
+ options: [rw,hard,intr,nfsvers=3]
+- workunit:
+ clients:
+ client.1:
+ - misc/chmod.sh
+ - misc/i_complete_vs_rename.sh
+ - misc/trivial_sync.sh
+ #- misc/multiple_rsync.sh
+ #- misc/xattrs.sh
+# Once we can run multiple_rsync.sh and xattrs.sh we can change to this
+# - misc
diff --git a/suites/nfs/basic/tasks/nfs_workunit_suites_blogbench.yaml b/suites/nfs/basic/tasks/nfs_workunit_suites_blogbench.yaml
new file mode 100644
index 000000000..85b5f7c14
--- /dev/null
+++ b/suites/nfs/basic/tasks/nfs_workunit_suites_blogbench.yaml
@@ -0,0 +1,13 @@
+tasks:
+- install:
+- ceph:
+- kclient: [client.0]
+- knfsd: [client.0]
+- nfs:
+ client.1:
+ server: client.0
+ options: [rw,hard,intr,nfsvers=3]
+- workunit:
+ clients:
+ client.1:
+ - suites/blogbench.sh
diff --git a/suites/nfs/basic/tasks/nfs_workunit_suites_dbench.yaml b/suites/nfs/basic/tasks/nfs_workunit_suites_dbench.yaml
new file mode 100644
index 000000000..dc5264378
--- /dev/null
+++ b/suites/nfs/basic/tasks/nfs_workunit_suites_dbench.yaml
@@ -0,0 +1,13 @@
+tasks:
+- install:
+- ceph:
+- kclient: [client.0]
+- knfsd: [client.0]
+- nfs:
+ client.1:
+ server: client.0
+ options: [rw,hard,intr,nfsvers=3]
+- workunit:
+ clients:
+ client.1:
+ - suites/dbench-short.sh
diff --git a/suites/nfs/basic/tasks/nfs_workunit_suites_ffsb.yaml b/suites/nfs/basic/tasks/nfs_workunit_suites_ffsb.yaml
new file mode 100644
index 000000000..8ccd58051
--- /dev/null
+++ b/suites/nfs/basic/tasks/nfs_workunit_suites_ffsb.yaml
@@ -0,0 +1,16 @@
+tasks:
+- install:
+- ceph:
+ conf:
+ osd:
+ filestore flush min: 0
+- kclient: [client.0]
+- knfsd: [client.0]
+- nfs:
+ client.1:
+ server: client.0
+ options: [rw,hard,intr,nfsvers=3]
+- workunit:
+ clients:
+ client.1:
+ - suites/ffsb.sh
diff --git a/suites/nfs/basic/tasks/nfs_workunit_suites_iozone.yaml b/suites/nfs/basic/tasks/nfs_workunit_suites_iozone.yaml
new file mode 100644
index 000000000..6b86d63d9
--- /dev/null
+++ b/suites/nfs/basic/tasks/nfs_workunit_suites_iozone.yaml
@@ -0,0 +1,13 @@
+tasks:
+- install:
+- ceph:
+- kclient: [client.0]
+- knfsd: [client.0]
+- nfs:
+ client.1:
+ server: client.0
+ options: [rw,hard,intr,nfsvers=3]
+- workunit:
+ clients:
+ client.1:
+ - suites/iozone.sh
diff --git a/suites/powercycle/osd/% b/suites/powercycle/osd/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/powercycle/osd/clusters/3osd-1per-target.yaml b/suites/powercycle/osd/clusters/3osd-1per-target.yaml
new file mode 100644
index 000000000..d5503a40c
--- /dev/null
+++ b/suites/powercycle/osd/clusters/3osd-1per-target.yaml
@@ -0,0 +1,5 @@
+roles:
+- [mon.0, mon.1, mon.2, mds.0, client.0]
+- [osd.0]
+- [osd.1]
+- [osd.2]
diff --git a/suites/powercycle/osd/fs/btrfs.yaml b/suites/powercycle/osd/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/powercycle/osd/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/powercycle/osd/fs/ext4.yaml b/suites/powercycle/osd/fs/ext4.yaml
new file mode 100644
index 000000000..fde675175
--- /dev/null
+++ b/suites/powercycle/osd/fs/ext4.yaml
@@ -0,0 +1,3 @@
+overrides:
+ ceph:
+ fs: ext4
diff --git a/suites/powercycle/osd/fs/xfs.yaml b/suites/powercycle/osd/fs/xfs.yaml
new file mode 100644
index 000000000..bfc3d618f
--- /dev/null
+++ b/suites/powercycle/osd/fs/xfs.yaml
@@ -0,0 +1,3 @@
+overrides:
+ ceph:
+ fs: xfs
diff --git a/suites/powercycle/osd/powercycle/default.yaml b/suites/powercycle/osd/powercycle/default.yaml
new file mode 100644
index 000000000..6d80a1205
--- /dev/null
+++ b/suites/powercycle/osd/powercycle/default.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- thrashosds:
+ thrash_primary_affinity: false
+ chance_down: 1.0
+ powercycle: true
+ timeout: 600
diff --git a/suites/powercycle/osd/tasks/admin_socket_objecter_requests.yaml b/suites/powercycle/osd/tasks/admin_socket_objecter_requests.yaml
new file mode 100644
index 000000000..66791551f
--- /dev/null
+++ b/suites/powercycle/osd/tasks/admin_socket_objecter_requests.yaml
@@ -0,0 +1,13 @@
+overrides:
+ ceph:
+ conf:
+ client.0:
+ admin socket: /var/run/ceph/ceph-$name.asok
+tasks:
+- radosbench:
+ clients: [client.0]
+ time: 60
+- admin_socket:
+ client.0:
+ objecter_requests:
+ test: "http://ceph.newdream.net/git/?p=ceph.git;a=blob_plain;f=src/test/admin_socket/objecter_requests;hb={branch}"
diff --git a/suites/powercycle/osd/tasks/cfuse_workunit_kernel_untar_build.yaml b/suites/powercycle/osd/tasks/cfuse_workunit_kernel_untar_build.yaml
new file mode 100644
index 000000000..3e99204de
--- /dev/null
+++ b/suites/powercycle/osd/tasks/cfuse_workunit_kernel_untar_build.yaml
@@ -0,0 +1,6 @@
+tasks:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - kernel_untar_build.sh
diff --git a/suites/powercycle/osd/tasks/cfuse_workunit_misc.yaml b/suites/powercycle/osd/tasks/cfuse_workunit_misc.yaml
new file mode 100644
index 000000000..792eeb2c3
--- /dev/null
+++ b/suites/powercycle/osd/tasks/cfuse_workunit_misc.yaml
@@ -0,0 +1,6 @@
+tasks:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - misc
diff --git a/suites/powercycle/osd/tasks/cfuse_workunit_suites_ffsb.yaml b/suites/powercycle/osd/tasks/cfuse_workunit_suites_ffsb.yaml
new file mode 100644
index 000000000..9f3fa7b18
--- /dev/null
+++ b/suites/powercycle/osd/tasks/cfuse_workunit_suites_ffsb.yaml
@@ -0,0 +1,14 @@
+overrides:
+ ceph:
+ conf:
+ osd:
+ filestore flush min: 0
+ mds:
+ debug ms: 1
+ debug mds: 20
+tasks:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/ffsb.sh
diff --git a/suites/powercycle/osd/tasks/cfuse_workunit_suites_fsstress.yaml b/suites/powercycle/osd/tasks/cfuse_workunit_suites_fsstress.yaml
new file mode 100644
index 000000000..5908d951b
--- /dev/null
+++ b/suites/powercycle/osd/tasks/cfuse_workunit_suites_fsstress.yaml
@@ -0,0 +1,6 @@
+tasks:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/fsstress.sh
diff --git a/suites/powercycle/osd/tasks/cfuse_workunit_suites_fsx.yaml b/suites/powercycle/osd/tasks/cfuse_workunit_suites_fsx.yaml
new file mode 100644
index 000000000..3c11ed74f
--- /dev/null
+++ b/suites/powercycle/osd/tasks/cfuse_workunit_suites_fsx.yaml
@@ -0,0 +1,6 @@
+tasks:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/fsx.sh
diff --git a/suites/powercycle/osd/tasks/cfuse_workunit_suites_fsync.yaml b/suites/powercycle/osd/tasks/cfuse_workunit_suites_fsync.yaml
new file mode 100644
index 000000000..c6043e209
--- /dev/null
+++ b/suites/powercycle/osd/tasks/cfuse_workunit_suites_fsync.yaml
@@ -0,0 +1,6 @@
+tasks:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/fsync-tester.sh
diff --git a/suites/powercycle/osd/tasks/cfuse_workunit_suites_pjd.yaml b/suites/powercycle/osd/tasks/cfuse_workunit_suites_pjd.yaml
new file mode 100644
index 000000000..930bf4a67
--- /dev/null
+++ b/suites/powercycle/osd/tasks/cfuse_workunit_suites_pjd.yaml
@@ -0,0 +1,6 @@
+tasks:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/pjd.sh
diff --git a/suites/powercycle/osd/tasks/cfuse_workunit_suites_truncate_delay.yaml b/suites/powercycle/osd/tasks/cfuse_workunit_suites_truncate_delay.yaml
new file mode 100644
index 000000000..f3efafa2e
--- /dev/null
+++ b/suites/powercycle/osd/tasks/cfuse_workunit_suites_truncate_delay.yaml
@@ -0,0 +1,15 @@
+overrides:
+ ceph:
+ conf:
+ client:
+ ms_inject_delay_probability: 1
+ ms_inject_delay_type: osd
+ ms_inject_delay_max: 5
+ client_oc_max_dirty_age: 1
+tasks:
+- ceph-fuse:
+- exec:
+ client.0:
+ - dd if=/dev/zero of=./foo count=100
+ - sleep 2
+ - truncate --size 0 ./foo
diff --git a/suites/powercycle/osd/tasks/rados_api_tests.yaml b/suites/powercycle/osd/tasks/rados_api_tests.yaml
new file mode 100644
index 000000000..b4708ebd7
--- /dev/null
+++ b/suites/powercycle/osd/tasks/rados_api_tests.yaml
@@ -0,0 +1,6 @@
+tasks:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - rados/test.sh
diff --git a/suites/powercycle/osd/tasks/radosbench.yaml b/suites/powercycle/osd/tasks/radosbench.yaml
new file mode 100644
index 000000000..3940870fc
--- /dev/null
+++ b/suites/powercycle/osd/tasks/radosbench.yaml
@@ -0,0 +1,4 @@
+tasks:
+- radosbench:
+ clients: [client.0]
+ time: 1800
diff --git a/suites/powercycle/osd/tasks/readwrite.yaml b/suites/powercycle/osd/tasks/readwrite.yaml
new file mode 100644
index 000000000..c53e52b08
--- /dev/null
+++ b/suites/powercycle/osd/tasks/readwrite.yaml
@@ -0,0 +1,9 @@
+tasks:
+- rados:
+ clients: [client.0]
+ ops: 4000
+ objects: 500
+ op_weights:
+ read: 45
+ write: 45
+ delete: 10
diff --git a/suites/powercycle/osd/tasks/snaps-few-objects.yaml b/suites/powercycle/osd/tasks/snaps-few-objects.yaml
new file mode 100644
index 000000000..c54039766
--- /dev/null
+++ b/suites/powercycle/osd/tasks/snaps-few-objects.yaml
@@ -0,0 +1,12 @@
+tasks:
+- rados:
+ clients: [client.0]
+ ops: 4000
+ objects: 50
+ op_weights:
+ read: 100
+ write: 100
+ delete: 50
+ snap_create: 50
+ snap_remove: 50
+ rollback: 50
diff --git a/suites/powercycle/osd/tasks/snaps-many-objects.yaml b/suites/powercycle/osd/tasks/snaps-many-objects.yaml
new file mode 100644
index 000000000..9e311c946
--- /dev/null
+++ b/suites/powercycle/osd/tasks/snaps-many-objects.yaml
@@ -0,0 +1,12 @@
+tasks:
+- rados:
+ clients: [client.0]
+ ops: 4000
+ objects: 500
+ op_weights:
+ read: 100
+ write: 100
+ delete: 50
+ snap_create: 50
+ snap_remove: 50
+ rollback: 50
diff --git a/suites/rados/basic/% b/suites/rados/basic/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/rados/basic/clusters/fixed-2.yaml b/suites/rados/basic/clusters/fixed-2.yaml
new file mode 120000
index 000000000..cd0791a14
--- /dev/null
+++ b/suites/rados/basic/clusters/fixed-2.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-2.yaml
\ No newline at end of file
diff --git a/suites/rados/basic/fs/btrfs.yaml b/suites/rados/basic/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/rados/basic/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/rados/basic/msgr-failures/few.yaml b/suites/rados/basic/msgr-failures/few.yaml
new file mode 100644
index 000000000..0de320d46
--- /dev/null
+++ b/suites/rados/basic/msgr-failures/few.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 5000
diff --git a/suites/rados/basic/msgr-failures/many.yaml b/suites/rados/basic/msgr-failures/many.yaml
new file mode 100644
index 000000000..038c3a799
--- /dev/null
+++ b/suites/rados/basic/msgr-failures/many.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 1500
diff --git a/suites/rados/basic/tasks/rados_api_tests.yaml b/suites/rados/basic/tasks/rados_api_tests.yaml
new file mode 100644
index 000000000..1636c7f7b
--- /dev/null
+++ b/suites/rados/basic/tasks/rados_api_tests.yaml
@@ -0,0 +1,13 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - reached quota
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ client.0:
+ - rados/test.sh
+ - rados/test_pool_quota.sh
+
diff --git a/suites/rados/basic/tasks/rados_cls_all.yaml b/suites/rados/basic/tasks/rados_cls_all.yaml
new file mode 100644
index 000000000..34f7cbbb4
--- /dev/null
+++ b/suites/rados/basic/tasks/rados_cls_all.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ client.0:
+ - cls
diff --git a/suites/rados/basic/tasks/rados_python.yaml b/suites/rados/basic/tasks/rados_python.yaml
new file mode 100644
index 000000000..4faf10e39
--- /dev/null
+++ b/suites/rados/basic/tasks/rados_python.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ client.0:
+ - rados/test_python.sh
diff --git a/suites/rados/basic/tasks/rados_stress_watch.yaml b/suites/rados/basic/tasks/rados_stress_watch.yaml
new file mode 100644
index 000000000..ae2e5fd00
--- /dev/null
+++ b/suites/rados/basic/tasks/rados_stress_watch.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ client.0:
+ - rados/stress_watch.sh
diff --git a/suites/rados/basic/tasks/rados_workunit_loadgen_big.yaml b/suites/rados/basic/tasks/rados_workunit_loadgen_big.yaml
new file mode 100644
index 000000000..3a2172782
--- /dev/null
+++ b/suites/rados/basic/tasks/rados_workunit_loadgen_big.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ all:
+ - rados/load-gen-big.sh
diff --git a/suites/rados/basic/tasks/rados_workunit_loadgen_mix.yaml b/suites/rados/basic/tasks/rados_workunit_loadgen_mix.yaml
new file mode 100644
index 000000000..642148d60
--- /dev/null
+++ b/suites/rados/basic/tasks/rados_workunit_loadgen_mix.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ all:
+ - rados/load-gen-mix.sh
diff --git a/suites/rados/basic/tasks/rados_workunit_loadgen_mostlyread.yaml b/suites/rados/basic/tasks/rados_workunit_loadgen_mostlyread.yaml
new file mode 100644
index 000000000..87d8d28c4
--- /dev/null
+++ b/suites/rados/basic/tasks/rados_workunit_loadgen_mostlyread.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ all:
+ - rados/load-gen-mostlyread.sh
diff --git a/suites/rados/monthrash/% b/suites/rados/monthrash/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/rados/monthrash/ceph/ceph.yaml b/suites/rados/monthrash/ceph/ceph.yaml
new file mode 100644
index 000000000..a2c0efc77
--- /dev/null
+++ b/suites/rados/monthrash/ceph/ceph.yaml
@@ -0,0 +1,9 @@
+overrides:
+ ceph:
+ conf:
+ mon:
+ mon min osdmap epochs: 25
+ paxos service trim min: 5
+tasks:
+- install:
+- ceph:
diff --git a/suites/rados/monthrash/clusters/3-mons.yaml b/suites/rados/monthrash/clusters/3-mons.yaml
new file mode 100644
index 000000000..6298ff23c
--- /dev/null
+++ b/suites/rados/monthrash/clusters/3-mons.yaml
@@ -0,0 +1,3 @@
+roles:
+- [mon.a, mon.c, osd.0, osd.1, osd.2]
+- [mon.b, mds.a, osd.3, osd.4, osd.5, client.0]
diff --git a/suites/rados/monthrash/clusters/9-mons.yaml b/suites/rados/monthrash/clusters/9-mons.yaml
new file mode 100644
index 000000000..a22e6c5a0
--- /dev/null
+++ b/suites/rados/monthrash/clusters/9-mons.yaml
@@ -0,0 +1,3 @@
+roles:
+- [mon.a, mon.b, mon.c, mon.d, mon.e, osd.0, osd.1, osd.2]
+- [mon.f, mon.g, mon.h, mon.i, mds.a, osd.3, osd.4, osd.5, client.0]
diff --git a/suites/rados/monthrash/fs/xfs.yaml b/suites/rados/monthrash/fs/xfs.yaml
new file mode 100644
index 000000000..bfc3d618f
--- /dev/null
+++ b/suites/rados/monthrash/fs/xfs.yaml
@@ -0,0 +1,3 @@
+overrides:
+ ceph:
+ fs: xfs
diff --git a/suites/rados/monthrash/msgr-failures/few.yaml b/suites/rados/monthrash/msgr-failures/few.yaml
new file mode 100644
index 000000000..0de320d46
--- /dev/null
+++ b/suites/rados/monthrash/msgr-failures/few.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 5000
diff --git a/suites/rados/monthrash/msgr-failures/mon-delay.yaml b/suites/rados/monthrash/msgr-failures/mon-delay.yaml
new file mode 100644
index 000000000..03b7e37f8
--- /dev/null
+++ b/suites/rados/monthrash/msgr-failures/mon-delay.yaml
@@ -0,0 +1,9 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 2500
+ ms inject delay type: mon
+ ms inject delay probability: .005
+ ms inject delay max: 1
+ ms inject internal delays: .002
diff --git a/suites/rados/monthrash/thrashers/force-sync-many.yaml b/suites/rados/monthrash/thrashers/force-sync-many.yaml
new file mode 100644
index 000000000..2867f2db5
--- /dev/null
+++ b/suites/rados/monthrash/thrashers/force-sync-many.yaml
@@ -0,0 +1,6 @@
+tasks:
+- mon_thrash:
+ revive_delay: 90
+ thrash_delay: 1
+ thrash_store: true
+ thrash_many: true
diff --git a/suites/rados/monthrash/thrashers/many.yaml b/suites/rados/monthrash/thrashers/many.yaml
new file mode 100644
index 000000000..e0cea87e5
--- /dev/null
+++ b/suites/rados/monthrash/thrashers/many.yaml
@@ -0,0 +1,5 @@
+tasks:
+- mon_thrash:
+ revive_delay: 20
+ thrash_delay: 1
+ thrash_many: true
diff --git a/suites/rados/monthrash/thrashers/one.yaml b/suites/rados/monthrash/thrashers/one.yaml
new file mode 100644
index 000000000..2ce44c860
--- /dev/null
+++ b/suites/rados/monthrash/thrashers/one.yaml
@@ -0,0 +1,4 @@
+tasks:
+- mon_thrash:
+ revive_delay: 20
+ thrash_delay: 1
diff --git a/suites/rados/monthrash/thrashers/sync-many.yaml b/suites/rados/monthrash/thrashers/sync-many.yaml
new file mode 100644
index 000000000..9868f1815
--- /dev/null
+++ b/suites/rados/monthrash/thrashers/sync-many.yaml
@@ -0,0 +1,11 @@
+overrides:
+ ceph:
+ conf:
+ mon:
+ paxos min: 10
+ paxos trim min: 10
+tasks:
+- mon_thrash:
+ revive_delay: 90
+ thrash_delay: 1
+ thrash_many: true
diff --git a/suites/rados/monthrash/thrashers/sync.yaml b/suites/rados/monthrash/thrashers/sync.yaml
new file mode 100644
index 000000000..1e7054c27
--- /dev/null
+++ b/suites/rados/monthrash/thrashers/sync.yaml
@@ -0,0 +1,10 @@
+overrides:
+ ceph:
+ conf:
+ mon:
+ paxos min: 10
+ paxos trim min: 10
+tasks:
+- mon_thrash:
+ revive_delay: 90
+ thrash_delay: 1
diff --git a/suites/rados/monthrash/workloads/rados_api_tests.yaml b/suites/rados/monthrash/workloads/rados_api_tests.yaml
new file mode 100644
index 000000000..cd11ae6ca
--- /dev/null
+++ b/suites/rados/monthrash/workloads/rados_api_tests.yaml
@@ -0,0 +1,5 @@
+tasks:
+- workunit:
+ clients:
+ client.0:
+ - rados/test.sh
diff --git a/suites/rados/monthrash/workloads/rados_mon_workunits.yaml b/suites/rados/monthrash/workloads/rados_mon_workunits.yaml
new file mode 100644
index 000000000..31465cffe
--- /dev/null
+++ b/suites/rados/monthrash/workloads/rados_mon_workunits.yaml
@@ -0,0 +1,13 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - wrongly marked me down
+tasks:
+- workunit:
+ clients:
+ client.0:
+ - mon/pool_ops.sh
+ - mon/crush_ops.sh
+ - mon/osd.sh
+ - mon/caps.sh
+
diff --git a/suites/rados/monthrash/workloads/snaps-few-objects.yaml b/suites/rados/monthrash/workloads/snaps-few-objects.yaml
new file mode 100644
index 000000000..c54039766
--- /dev/null
+++ b/suites/rados/monthrash/workloads/snaps-few-objects.yaml
@@ -0,0 +1,12 @@
+tasks:
+- rados:
+ clients: [client.0]
+ ops: 4000
+ objects: 50
+ op_weights:
+ read: 100
+ write: 100
+ delete: 50
+ snap_create: 50
+ snap_remove: 50
+ rollback: 50
diff --git a/suites/rados/multimon/% b/suites/rados/multimon/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/rados/multimon/clusters/21.yaml b/suites/rados/multimon/clusters/21.yaml
new file mode 100644
index 000000000..2d134788a
--- /dev/null
+++ b/suites/rados/multimon/clusters/21.yaml
@@ -0,0 +1,4 @@
+roles:
+- [mon.a, mon.d, mon.g, mon.j, mon.m, mon.p, mon.s, osd.0]
+- [mon.b, mon.e, mon.h, mon.k, mon.n, mon.q, mon.t, mds.a]
+- [mon.c, mon.f, mon.i, mon.l, mon.o, mon.r, mon.u, osd.1]
diff --git a/suites/rados/multimon/clusters/3.yaml b/suites/rados/multimon/clusters/3.yaml
new file mode 100644
index 000000000..703cc664f
--- /dev/null
+++ b/suites/rados/multimon/clusters/3.yaml
@@ -0,0 +1,2 @@
+roles:
+- [mon.a, mon.b, mon.c, osd.0, osd.1, mds.a]
diff --git a/suites/rados/multimon/clusters/6.yaml b/suites/rados/multimon/clusters/6.yaml
new file mode 100644
index 000000000..627806603
--- /dev/null
+++ b/suites/rados/multimon/clusters/6.yaml
@@ -0,0 +1,3 @@
+roles:
+- [mon.a, mon.c, mon.e, osd.0]
+- [mon.b, mon.d, mon.f, osd.1, mds.a]
diff --git a/suites/rados/multimon/clusters/9.yaml b/suites/rados/multimon/clusters/9.yaml
new file mode 100644
index 000000000..b87a158db
--- /dev/null
+++ b/suites/rados/multimon/clusters/9.yaml
@@ -0,0 +1,4 @@
+roles:
+- [mon.a, mon.d, mon.g, osd.0]
+- [mon.b, mon.e, mon.h, mds.a]
+- [mon.c, mon.f, mon.i, osd.1]
diff --git a/suites/rados/multimon/msgr-failures/few.yaml b/suites/rados/multimon/msgr-failures/few.yaml
new file mode 100644
index 000000000..0de320d46
--- /dev/null
+++ b/suites/rados/multimon/msgr-failures/few.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 5000
diff --git a/suites/rados/multimon/msgr-failures/many.yaml b/suites/rados/multimon/msgr-failures/many.yaml
new file mode 100644
index 000000000..86f8dde8a
--- /dev/null
+++ b/suites/rados/multimon/msgr-failures/many.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 500
diff --git a/suites/rados/multimon/tasks/mon_clock_no_skews.yaml b/suites/rados/multimon/tasks/mon_clock_no_skews.yaml
new file mode 100644
index 000000000..e86bdde1d
--- /dev/null
+++ b/suites/rados/multimon/tasks/mon_clock_no_skews.yaml
@@ -0,0 +1,9 @@
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - slow request
+ - .*clock.*skew.*
+ - clocks not synchronized
+- mon_clock_skew_check:
+ expect-skew: false
diff --git a/suites/rados/multimon/tasks/mon_clock_with_skews.yaml b/suites/rados/multimon/tasks/mon_clock_with_skews.yaml
new file mode 100644
index 000000000..2953e0d6d
--- /dev/null
+++ b/suites/rados/multimon/tasks/mon_clock_with_skews.yaml
@@ -0,0 +1,15 @@
+overrides:
+ ceph:
+ conf:
+ mon.b:
+ clock offset: 10
+tasks:
+- install:
+- ceph:
+ wait-for-healthy: false
+ log-whitelist:
+ - slow request
+ - .*clock.*skew.*
+ - clocks not synchronized
+- mon_clock_skew_check:
+ expect-skew: true
diff --git a/suites/rados/multimon/tasks/mon_recovery.yaml b/suites/rados/multimon/tasks/mon_recovery.yaml
new file mode 100644
index 000000000..94721ea53
--- /dev/null
+++ b/suites/rados/multimon/tasks/mon_recovery.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install:
+- ceph:
+- mon_recovery:
diff --git a/suites/rados/singleton-nomsgr/% b/suites/rados/singleton-nomsgr/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/rados/singleton-nomsgr/all/filejournal.yaml b/suites/rados/singleton-nomsgr/all/filejournal.yaml
new file mode 100644
index 000000000..28a0c041d
--- /dev/null
+++ b/suites/rados/singleton-nomsgr/all/filejournal.yaml
@@ -0,0 +1,8 @@
+roles:
+- [mon.0, osd.0, osd.1, mds.a, client.0]
+tasks:
+- install:
+- ceph:
+- exec:
+ client.0:
+ - ceph_test_filejournal
diff --git a/suites/rados/singleton-nomsgr/all/filestore-idempotent-aio-journal.yaml b/suites/rados/singleton-nomsgr/all/filestore-idempotent-aio-journal.yaml
new file mode 100644
index 000000000..15437cf65
--- /dev/null
+++ b/suites/rados/singleton-nomsgr/all/filestore-idempotent-aio-journal.yaml
@@ -0,0 +1,9 @@
+roles:
+- [mon.0, osd.0, osd.1, mds.a, client.0]
+tasks:
+- install:
+- ceph:
+ conf:
+ global:
+ journal aio: true
+- filestore_idempotent:
diff --git a/suites/rados/singleton-nomsgr/all/filestore-idempotent.yaml b/suites/rados/singleton-nomsgr/all/filestore-idempotent.yaml
new file mode 100644
index 000000000..c6af200d5
--- /dev/null
+++ b/suites/rados/singleton-nomsgr/all/filestore-idempotent.yaml
@@ -0,0 +1,6 @@
+roles:
+- [mon.0, osd.0, osd.1, mds.a, client.0]
+tasks:
+- install:
+- ceph:
+- filestore_idempotent:
diff --git a/suites/rados/singleton-nomsgr/all/objectcacher-stress.yaml b/suites/rados/singleton-nomsgr/all/objectcacher-stress.yaml
new file mode 100644
index 000000000..bc5a2838e
--- /dev/null
+++ b/suites/rados/singleton-nomsgr/all/objectcacher-stress.yaml
@@ -0,0 +1,9 @@
+roles:
+- [mon.0, osd.0, osd.1, mds.a, client.0]
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ all:
+ - osdc/stress_objectcacher.sh
diff --git a/suites/rados/singleton/% b/suites/rados/singleton/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/rados/singleton/all/admin-socket.yaml b/suites/rados/singleton/all/admin-socket.yaml
new file mode 100644
index 000000000..9e580f29d
--- /dev/null
+++ b/suites/rados/singleton/all/admin-socket.yaml
@@ -0,0 +1,18 @@
+roles:
+- - mon.a
+ - osd.0
+ - mds.a
+ - osd.1
+ - client.a
+tasks:
+- install:
+- ceph:
+- admin_socket:
+ osd.0:
+ version:
+ git_version:
+ help:
+ config show:
+ config set filestore_dump_file /tmp/foo:
+ perf dump:
+ perf schema:
diff --git a/suites/rados/singleton/all/cephtool.yaml b/suites/rados/singleton/all/cephtool.yaml
new file mode 100644
index 000000000..428c39149
--- /dev/null
+++ b/suites/rados/singleton/all/cephtool.yaml
@@ -0,0 +1,20 @@
+roles:
+- - mon.a
+ - mon.b
+ - mon.c
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+ - client.0
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - had wrong client addr
+- workunit:
+ clients:
+ all:
+ - cephtool
+ - mon/pool_ops.sh
diff --git a/suites/rados/singleton/all/dump-stuck.yaml b/suites/rados/singleton/all/dump-stuck.yaml
new file mode 100644
index 000000000..9bdcb0c3c
--- /dev/null
+++ b/suites/rados/singleton/all/dump-stuck.yaml
@@ -0,0 +1,11 @@
+roles:
+- - mon.a
+ - mds.0
+ - osd.0
+ - osd.1
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+- dump_stuck:
diff --git a/suites/rados/singleton/all/lost-unfound.yaml b/suites/rados/singleton/all/lost-unfound.yaml
new file mode 100644
index 000000000..6014723ed
--- /dev/null
+++ b/suites/rados/singleton/all/lost-unfound.yaml
@@ -0,0 +1,14 @@
+roles:
+- - mon.a
+ - mon.b
+ - mon.c
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - objects unfound and apparently lost
+- lost_unfound:
diff --git a/suites/rados/singleton/all/mon-config-keys.yaml b/suites/rados/singleton/all/mon-config-keys.yaml
new file mode 100644
index 000000000..524c6b6f5
--- /dev/null
+++ b/suites/rados/singleton/all/mon-config-keys.yaml
@@ -0,0 +1,16 @@
+roles:
+- - mon.0
+ - mon.1
+ - mon.2
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+ - client.0
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ all:
+ - mon/test_mon_config_key.py
diff --git a/suites/rados/singleton/all/mon-thrasher.yaml b/suites/rados/singleton/all/mon-thrasher.yaml
new file mode 100644
index 000000000..4e4e8571b
--- /dev/null
+++ b/suites/rados/singleton/all/mon-thrasher.yaml
@@ -0,0 +1,22 @@
+roles:
+- - mon.a
+ - mon.b
+ - mon.c
+ - osd.0
+ - osd.1
+ - mds.0
+ - client.0
+tasks:
+- install:
+- ceph:
+- mon_thrash:
+ revive_delay: 20
+ thrash_delay: 1
+- workunit:
+ clients:
+ all:
+ - mon/workloadgen.sh
+ env:
+ LOADGEN_NUM_OSDS: "5"
+ VERBOSE: "1"
+ DURATION: "600"
diff --git a/suites/rados/singleton/all/osd-backfill.yaml b/suites/rados/singleton/all/osd-backfill.yaml
new file mode 100644
index 000000000..7c18a3b9b
--- /dev/null
+++ b/suites/rados/singleton/all/osd-backfill.yaml
@@ -0,0 +1,17 @@
+roles:
+- - mon.a
+ - mon.b
+ - mon.c
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ conf:
+ osd:
+ osd min pg log entries: 5
+- osd_backfill:
diff --git a/suites/rados/singleton/all/osd-recovery-incomplete.yaml b/suites/rados/singleton/all/osd-recovery-incomplete.yaml
new file mode 100644
index 000000000..e6f99983e
--- /dev/null
+++ b/suites/rados/singleton/all/osd-recovery-incomplete.yaml
@@ -0,0 +1,18 @@
+roles:
+- - mon.a
+ - mon.b
+ - mon.c
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+ - osd.3
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ conf:
+ osd:
+ osd min pg log entries: 5
+- osd_recovery.test_incomplete_pgs:
diff --git a/suites/rados/singleton/all/osd-recovery.yaml b/suites/rados/singleton/all/osd-recovery.yaml
new file mode 100644
index 000000000..8307d4245
--- /dev/null
+++ b/suites/rados/singleton/all/osd-recovery.yaml
@@ -0,0 +1,17 @@
+roles:
+- - mon.a
+ - mon.b
+ - mon.c
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ conf:
+ osd:
+ osd min pg log entries: 5
+- osd_recovery:
diff --git a/suites/rados/singleton/all/peer.yaml b/suites/rados/singleton/all/peer.yaml
new file mode 100644
index 000000000..a441059bb
--- /dev/null
+++ b/suites/rados/singleton/all/peer.yaml
@@ -0,0 +1,17 @@
+roles:
+- - mon.0
+ - mon.1
+ - mon.2
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+tasks:
+- install:
+- ceph:
+ config:
+ global:
+ osd pool default min size : 1
+ log-whitelist:
+ - objects unfound and apparently lost
+- peer:
diff --git a/suites/rados/singleton/all/rest-api.yaml b/suites/rados/singleton/all/rest-api.yaml
new file mode 100644
index 000000000..425db5566
--- /dev/null
+++ b/suites/rados/singleton/all/rest-api.yaml
@@ -0,0 +1,20 @@
+roles:
+- - mon.0
+ - mon.1
+ - mon.2
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+ - client.0
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - had wrong client addr
+- rest-api: [client.0]
+- workunit:
+ clients:
+ all:
+ - rest/test.py
diff --git a/suites/rados/singleton/all/thrash-rados.yaml b/suites/rados/singleton/all/thrash-rados.yaml
new file mode 100644
index 000000000..7d3aac00b
--- /dev/null
+++ b/suites/rados/singleton/all/thrash-rados.yaml
@@ -0,0 +1,24 @@
+roles:
+- - mon.a
+ - mds.0
+ - osd.0
+ - osd.1
+ - osd.2
+- - osd.3
+ - osd.4
+ - osd.5
+ - client.0
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+- thrashosds:
+ thrash_primary_affinity: false
+ op_delay: 30
+ clean_interval: 120
+ chance_down: .5
+- workunit:
+ clients:
+ all:
+ - rados/load-gen-mix-small.sh
diff --git a/suites/rados/singleton/fs/btrfs.yaml b/suites/rados/singleton/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/rados/singleton/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/rados/singleton/msgr-failures/few.yaml b/suites/rados/singleton/msgr-failures/few.yaml
new file mode 100644
index 000000000..0de320d46
--- /dev/null
+++ b/suites/rados/singleton/msgr-failures/few.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 5000
diff --git a/suites/rados/singleton/msgr-failures/many.yaml b/suites/rados/singleton/msgr-failures/many.yaml
new file mode 100644
index 000000000..86f8dde8a
--- /dev/null
+++ b/suites/rados/singleton/msgr-failures/many.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 500
diff --git a/suites/rados/thrash/% b/suites/rados/thrash/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/rados/thrash/clusters/fixed-2.yaml b/suites/rados/thrash/clusters/fixed-2.yaml
new file mode 120000
index 000000000..cd0791a14
--- /dev/null
+++ b/suites/rados/thrash/clusters/fixed-2.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-2.yaml
\ No newline at end of file
diff --git a/suites/rados/thrash/fs/btrfs.yaml b/suites/rados/thrash/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/rados/thrash/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/rados/thrash/fs/ext4.yaml b/suites/rados/thrash/fs/ext4.yaml
new file mode 100644
index 000000000..fde675175
--- /dev/null
+++ b/suites/rados/thrash/fs/ext4.yaml
@@ -0,0 +1,3 @@
+overrides:
+ ceph:
+ fs: ext4
diff --git a/suites/rados/thrash/fs/xfs.yaml b/suites/rados/thrash/fs/xfs.yaml
new file mode 100644
index 000000000..bfc3d618f
--- /dev/null
+++ b/suites/rados/thrash/fs/xfs.yaml
@@ -0,0 +1,3 @@
+overrides:
+ ceph:
+ fs: xfs
diff --git a/suites/rados/thrash/msgr-failures/few.yaml b/suites/rados/thrash/msgr-failures/few.yaml
new file mode 100644
index 000000000..0de320d46
--- /dev/null
+++ b/suites/rados/thrash/msgr-failures/few.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 5000
diff --git a/suites/rados/thrash/msgr-failures/osd-delay.yaml b/suites/rados/thrash/msgr-failures/osd-delay.yaml
new file mode 100644
index 000000000..a33ba89e1
--- /dev/null
+++ b/suites/rados/thrash/msgr-failures/osd-delay.yaml
@@ -0,0 +1,9 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 2500
+ ms inject delay type: osd
+ ms inject delay probability: .005
+ ms inject delay max: 1
+ ms inject internal delays: .002
diff --git a/suites/rados/thrash/thrashers/default.yaml b/suites/rados/thrash/thrashers/default.yaml
new file mode 100644
index 000000000..66ea0a362
--- /dev/null
+++ b/suites/rados/thrash/thrashers/default.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+- thrashosds:
+ thrash_primary_affinity: false
+ timeout: 1200
+ chance_pgnum_grow: 1
+ chance_pgpnum_fix: 1
diff --git a/suites/rados/thrash/thrashers/mapgap.yaml b/suites/rados/thrash/thrashers/mapgap.yaml
new file mode 100644
index 000000000..60aba7e2b
--- /dev/null
+++ b/suites/rados/thrash/thrashers/mapgap.yaml
@@ -0,0 +1,19 @@
+overrides:
+ ceph:
+ conf:
+ mon:
+ mon min osdmap epochs: 2
+ osd:
+ osd map cache size: 1
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+- thrashosds:
+ thrash_primary_affinity: false
+ timeout: 1200
+ chance_pgnum_grow: 1
+ chance_pgpnum_fix: 1
+ chance_test_map_discontinuity: 0.5
diff --git a/suites/rados/thrash/thrashers/morepggrow.yaml b/suites/rados/thrash/thrashers/morepggrow.yaml
new file mode 100644
index 000000000..944f654de
--- /dev/null
+++ b/suites/rados/thrash/thrashers/morepggrow.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+- thrashosds:
+ thrash_primary_affinity: false
+ timeout: 1200
+ chance_pgnum_grow: 3
+ chance_pgpnum_fix: 1
diff --git a/suites/rados/thrash/thrashers/pggrow.yaml b/suites/rados/thrash/thrashers/pggrow.yaml
new file mode 100644
index 000000000..d4012f942
--- /dev/null
+++ b/suites/rados/thrash/thrashers/pggrow.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+- thrashosds:
+ thrash_primary_affinity: false
+ timeout: 1200
+ chance_pgnum_grow: 2
+ chance_pgpnum_fix: 1
diff --git a/suites/rados/thrash/workloads/admin_socket_objecter_requests.yaml b/suites/rados/thrash/workloads/admin_socket_objecter_requests.yaml
new file mode 100644
index 000000000..66791551f
--- /dev/null
+++ b/suites/rados/thrash/workloads/admin_socket_objecter_requests.yaml
@@ -0,0 +1,13 @@
+overrides:
+ ceph:
+ conf:
+ client.0:
+ admin socket: /var/run/ceph/ceph-$name.asok
+tasks:
+- radosbench:
+ clients: [client.0]
+ time: 60
+- admin_socket:
+ client.0:
+ objecter_requests:
+ test: "http://ceph.newdream.net/git/?p=ceph.git;a=blob_plain;f=src/test/admin_socket/objecter_requests;hb={branch}"
diff --git a/suites/rados/thrash/workloads/rados_api_tests.yaml b/suites/rados/thrash/workloads/rados_api_tests.yaml
new file mode 100644
index 000000000..cd11ae6ca
--- /dev/null
+++ b/suites/rados/thrash/workloads/rados_api_tests.yaml
@@ -0,0 +1,5 @@
+tasks:
+- workunit:
+ clients:
+ client.0:
+ - rados/test.sh
diff --git a/suites/rados/thrash/workloads/radosbench.yaml b/suites/rados/thrash/workloads/radosbench.yaml
new file mode 100644
index 000000000..3940870fc
--- /dev/null
+++ b/suites/rados/thrash/workloads/radosbench.yaml
@@ -0,0 +1,4 @@
+tasks:
+- radosbench:
+ clients: [client.0]
+ time: 1800
diff --git a/suites/rados/thrash/workloads/readwrite.yaml b/suites/rados/thrash/workloads/readwrite.yaml
new file mode 100644
index 000000000..c53e52b08
--- /dev/null
+++ b/suites/rados/thrash/workloads/readwrite.yaml
@@ -0,0 +1,9 @@
+tasks:
+- rados:
+ clients: [client.0]
+ ops: 4000
+ objects: 500
+ op_weights:
+ read: 45
+ write: 45
+ delete: 10
diff --git a/suites/rados/thrash/workloads/snaps-few-objects.yaml b/suites/rados/thrash/workloads/snaps-few-objects.yaml
new file mode 100644
index 000000000..c54039766
--- /dev/null
+++ b/suites/rados/thrash/workloads/snaps-few-objects.yaml
@@ -0,0 +1,12 @@
+tasks:
+- rados:
+ clients: [client.0]
+ ops: 4000
+ objects: 50
+ op_weights:
+ read: 100
+ write: 100
+ delete: 50
+ snap_create: 50
+ snap_remove: 50
+ rollback: 50
diff --git a/suites/rados/thrash/workloads/snaps-many-objects.yaml b/suites/rados/thrash/workloads/snaps-many-objects.yaml
new file mode 100644
index 000000000..9e311c946
--- /dev/null
+++ b/suites/rados/thrash/workloads/snaps-many-objects.yaml
@@ -0,0 +1,12 @@
+tasks:
+- rados:
+ clients: [client.0]
+ ops: 4000
+ objects: 500
+ op_weights:
+ read: 100
+ write: 100
+ delete: 50
+ snap_create: 50
+ snap_remove: 50
+ rollback: 50
diff --git a/suites/rados/verify/% b/suites/rados/verify/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/rados/verify/1thrash/default.yaml b/suites/rados/verify/1thrash/default.yaml
new file mode 100644
index 000000000..66ea0a362
--- /dev/null
+++ b/suites/rados/verify/1thrash/default.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+- thrashosds:
+ thrash_primary_affinity: false
+ timeout: 1200
+ chance_pgnum_grow: 1
+ chance_pgpnum_fix: 1
diff --git a/suites/rados/verify/1thrash/none.yaml b/suites/rados/verify/1thrash/none.yaml
new file mode 100644
index 000000000..2030acb90
--- /dev/null
+++ b/suites/rados/verify/1thrash/none.yaml
@@ -0,0 +1,3 @@
+tasks:
+- install:
+- ceph:
diff --git a/suites/rados/verify/clusters/fixed-2.yaml b/suites/rados/verify/clusters/fixed-2.yaml
new file mode 120000
index 000000000..cd0791a14
--- /dev/null
+++ b/suites/rados/verify/clusters/fixed-2.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-2.yaml
\ No newline at end of file
diff --git a/suites/rados/verify/fs/btrfs.yaml b/suites/rados/verify/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/rados/verify/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/rados/verify/msgr-failures/few.yaml b/suites/rados/verify/msgr-failures/few.yaml
new file mode 100644
index 000000000..0de320d46
--- /dev/null
+++ b/suites/rados/verify/msgr-failures/few.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 5000
diff --git a/suites/rados/verify/tasks/mon_recovery.yaml b/suites/rados/verify/tasks/mon_recovery.yaml
new file mode 100644
index 000000000..698630340
--- /dev/null
+++ b/suites/rados/verify/tasks/mon_recovery.yaml
@@ -0,0 +1,2 @@
+tasks:
+- mon_recovery:
diff --git a/suites/rados/verify/tasks/rados_api_tests.yaml b/suites/rados/verify/tasks/rados_api_tests.yaml
new file mode 100644
index 000000000..cd11ae6ca
--- /dev/null
+++ b/suites/rados/verify/tasks/rados_api_tests.yaml
@@ -0,0 +1,5 @@
+tasks:
+- workunit:
+ clients:
+ client.0:
+ - rados/test.sh
diff --git a/suites/rados/verify/tasks/rados_cls_all.yaml b/suites/rados/verify/tasks/rados_cls_all.yaml
new file mode 100644
index 000000000..853da39ad
--- /dev/null
+++ b/suites/rados/verify/tasks/rados_cls_all.yaml
@@ -0,0 +1,5 @@
+tasks:
+- workunit:
+ clients:
+ client.0:
+ - cls
diff --git a/suites/rados/verify/validater/lockdep.yaml b/suites/rados/verify/validater/lockdep.yaml
new file mode 100644
index 000000000..25f84355c
--- /dev/null
+++ b/suites/rados/verify/validater/lockdep.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ lockdep: true
diff --git a/suites/rados/verify/validater/valgrind.yaml b/suites/rados/verify/validater/valgrind.yaml
new file mode 100644
index 000000000..7b8f7a286
--- /dev/null
+++ b/suites/rados/verify/validater/valgrind.yaml
@@ -0,0 +1,9 @@
+overrides:
+ install:
+ ceph:
+ flavor: notcmalloc
+ ceph:
+ valgrind:
+ mon: [--tool=memcheck, --leak-check=full, --show-reachable=yes]
+ osd: [--tool=memcheck]
+ mds: [--tool=memcheck]
diff --git a/suites/rbd/basic/% b/suites/rbd/basic/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/rbd/basic/clusters/fixed-1.yaml b/suites/rbd/basic/clusters/fixed-1.yaml
new file mode 120000
index 000000000..435ea3c75
--- /dev/null
+++ b/suites/rbd/basic/clusters/fixed-1.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-1.yaml
\ No newline at end of file
diff --git a/suites/rbd/basic/fs/btrfs.yaml b/suites/rbd/basic/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/rbd/basic/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/rbd/basic/msgr-failures/few.yaml b/suites/rbd/basic/msgr-failures/few.yaml
new file mode 100644
index 000000000..0de320d46
--- /dev/null
+++ b/suites/rbd/basic/msgr-failures/few.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 5000
diff --git a/suites/rbd/basic/msgr-failures/many.yaml b/suites/rbd/basic/msgr-failures/many.yaml
new file mode 100644
index 000000000..86f8dde8a
--- /dev/null
+++ b/suites/rbd/basic/msgr-failures/many.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 500
diff --git a/suites/rbd/basic/tasks/rbd_api_tests_old_format.yaml b/suites/rbd/basic/tasks/rbd_api_tests_old_format.yaml
new file mode 100644
index 000000000..f9e4110b5
--- /dev/null
+++ b/suites/rbd/basic/tasks/rbd_api_tests_old_format.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ client.0:
+ - rbd/test_librbd.sh
diff --git a/suites/rbd/basic/tasks/rbd_cli_copy.yaml b/suites/rbd/basic/tasks/rbd_cli_copy.yaml
new file mode 100644
index 000000000..cb954edeb
--- /dev/null
+++ b/suites/rbd/basic/tasks/rbd_cli_copy.yaml
@@ -0,0 +1,9 @@
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ client.0:
+ - rbd/copy.sh
+ env:
+ RBD_CREATE_ARGS: --new-format
diff --git a/suites/rbd/basic/tasks/rbd_cli_copy_old_format.yaml b/suites/rbd/basic/tasks/rbd_cli_copy_old_format.yaml
new file mode 100644
index 000000000..3ca43192f
--- /dev/null
+++ b/suites/rbd/basic/tasks/rbd_cli_copy_old_format.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ client.0:
+ - rbd/copy.sh
diff --git a/suites/rbd/basic/tasks/rbd_cli_import_export.yaml b/suites/rbd/basic/tasks/rbd_cli_import_export.yaml
new file mode 100644
index 000000000..5093e69ee
--- /dev/null
+++ b/suites/rbd/basic/tasks/rbd_cli_import_export.yaml
@@ -0,0 +1,9 @@
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ client.0:
+ - rbd/import_export.sh
+ env:
+ RBD_CREATE_ARGS: --new-format
diff --git a/suites/rbd/basic/tasks/rbd_cli_import_export_old_format.yaml b/suites/rbd/basic/tasks/rbd_cli_import_export_old_format.yaml
new file mode 100644
index 000000000..21fb494c1
--- /dev/null
+++ b/suites/rbd/basic/tasks/rbd_cli_import_export_old_format.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ client.0:
+ - rbd/import_export.sh
diff --git a/suites/rbd/basic/tasks/rbd_cli_tests.yaml b/suites/rbd/basic/tasks/rbd_cli_tests.yaml
new file mode 100644
index 000000000..c66fefe80
--- /dev/null
+++ b/suites/rbd/basic/tasks/rbd_cli_tests.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ client.0:
+ - rbd/run_cli_tests.sh
+
diff --git a/suites/rbd/basic/tasks/rbd_cls_tests.yaml b/suites/rbd/basic/tasks/rbd_cls_tests.yaml
new file mode 100644
index 000000000..6a3c73f33
--- /dev/null
+++ b/suites/rbd/basic/tasks/rbd_cls_tests.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ client.0:
+ - cls/test_cls_rbd.sh
diff --git a/suites/rbd/basic/tasks/rbd_lock_and_fence.yaml b/suites/rbd/basic/tasks/rbd_lock_and_fence.yaml
new file mode 100644
index 000000000..961e1c17b
--- /dev/null
+++ b/suites/rbd/basic/tasks/rbd_lock_and_fence.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ client.0:
+ - rbd/test_lock_fence.sh
diff --git a/suites/rbd/basic/tasks/rbd_python_api_tests_old_format.yaml b/suites/rbd/basic/tasks/rbd_python_api_tests_old_format.yaml
new file mode 100644
index 000000000..4d93e73d9
--- /dev/null
+++ b/suites/rbd/basic/tasks/rbd_python_api_tests_old_format.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- workunit:
+ clients:
+ client.0:
+ - rbd/test_librbd_python.sh
diff --git a/suites/rbd/librbd/% b/suites/rbd/librbd/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/rbd/librbd/cache/none.yaml b/suites/rbd/librbd/cache/none.yaml
new file mode 100644
index 000000000..42fd9c955
--- /dev/null
+++ b/suites/rbd/librbd/cache/none.yaml
@@ -0,0 +1,6 @@
+tasks:
+- install:
+- ceph:
+ conf:
+ client:
+ rbd cache: false
diff --git a/suites/rbd/librbd/cache/writeback.yaml b/suites/rbd/librbd/cache/writeback.yaml
new file mode 100644
index 000000000..86fe06afa
--- /dev/null
+++ b/suites/rbd/librbd/cache/writeback.yaml
@@ -0,0 +1,6 @@
+tasks:
+- install:
+- ceph:
+ conf:
+ client:
+ rbd cache: true
diff --git a/suites/rbd/librbd/cache/writethrough.yaml b/suites/rbd/librbd/cache/writethrough.yaml
new file mode 100644
index 000000000..6dc29e16c
--- /dev/null
+++ b/suites/rbd/librbd/cache/writethrough.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+ conf:
+ client:
+ rbd cache: true
+ rbd cache max dirty: 0
diff --git a/suites/rbd/librbd/clusters/fixed-3.yaml b/suites/rbd/librbd/clusters/fixed-3.yaml
new file mode 120000
index 000000000..a3ac9fc4d
--- /dev/null
+++ b/suites/rbd/librbd/clusters/fixed-3.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-3.yaml
\ No newline at end of file
diff --git a/suites/rbd/librbd/fs b/suites/rbd/librbd/fs
new file mode 120000
index 000000000..365892036
--- /dev/null
+++ b/suites/rbd/librbd/fs
@@ -0,0 +1 @@
+../basic/fs
\ No newline at end of file
diff --git a/suites/rbd/librbd/msgr-failures/few.yaml b/suites/rbd/librbd/msgr-failures/few.yaml
new file mode 100644
index 000000000..0de320d46
--- /dev/null
+++ b/suites/rbd/librbd/msgr-failures/few.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 5000
diff --git a/suites/rbd/librbd/workloads/c_api_tests.yaml b/suites/rbd/librbd/workloads/c_api_tests.yaml
new file mode 100644
index 000000000..188ddc56c
--- /dev/null
+++ b/suites/rbd/librbd/workloads/c_api_tests.yaml
@@ -0,0 +1,7 @@
+tasks:
+- workunit:
+ clients:
+ client.0:
+ - rbd/test_librbd.sh
+ env:
+ RBD_FEATURES: "1"
diff --git a/suites/rbd/librbd/workloads/fsx.yaml b/suites/rbd/librbd/workloads/fsx.yaml
new file mode 100644
index 000000000..ef512d8a9
--- /dev/null
+++ b/suites/rbd/librbd/workloads/fsx.yaml
@@ -0,0 +1,4 @@
+tasks:
+- rbd_fsx:
+ clients: [client.0]
+ ops: 5000
diff --git a/suites/rbd/librbd/workloads/python_api_tests.yaml b/suites/rbd/librbd/workloads/python_api_tests.yaml
new file mode 100644
index 000000000..a7b3ce7d3
--- /dev/null
+++ b/suites/rbd/librbd/workloads/python_api_tests.yaml
@@ -0,0 +1,7 @@
+tasks:
+- workunit:
+ clients:
+ client.0:
+ - rbd/test_librbd_python.sh
+ env:
+ RBD_FEATURES: "1"
diff --git a/suites/rbd/librbd/workloads/qemu_bonnie.yaml b/suites/rbd/librbd/workloads/qemu_bonnie.yaml
new file mode 100644
index 000000000..45368ee94
--- /dev/null
+++ b/suites/rbd/librbd/workloads/qemu_bonnie.yaml
@@ -0,0 +1,5 @@
+tasks:
+- qemu:
+ all:
+ test: https://ceph.com/git/?p=ceph.git;a=blob_plain;f=qa/workunits/suites/bonnie.sh
+exclude_arch: armv7l
diff --git a/suites/rbd/librbd/workloads/qemu_fsstress.yaml b/suites/rbd/librbd/workloads/qemu_fsstress.yaml
new file mode 100644
index 000000000..9ca3e1760
--- /dev/null
+++ b/suites/rbd/librbd/workloads/qemu_fsstress.yaml
@@ -0,0 +1,5 @@
+tasks:
+- qemu:
+ all:
+ test: https://ceph.com/git/?p=ceph.git;a=blob_plain;f=qa/workunits/suites/fsstress.sh
+exclude_arch: armv7l
diff --git a/suites/rbd/librbd/workloads/qemu_iozone.yaml.disabled b/suites/rbd/librbd/workloads/qemu_iozone.yaml.disabled
new file mode 100644
index 000000000..dfd41818a
--- /dev/null
+++ b/suites/rbd/librbd/workloads/qemu_iozone.yaml.disabled
@@ -0,0 +1,6 @@
+tasks:
+- qemu:
+ all:
+ test: https://ceph.com/git/?p=ceph.git;a=blob_plain;f=qa/workunits/suites/iozone.sh
+ image_size: 20480
+exclude_arch: armv7l
diff --git a/suites/rbd/librbd/workloads/qemu_tiobench.yaml b/suites/rbd/librbd/workloads/qemu_tiobench.yaml
new file mode 100644
index 000000000..3f17df3e6
--- /dev/null
+++ b/suites/rbd/librbd/workloads/qemu_tiobench.yaml
@@ -0,0 +1,5 @@
+tasks:
+- qemu:
+ all:
+ test: https://ceph.com/git/?p=ceph.git;a=blob_plain;f=qa/workunits/suites/tiobench.sh
+exclude_arch: armv7l
diff --git a/suites/rbd/librbd/workloads/qemu_xfstests.yaml b/suites/rbd/librbd/workloads/qemu_xfstests.yaml
new file mode 100644
index 000000000..fa0fe22b5
--- /dev/null
+++ b/suites/rbd/librbd/workloads/qemu_xfstests.yaml
@@ -0,0 +1,7 @@
+tasks:
+- qemu:
+ all:
+ type: block
+ num_rbd: 2
+ test: https://ceph.com/git/?p=ceph.git;a=blob_plain;f=qa/run_xfstests_qemu.sh
+exclude_arch: armv7l
diff --git a/suites/rbd/singleton/% b/suites/rbd/singleton/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/rbd/singleton/all/formatted-output.yaml b/suites/rbd/singleton/all/formatted-output.yaml
new file mode 100644
index 000000000..a120f185a
--- /dev/null
+++ b/suites/rbd/singleton/all/formatted-output.yaml
@@ -0,0 +1,9 @@
+roles:
+- [mon.a, osd.0, osd.1, client.0]
+tasks:
+- install:
+- ceph:
+- cram:
+ clients:
+ client.0:
+ - https://ceph.com/git/?p=ceph.git;a=blob_plain;;hb=c7a0477bad6bfbec4ef325295ca0489ec197792;f=src/test/cli-integration/rbd/formatted-output.t
diff --git a/suites/rbd/singleton/all/qemu-iotests-no-cache.yaml b/suites/rbd/singleton/all/qemu-iotests-no-cache.yaml
new file mode 100644
index 000000000..e6b71a0e2
--- /dev/null
+++ b/suites/rbd/singleton/all/qemu-iotests-no-cache.yaml
@@ -0,0 +1,11 @@
+roles:
+- [mon.a, osd.0, osd.1, client.0]
+tasks:
+- install:
+- ceph:
+ conf:
+ client:
+ rbd cache: false
+- workunit:
+ clients:
+ all: [rbd/qemu-iotests.sh]
diff --git a/suites/rbd/singleton/all/qemu-iotests-writeback.yaml b/suites/rbd/singleton/all/qemu-iotests-writeback.yaml
new file mode 100644
index 000000000..81afb8234
--- /dev/null
+++ b/suites/rbd/singleton/all/qemu-iotests-writeback.yaml
@@ -0,0 +1,11 @@
+roles:
+- [mon.a, osd.0, osd.1, client.0]
+tasks:
+- install:
+- ceph:
+ conf:
+ client:
+ rbd cache: true
+- workunit:
+ clients:
+ all: [rbd/qemu-iotests.sh]
diff --git a/suites/rbd/singleton/all/qemu-iotests-writethrough.yaml b/suites/rbd/singleton/all/qemu-iotests-writethrough.yaml
new file mode 100644
index 000000000..1bb195a28
--- /dev/null
+++ b/suites/rbd/singleton/all/qemu-iotests-writethrough.yaml
@@ -0,0 +1,12 @@
+roles:
+- [mon.a, osd.0, osd.1, client.0]
+tasks:
+- install:
+- ceph:
+ conf:
+ client:
+ rbd cache: true
+ rbd cache max dirty: 0
+- workunit:
+ clients:
+ all: [rbd/qemu-iotests.sh]
diff --git a/suites/rbd/singleton/all/read-flags-no-cache.yaml b/suites/rbd/singleton/all/read-flags-no-cache.yaml
new file mode 100644
index 000000000..f7d44456d
--- /dev/null
+++ b/suites/rbd/singleton/all/read-flags-no-cache.yaml
@@ -0,0 +1,11 @@
+roles:
+- [mon.a, osd.0, osd.1, client.0]
+tasks:
+- install:
+- ceph:
+ conf:
+ client:
+ rbd cache: false
+- workunit:
+ clients:
+ all: [rbd/read-flags.sh]
diff --git a/suites/rbd/singleton/all/read-flags-writeback.yaml b/suites/rbd/singleton/all/read-flags-writeback.yaml
new file mode 100644
index 000000000..f25be79e0
--- /dev/null
+++ b/suites/rbd/singleton/all/read-flags-writeback.yaml
@@ -0,0 +1,11 @@
+roles:
+- [mon.a, osd.0, osd.1, client.0]
+tasks:
+- install:
+- ceph:
+ conf:
+ client:
+ rbd cache: true
+- workunit:
+ clients:
+ all: [rbd/read-flags.sh]
diff --git a/suites/rbd/singleton/all/read-flags-writethrough.yaml b/suites/rbd/singleton/all/read-flags-writethrough.yaml
new file mode 100644
index 000000000..80d7b4254
--- /dev/null
+++ b/suites/rbd/singleton/all/read-flags-writethrough.yaml
@@ -0,0 +1,12 @@
+roles:
+- [mon.a, osd.0, osd.1, client.0]
+tasks:
+- install:
+- ceph:
+ conf:
+ client:
+ rbd cache: true
+ rbd cache max dirty: 0
+- workunit:
+ clients:
+ all: [rbd/read-flags.sh]
diff --git a/suites/rbd/thrash/% b/suites/rbd/thrash/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/rbd/thrash/clusters/fixed-2.yaml b/suites/rbd/thrash/clusters/fixed-2.yaml
new file mode 120000
index 000000000..cd0791a14
--- /dev/null
+++ b/suites/rbd/thrash/clusters/fixed-2.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-2.yaml
\ No newline at end of file
diff --git a/suites/rbd/thrash/fs/btrfs.yaml b/suites/rbd/thrash/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/rbd/thrash/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/rbd/thrash/fs/xfs.yaml b/suites/rbd/thrash/fs/xfs.yaml
new file mode 100644
index 000000000..bfc3d618f
--- /dev/null
+++ b/suites/rbd/thrash/fs/xfs.yaml
@@ -0,0 +1,3 @@
+overrides:
+ ceph:
+ fs: xfs
diff --git a/suites/rbd/thrash/msgr-failures/few.yaml b/suites/rbd/thrash/msgr-failures/few.yaml
new file mode 100644
index 000000000..0de320d46
--- /dev/null
+++ b/suites/rbd/thrash/msgr-failures/few.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 5000
diff --git a/suites/rbd/thrash/thrashers/default.yaml b/suites/rbd/thrash/thrashers/default.yaml
new file mode 100644
index 000000000..04552142a
--- /dev/null
+++ b/suites/rbd/thrash/thrashers/default.yaml
@@ -0,0 +1,9 @@
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+- thrashosds:
+ thrash_primary_affinity: false
+ timeout: 1200
diff --git a/suites/rbd/thrash/workloads/rbd_api_tests.yaml b/suites/rbd/thrash/workloads/rbd_api_tests.yaml
new file mode 100644
index 000000000..188ddc56c
--- /dev/null
+++ b/suites/rbd/thrash/workloads/rbd_api_tests.yaml
@@ -0,0 +1,7 @@
+tasks:
+- workunit:
+ clients:
+ client.0:
+ - rbd/test_librbd.sh
+ env:
+ RBD_FEATURES: "1"
diff --git a/suites/rbd/thrash/workloads/rbd_fsx_cache_writeback.yaml b/suites/rbd/thrash/workloads/rbd_fsx_cache_writeback.yaml
new file mode 100644
index 000000000..bd812695c
--- /dev/null
+++ b/suites/rbd/thrash/workloads/rbd_fsx_cache_writeback.yaml
@@ -0,0 +1,9 @@
+tasks:
+- rbd_fsx:
+ clients: [client.0]
+ ops: 2000
+overrides:
+ ceph:
+ conf:
+ client:
+ rbd cache: true
diff --git a/suites/rbd/thrash/workloads/rbd_fsx_cache_writethrough.yaml b/suites/rbd/thrash/workloads/rbd_fsx_cache_writethrough.yaml
new file mode 100644
index 000000000..568952980
--- /dev/null
+++ b/suites/rbd/thrash/workloads/rbd_fsx_cache_writethrough.yaml
@@ -0,0 +1,10 @@
+tasks:
+- rbd_fsx:
+ clients: [client.0]
+ ops: 2000
+overrides:
+ ceph:
+ conf:
+ client:
+ rbd cache: true
+ rbd cache max dirty: 0
diff --git a/suites/rbd/thrash/workloads/rbd_fsx_nocache.yaml b/suites/rbd/thrash/workloads/rbd_fsx_nocache.yaml
new file mode 100644
index 000000000..6c5e0e457
--- /dev/null
+++ b/suites/rbd/thrash/workloads/rbd_fsx_nocache.yaml
@@ -0,0 +1,9 @@
+tasks:
+- rbd_fsx:
+ clients: [client.0]
+ ops: 2000
+overrides:
+ ceph:
+ conf:
+ client:
+ rbd cache: false
diff --git a/suites/regression/fs-basic b/suites/regression/fs-basic
new file mode 120000
index 000000000..06774f995
--- /dev/null
+++ b/suites/regression/fs-basic
@@ -0,0 +1 @@
+../fs/basic
\ No newline at end of file
diff --git a/suites/regression/fs-traceless b/suites/regression/fs-traceless
new file mode 120000
index 000000000..df75523ef
--- /dev/null
+++ b/suites/regression/fs-traceless
@@ -0,0 +1 @@
+../fs/traceless
\ No newline at end of file
diff --git a/suites/regression/fs-verify b/suites/regression/fs-verify
new file mode 120000
index 000000000..ac9377397
--- /dev/null
+++ b/suites/regression/fs-verify
@@ -0,0 +1 @@
+../fs/verify
\ No newline at end of file
diff --git a/suites/regression/kernel-cephfs b/suites/regression/kernel-cephfs
new file mode 120000
index 000000000..f8ce33f7d
--- /dev/null
+++ b/suites/regression/kernel-cephfs
@@ -0,0 +1 @@
+../kernel/cephfs
\ No newline at end of file
diff --git a/suites/regression/kernel-rbd b/suites/regression/kernel-rbd
new file mode 120000
index 000000000..58370baab
--- /dev/null
+++ b/suites/regression/kernel-rbd
@@ -0,0 +1 @@
+../kernel/rbd
\ No newline at end of file
diff --git a/suites/regression/kernel-singleton b/suites/regression/kernel-singleton
new file mode 120000
index 000000000..e4ba5826f
--- /dev/null
+++ b/suites/regression/kernel-singleton
@@ -0,0 +1 @@
+../kernel/singleton
\ No newline at end of file
diff --git a/suites/regression/kernel-thrash b/suites/regression/kernel-thrash
new file mode 120000
index 000000000..6ac2a7855
--- /dev/null
+++ b/suites/regression/kernel-thrash
@@ -0,0 +1 @@
+../kernel/thrash
\ No newline at end of file
diff --git a/suites/regression/nfs-basic b/suites/regression/nfs-basic
new file mode 120000
index 000000000..156c33187
--- /dev/null
+++ b/suites/regression/nfs-basic
@@ -0,0 +1 @@
+../nfs/basic/
\ No newline at end of file
diff --git a/suites/regression/rados-basic b/suites/regression/rados-basic
new file mode 120000
index 000000000..490ca1d58
--- /dev/null
+++ b/suites/regression/rados-basic
@@ -0,0 +1 @@
+../rados/basic
\ No newline at end of file
diff --git a/suites/regression/rados-monthrash b/suites/regression/rados-monthrash
new file mode 120000
index 000000000..754aedde8
--- /dev/null
+++ b/suites/regression/rados-monthrash
@@ -0,0 +1 @@
+../rados/monthrash/
\ No newline at end of file
diff --git a/suites/regression/rados-multimon b/suites/regression/rados-multimon
new file mode 120000
index 000000000..183dd5060
--- /dev/null
+++ b/suites/regression/rados-multimon
@@ -0,0 +1 @@
+../rados/multimon
\ No newline at end of file
diff --git a/suites/regression/rados-singleton b/suites/regression/rados-singleton
new file mode 120000
index 000000000..211ca683c
--- /dev/null
+++ b/suites/regression/rados-singleton
@@ -0,0 +1 @@
+../rados/singleton
\ No newline at end of file
diff --git a/suites/regression/rados-thrash b/suites/regression/rados-thrash
new file mode 120000
index 000000000..e6803820c
--- /dev/null
+++ b/suites/regression/rados-thrash
@@ -0,0 +1 @@
+../rados/thrash
\ No newline at end of file
diff --git a/suites/regression/rados-verify b/suites/regression/rados-verify
new file mode 120000
index 000000000..ac3710773
--- /dev/null
+++ b/suites/regression/rados-verify
@@ -0,0 +1 @@
+../rados/verify
\ No newline at end of file
diff --git a/suites/regression/rbd-basic b/suites/regression/rbd-basic
new file mode 120000
index 000000000..ae23de1ec
--- /dev/null
+++ b/suites/regression/rbd-basic
@@ -0,0 +1 @@
+../rbd/basic
\ No newline at end of file
diff --git a/suites/regression/rbd-librbd b/suites/regression/rbd-librbd
new file mode 120000
index 000000000..58f2bd93e
--- /dev/null
+++ b/suites/regression/rbd-librbd
@@ -0,0 +1 @@
+../rbd/librbd
\ No newline at end of file
diff --git a/suites/regression/rbd-singleton b/suites/regression/rbd-singleton
new file mode 120000
index 000000000..f01ee0de0
--- /dev/null
+++ b/suites/regression/rbd-singleton
@@ -0,0 +1 @@
+../rbd/singleton/
\ No newline at end of file
diff --git a/suites/regression/rbd-thrash b/suites/regression/rbd-thrash
new file mode 120000
index 000000000..080dac982
--- /dev/null
+++ b/suites/regression/rbd-thrash
@@ -0,0 +1 @@
+../rbd/thrash
\ No newline at end of file
diff --git a/suites/regression/rgw-multifs b/suites/regression/rgw-multifs
new file mode 120000
index 000000000..a2ef33fbd
--- /dev/null
+++ b/suites/regression/rgw-multifs
@@ -0,0 +1 @@
+../rgw/multifs
\ No newline at end of file
diff --git a/suites/regression/rgw-verify b/suites/regression/rgw-verify
new file mode 120000
index 000000000..657024010
--- /dev/null
+++ b/suites/regression/rgw-verify
@@ -0,0 +1 @@
+../rgw/verify
\ No newline at end of file
diff --git a/suites/rgw/multifs/% b/suites/rgw/multifs/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/rgw/multifs/clusters/fixed-2.yaml b/suites/rgw/multifs/clusters/fixed-2.yaml
new file mode 120000
index 000000000..cd0791a14
--- /dev/null
+++ b/suites/rgw/multifs/clusters/fixed-2.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-2.yaml
\ No newline at end of file
diff --git a/suites/rgw/multifs/fs/btrfs.yaml b/suites/rgw/multifs/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/rgw/multifs/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/rgw/multifs/fs/ext4.yaml b/suites/rgw/multifs/fs/ext4.yaml
new file mode 100644
index 000000000..fde675175
--- /dev/null
+++ b/suites/rgw/multifs/fs/ext4.yaml
@@ -0,0 +1,3 @@
+overrides:
+ ceph:
+ fs: ext4
diff --git a/suites/rgw/multifs/fs/xfs.yaml b/suites/rgw/multifs/fs/xfs.yaml
new file mode 100644
index 000000000..bfc3d618f
--- /dev/null
+++ b/suites/rgw/multifs/fs/xfs.yaml
@@ -0,0 +1,3 @@
+overrides:
+ ceph:
+ fs: xfs
diff --git a/suites/rgw/multifs/tasks/rgw_readwrite.yaml b/suites/rgw/multifs/tasks/rgw_readwrite.yaml
new file mode 100644
index 000000000..c7efaa1c7
--- /dev/null
+++ b/suites/rgw/multifs/tasks/rgw_readwrite.yaml
@@ -0,0 +1,16 @@
+tasks:
+- install:
+- ceph:
+- rgw: [client.0]
+- s3readwrite:
+ client.0:
+ rgw_server: client.0
+ readwrite:
+ bucket: rwtest
+ readers: 10
+ writers: 3
+ duration: 300
+ files:
+ num: 10
+ size: 2000
+ stddev: 500
diff --git a/suites/rgw/multifs/tasks/rgw_roundtrip.yaml b/suites/rgw/multifs/tasks/rgw_roundtrip.yaml
new file mode 100644
index 000000000..47b3c1894
--- /dev/null
+++ b/suites/rgw/multifs/tasks/rgw_roundtrip.yaml
@@ -0,0 +1,16 @@
+tasks:
+- install:
+- ceph:
+- rgw: [client.0]
+- s3roundtrip:
+ client.0:
+ rgw_server: client.0
+ roundtrip:
+ bucket: rttest
+ readers: 10
+ writers: 3
+ duration: 300
+ files:
+ num: 10
+ size: 2000
+ stddev: 500
diff --git a/suites/rgw/multifs/tasks/rgw_s3tests.yaml b/suites/rgw/multifs/tasks/rgw_s3tests.yaml
new file mode 100644
index 000000000..62608773a
--- /dev/null
+++ b/suites/rgw/multifs/tasks/rgw_s3tests.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- rgw: [client.0]
+- s3tests:
+ client.0:
+ rgw_server: client.0
diff --git a/suites/rgw/multifs/tasks/rgw_swift.yaml b/suites/rgw/multifs/tasks/rgw_swift.yaml
new file mode 100644
index 000000000..569741b0e
--- /dev/null
+++ b/suites/rgw/multifs/tasks/rgw_swift.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- rgw: [client.0]
+- swift:
+ client.0:
+ rgw_server: client.0
diff --git a/suites/rgw/singleton/% b/suites/rgw/singleton/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/rgw/singleton/all/radosgw-admin.yaml b/suites/rgw/singleton/all/radosgw-admin.yaml
new file mode 100644
index 000000000..67aa5f92e
--- /dev/null
+++ b/suites/rgw/singleton/all/radosgw-admin.yaml
@@ -0,0 +1,15 @@
+roles:
+- [mon.a, mds.a, osd.0, client.0, osd.1]
+tasks:
+- install:
+- ceph:
+ conf:
+ client:
+ debug ms: 1
+ rgw gc obj min wait: 15
+ osd:
+ debug ms: 1
+ debug objclass : 20
+- rgw:
+ client.0:
+- radosgw-admin:
diff --git a/suites/rgw/verify/% b/suites/rgw/verify/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/rgw/verify/clusters/fixed-2.yaml b/suites/rgw/verify/clusters/fixed-2.yaml
new file mode 120000
index 000000000..cd0791a14
--- /dev/null
+++ b/suites/rgw/verify/clusters/fixed-2.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-2.yaml
\ No newline at end of file
diff --git a/suites/rgw/verify/fs/btrfs.yaml b/suites/rgw/verify/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/rgw/verify/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/rgw/verify/msgr-failures/few.yaml b/suites/rgw/verify/msgr-failures/few.yaml
new file mode 100644
index 000000000..0de320d46
--- /dev/null
+++ b/suites/rgw/verify/msgr-failures/few.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ ms inject socket failures: 5000
diff --git a/suites/rgw/verify/tasks/rgw_s3tests.yaml b/suites/rgw/verify/tasks/rgw_s3tests.yaml
new file mode 100644
index 000000000..c23a2cbf4
--- /dev/null
+++ b/suites/rgw/verify/tasks/rgw_s3tests.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ flavor: notcmalloc
+- ceph:
+- rgw:
+ client.0:
+ valgrind: [--tool=memcheck]
+- s3tests:
+ client.0:
+ rgw_server: client.0
diff --git a/suites/rgw/verify/tasks/rgw_swift.yaml b/suites/rgw/verify/tasks/rgw_swift.yaml
new file mode 100644
index 000000000..792fb848a
--- /dev/null
+++ b/suites/rgw/verify/tasks/rgw_swift.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ flavor: notcmalloc
+- ceph:
+- rgw:
+ client.0:
+ valgrind: [--tool=memcheck]
+- swift:
+ client.0:
+ rgw_server: client.0
diff --git a/suites/rgw/verify/validater/lockdep.yaml b/suites/rgw/verify/validater/lockdep.yaml
new file mode 100644
index 000000000..941fe12b1
--- /dev/null
+++ b/suites/rgw/verify/validater/lockdep.yaml
@@ -0,0 +1,7 @@
+overrides:
+ ceph:
+ conf:
+ osd:
+ lockdep: true
+ mon:
+ lockdep: true
diff --git a/suites/rgw/verify/validater/valgrind.yaml b/suites/rgw/verify/validater/valgrind.yaml
new file mode 100644
index 000000000..7b8f7a286
--- /dev/null
+++ b/suites/rgw/verify/validater/valgrind.yaml
@@ -0,0 +1,9 @@
+overrides:
+ install:
+ ceph:
+ flavor: notcmalloc
+ ceph:
+ valgrind:
+ mon: [--tool=memcheck, --leak-check=full, --show-reachable=yes]
+ osd: [--tool=memcheck]
+ mds: [--tool=memcheck]
diff --git a/suites/smoke/basic/% b/suites/smoke/basic/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/smoke/basic/clusters/fixed-3.yaml b/suites/smoke/basic/clusters/fixed-3.yaml
new file mode 120000
index 000000000..a3ac9fc4d
--- /dev/null
+++ b/suites/smoke/basic/clusters/fixed-3.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-3.yaml
\ No newline at end of file
diff --git a/suites/smoke/basic/fs/btrfs.yaml b/suites/smoke/basic/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/smoke/basic/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/smoke/basic/tasks/cfuse_workunit_suites_blogbench.yaml b/suites/smoke/basic/tasks/cfuse_workunit_suites_blogbench.yaml
new file mode 100644
index 000000000..ed9d92d5b
--- /dev/null
+++ b/suites/smoke/basic/tasks/cfuse_workunit_suites_blogbench.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/blogbench.sh
diff --git a/suites/smoke/basic/tasks/cfuse_workunit_suites_fsstress.yaml b/suites/smoke/basic/tasks/cfuse_workunit_suites_fsstress.yaml
new file mode 100644
index 000000000..b58487c07
--- /dev/null
+++ b/suites/smoke/basic/tasks/cfuse_workunit_suites_fsstress.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/fsstress.sh
diff --git a/suites/smoke/basic/tasks/cfuse_workunit_suites_iozone.yaml b/suites/smoke/basic/tasks/cfuse_workunit_suites_iozone.yaml
new file mode 100644
index 000000000..dc6df2f70
--- /dev/null
+++ b/suites/smoke/basic/tasks/cfuse_workunit_suites_iozone.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse: [client.0]
+- workunit:
+ clients:
+ all:
+ - suites/iozone.sh
diff --git a/suites/smoke/basic/tasks/cfuse_workunit_suites_pjd.yaml b/suites/smoke/basic/tasks/cfuse_workunit_suites_pjd.yaml
new file mode 100644
index 000000000..347c7fdf0
--- /dev/null
+++ b/suites/smoke/basic/tasks/cfuse_workunit_suites_pjd.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/pjd.sh
diff --git a/suites/smoke/basic/tasks/kclient_workunit_direct_io.yaml b/suites/smoke/basic/tasks/kclient_workunit_direct_io.yaml
new file mode 100644
index 000000000..ce9240700
--- /dev/null
+++ b/suites/smoke/basic/tasks/kclient_workunit_direct_io.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - direct_io
diff --git a/suites/smoke/basic/tasks/kclient_workunit_suites_dbench.yaml b/suites/smoke/basic/tasks/kclient_workunit_suites_dbench.yaml
new file mode 100644
index 000000000..77d045e87
--- /dev/null
+++ b/suites/smoke/basic/tasks/kclient_workunit_suites_dbench.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - suites/dbench.sh
diff --git a/suites/smoke/basic/tasks/kclient_workunit_suites_fsstress.yaml b/suites/smoke/basic/tasks/kclient_workunit_suites_fsstress.yaml
new file mode 100644
index 000000000..10b84b8af
--- /dev/null
+++ b/suites/smoke/basic/tasks/kclient_workunit_suites_fsstress.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - suites/fsstress.sh
diff --git a/suites/smoke/basic/tasks/kclient_workunit_suites_pjd.yaml b/suites/smoke/basic/tasks/kclient_workunit_suites_pjd.yaml
new file mode 100644
index 000000000..305de51e9
--- /dev/null
+++ b/suites/smoke/basic/tasks/kclient_workunit_suites_pjd.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - suites/pjd.sh
diff --git a/suites/smoke/basic/tasks/libcephfs_interface_tests.yaml b/suites/smoke/basic/tasks/libcephfs_interface_tests.yaml
new file mode 100644
index 000000000..22d1f1421
--- /dev/null
+++ b/suites/smoke/basic/tasks/libcephfs_interface_tests.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - libcephfs/test.sh
diff --git a/suites/smoke/basic/tasks/rados_python.yaml b/suites/smoke/basic/tasks/rados_python.yaml
new file mode 100644
index 000000000..b9ac20e57
--- /dev/null
+++ b/suites/smoke/basic/tasks/rados_python.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - rados/test_python.sh
diff --git a/suites/smoke/basic/tasks/rados_workunit_loadgen_mix.yaml b/suites/smoke/basic/tasks/rados_workunit_loadgen_mix.yaml
new file mode 100644
index 000000000..716deac21
--- /dev/null
+++ b/suites/smoke/basic/tasks/rados_workunit_loadgen_mix.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - rados/load-gen-mix.sh
diff --git a/suites/smoke/basic/tasks/rbd_api_tests.yaml b/suites/smoke/basic/tasks/rbd_api_tests.yaml
new file mode 100644
index 000000000..46e43b98a
--- /dev/null
+++ b/suites/smoke/basic/tasks/rbd_api_tests.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - rbd/test_librbd.sh
+ env:
+ RBD_FEATURES: "1"
diff --git a/suites/smoke/basic/tasks/rbd_api_tests_old_format.yaml b/suites/smoke/basic/tasks/rbd_api_tests_old_format.yaml
new file mode 100644
index 000000000..390b9c034
--- /dev/null
+++ b/suites/smoke/basic/tasks/rbd_api_tests_old_format.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - rbd/test_librbd.sh
diff --git a/suites/smoke/basic/tasks/rbd_cli_import_export.yaml b/suites/smoke/basic/tasks/rbd_cli_import_export.yaml
new file mode 100644
index 000000000..df23dc58f
--- /dev/null
+++ b/suites/smoke/basic/tasks/rbd_cli_import_export.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - rbd/import_export.sh
+ env:
+ RBD_CREATE_ARGS: --new-format
diff --git a/suites/smoke/basic/tasks/rbd_cli_import_export_old_format.yaml b/suites/smoke/basic/tasks/rbd_cli_import_export_old_format.yaml
new file mode 100644
index 000000000..c870ad421
--- /dev/null
+++ b/suites/smoke/basic/tasks/rbd_cli_import_export_old_format.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - rbd/import_export.sh
diff --git a/suites/smoke/basic/tasks/rbd_python_api_tests.yaml b/suites/smoke/basic/tasks/rbd_python_api_tests.yaml
new file mode 100644
index 000000000..9714a6e40
--- /dev/null
+++ b/suites/smoke/basic/tasks/rbd_python_api_tests.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - rbd/test_librbd_python.sh
+ env:
+ RBD_FEATURES: "1"
diff --git a/suites/smoke/basic/tasks/rbd_python_api_tests_old_format.yaml b/suites/smoke/basic/tasks/rbd_python_api_tests_old_format.yaml
new file mode 100644
index 000000000..642175f77
--- /dev/null
+++ b/suites/smoke/basic/tasks/rbd_python_api_tests_old_format.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - rbd/test_librbd_python.sh
diff --git a/suites/smoke/basic/tasks/rbd_workunit_suites_iozone.yaml b/suites/smoke/basic/tasks/rbd_workunit_suites_iozone.yaml
new file mode 100644
index 000000000..eb8f18d60
--- /dev/null
+++ b/suites/smoke/basic/tasks/rbd_workunit_suites_iozone.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+- ceph:
+- rbd:
+ all:
+ image_size: 20480
+- workunit:
+ clients:
+ all:
+ - suites/iozone.sh
diff --git a/suites/smoke/multiclient/% b/suites/smoke/multiclient/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/smoke/multiclient/clusters/two_clients.yaml b/suites/smoke/multiclient/clusters/two_clients.yaml
new file mode 100644
index 000000000..d062b8ce0
--- /dev/null
+++ b/suites/smoke/multiclient/clusters/two_clients.yaml
@@ -0,0 +1,4 @@
+roles:
+- [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1]
+- [client.1]
+- [client.0]
diff --git a/suites/smoke/multiclient/fs/btrfs.yaml b/suites/smoke/multiclient/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/smoke/multiclient/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/smoke/multiclient/tasks/locktest.yaml b/suites/smoke/multiclient/tasks/locktest.yaml
new file mode 100644
index 000000000..444bb1f19
--- /dev/null
+++ b/suites/smoke/multiclient/tasks/locktest.yaml
@@ -0,0 +1,5 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- locktest: [client.0, client.1]
diff --git a/suites/smoke/multifs/% b/suites/smoke/multifs/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/smoke/multifs/clusters/fixed-3.yaml b/suites/smoke/multifs/clusters/fixed-3.yaml
new file mode 120000
index 000000000..a3ac9fc4d
--- /dev/null
+++ b/suites/smoke/multifs/clusters/fixed-3.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-3.yaml
\ No newline at end of file
diff --git a/suites/smoke/multifs/fs/btrfs.yaml b/suites/smoke/multifs/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/smoke/multifs/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/smoke/multifs/tasks/rgw_s3tests.yaml b/suites/smoke/multifs/tasks/rgw_s3tests.yaml
new file mode 100644
index 000000000..62608773a
--- /dev/null
+++ b/suites/smoke/multifs/tasks/rgw_s3tests.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+- ceph:
+- rgw: [client.0]
+- s3tests:
+ client.0:
+ rgw_server: client.0
diff --git a/suites/smoke/multimon/% b/suites/smoke/multimon/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/smoke/multimon/clusters/6.yaml b/suites/smoke/multimon/clusters/6.yaml
new file mode 100644
index 000000000..662fc92b8
--- /dev/null
+++ b/suites/smoke/multimon/clusters/6.yaml
@@ -0,0 +1,4 @@
+roles:
+- [mon.a, mon.d, osd.0]
+- [mon.b, mon.e, mds.a]
+- [mon.c, mon.f, osd.1]
diff --git a/suites/smoke/multimon/tasks/mon_recovery.yaml b/suites/smoke/multimon/tasks/mon_recovery.yaml
new file mode 100644
index 000000000..94721ea53
--- /dev/null
+++ b/suites/smoke/multimon/tasks/mon_recovery.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install:
+- ceph:
+- mon_recovery:
diff --git a/suites/smoke/singleton/% b/suites/smoke/singleton/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/smoke/singleton/all/filestore-idempotent.yaml b/suites/smoke/singleton/all/filestore-idempotent.yaml
new file mode 100644
index 000000000..c6af200d5
--- /dev/null
+++ b/suites/smoke/singleton/all/filestore-idempotent.yaml
@@ -0,0 +1,6 @@
+roles:
+- [mon.0, osd.0, osd.1, mds.a, client.0]
+tasks:
+- install:
+- ceph:
+- filestore_idempotent:
diff --git a/suites/smoke/singleton/all/osd-backfill.yaml b/suites/smoke/singleton/all/osd-backfill.yaml
new file mode 100644
index 000000000..77a79440f
--- /dev/null
+++ b/suites/smoke/singleton/all/osd-backfill.yaml
@@ -0,0 +1,17 @@
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+- - mon.b
+ - mon.c
+ - osd.2
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ conf:
+ osd:
+ osd min pg log entries: 5
+- osd_backfill:
diff --git a/suites/smoke/singleton/all/thrash-rados.yaml b/suites/smoke/singleton/all/thrash-rados.yaml
new file mode 100644
index 000000000..bf63d80ef
--- /dev/null
+++ b/suites/smoke/singleton/all/thrash-rados.yaml
@@ -0,0 +1,24 @@
+roles:
+- - mon.a
+ - mds.0
+ - osd.0
+- - osd.1
+- - osd.2
+- - osd.3
+- - osd.4
+- - client.0
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+- thrashosds:
+ thrash_primary_affinity: false
+ op_delay: 30
+ clean_interval: 120
+ chance_down: .5
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - rados/load-gen-mix-small.sh
diff --git a/suites/smoke/singleton/fs/btrfs.yaml b/suites/smoke/singleton/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/smoke/singleton/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/smoke/thrash/% b/suites/smoke/thrash/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/smoke/thrash/clusters/6-osd-3-machine.yaml b/suites/smoke/thrash/clusters/6-osd-3-machine.yaml
new file mode 100644
index 000000000..f6247ebf2
--- /dev/null
+++ b/suites/smoke/thrash/clusters/6-osd-3-machine.yaml
@@ -0,0 +1,4 @@
+roles:
+- [mon.a, osd.0, osd.1, osd.2]
+- [mds.a, osd.3, osd.4, osd.5]
+- [client.0]
diff --git a/suites/smoke/thrash/fs/xfs.yaml b/suites/smoke/thrash/fs/xfs.yaml
new file mode 100644
index 000000000..bfc3d618f
--- /dev/null
+++ b/suites/smoke/thrash/fs/xfs.yaml
@@ -0,0 +1,3 @@
+overrides:
+ ceph:
+ fs: xfs
diff --git a/suites/smoke/thrash/thrashers/default.yaml b/suites/smoke/thrash/thrashers/default.yaml
new file mode 100644
index 000000000..b822d7422
--- /dev/null
+++ b/suites/smoke/thrash/thrashers/default.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+- thrashosds:
+ thrash_primary_affinity: false
diff --git a/suites/smoke/thrash/workloads/admin_socket_objecter_requests.yaml b/suites/smoke/thrash/workloads/admin_socket_objecter_requests.yaml
new file mode 100644
index 000000000..66791551f
--- /dev/null
+++ b/suites/smoke/thrash/workloads/admin_socket_objecter_requests.yaml
@@ -0,0 +1,13 @@
+overrides:
+ ceph:
+ conf:
+ client.0:
+ admin socket: /var/run/ceph/ceph-$name.asok
+tasks:
+- radosbench:
+ clients: [client.0]
+ time: 60
+- admin_socket:
+ client.0:
+ objecter_requests:
+ test: "http://ceph.newdream.net/git/?p=ceph.git;a=blob_plain;f=src/test/admin_socket/objecter_requests;hb={branch}"
diff --git a/suites/smoke/thrash/workloads/rbd_workunit_suites_iozone.yaml.disabled b/suites/smoke/thrash/workloads/rbd_workunit_suites_iozone.yaml.disabled
new file mode 100644
index 000000000..d61ede1bd
--- /dev/null
+++ b/suites/smoke/thrash/workloads/rbd_workunit_suites_iozone.yaml.disabled
@@ -0,0 +1,8 @@
+tasks:
+- rbd:
+ all:
+ image_size: 20480
+- workunit:
+ clients:
+ all:
+ - suites/iozone.sh
diff --git a/suites/smoke/thrash/workloads/snaps-few-objects.yaml b/suites/smoke/thrash/workloads/snaps-few-objects.yaml
new file mode 100644
index 000000000..c54039766
--- /dev/null
+++ b/suites/smoke/thrash/workloads/snaps-few-objects.yaml
@@ -0,0 +1,12 @@
+tasks:
+- rados:
+ clients: [client.0]
+ ops: 4000
+ objects: 50
+ op_weights:
+ read: 100
+ write: 100
+ delete: 50
+ snap_create: 50
+ snap_remove: 50
+ rollback: 50
diff --git a/suites/smoke/verify/% b/suites/smoke/verify/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/smoke/verify/clusters/fixed-3.yaml b/suites/smoke/verify/clusters/fixed-3.yaml
new file mode 120000
index 000000000..a3ac9fc4d
--- /dev/null
+++ b/suites/smoke/verify/clusters/fixed-3.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-3.yaml
\ No newline at end of file
diff --git a/suites/smoke/verify/fs/btrfs.yaml b/suites/smoke/verify/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/smoke/verify/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/smoke/verify/tasks/cfuse_workunit_suites_fsstress.yaml b/suites/smoke/verify/tasks/cfuse_workunit_suites_fsstress.yaml
new file mode 100644
index 000000000..b58487c07
--- /dev/null
+++ b/suites/smoke/verify/tasks/cfuse_workunit_suites_fsstress.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/fsstress.sh
diff --git a/suites/smoke/verify/tasks/libcephfs_interface_tests.yaml b/suites/smoke/verify/tasks/libcephfs_interface_tests.yaml
new file mode 100644
index 000000000..22d1f1421
--- /dev/null
+++ b/suites/smoke/verify/tasks/libcephfs_interface_tests.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - libcephfs/test.sh
diff --git a/suites/smoke/verify/tasks/mon_recovery.yaml b/suites/smoke/verify/tasks/mon_recovery.yaml
new file mode 100644
index 000000000..94721ea53
--- /dev/null
+++ b/suites/smoke/verify/tasks/mon_recovery.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install:
+- ceph:
+- mon_recovery:
diff --git a/suites/smoke/verify/tasks/rados_api_tests.yaml b/suites/smoke/verify/tasks/rados_api_tests.yaml
new file mode 100644
index 000000000..c154219bc
--- /dev/null
+++ b/suites/smoke/verify/tasks/rados_api_tests.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - rados/test.sh
diff --git a/suites/smoke/verify/tasks/rados_cls_all.yaml b/suites/smoke/verify/tasks/rados_cls_all.yaml
new file mode 100644
index 000000000..80be56276
--- /dev/null
+++ b/suites/smoke/verify/tasks/rados_cls_all.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - cls
diff --git a/suites/smoke/verify/tasks/rgw_s3tests.yaml b/suites/smoke/verify/tasks/rgw_s3tests.yaml
new file mode 100644
index 000000000..e50ce8bf0
--- /dev/null
+++ b/suites/smoke/verify/tasks/rgw_s3tests.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+- ceph:
+- rgw:
+ default_idle_timeout: 300
+ client.0:
+ valgrind: [--tool=memcheck]
+- s3tests:
+ client.0:
+ idle_timeout: 300
+ rgw_server: client.0
diff --git a/suites/smoke/verify/validater/lockdep.yaml b/suites/smoke/verify/validater/lockdep.yaml
new file mode 100644
index 000000000..25f84355c
--- /dev/null
+++ b/suites/smoke/verify/validater/lockdep.yaml
@@ -0,0 +1,5 @@
+overrides:
+ ceph:
+ conf:
+ global:
+ lockdep: true
diff --git a/suites/smoke/verify/validater/valgrind.yaml b/suites/smoke/verify/validater/valgrind.yaml
new file mode 100644
index 000000000..7b8f7a286
--- /dev/null
+++ b/suites/smoke/verify/validater/valgrind.yaml
@@ -0,0 +1,9 @@
+overrides:
+ install:
+ ceph:
+ flavor: notcmalloc
+ ceph:
+ valgrind:
+ mon: [--tool=memcheck, --leak-check=full, --show-reachable=yes]
+ osd: [--tool=memcheck]
+ mds: [--tool=memcheck]
diff --git a/suites/stress/bench/% b/suites/stress/bench/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/stress/bench/clusters/fixed-3.yaml b/suites/stress/bench/clusters/fixed-3.yaml
new file mode 120000
index 000000000..a3ac9fc4d
--- /dev/null
+++ b/suites/stress/bench/clusters/fixed-3.yaml
@@ -0,0 +1 @@
+../../../../clusters/fixed-3.yaml
\ No newline at end of file
diff --git a/suites/stress/bench/tasks/cfuse_workunit_snaps.yaml b/suites/stress/bench/tasks/cfuse_workunit_snaps.yaml
new file mode 100644
index 000000000..eafec39e3
--- /dev/null
+++ b/suites/stress/bench/tasks/cfuse_workunit_snaps.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - snaps
diff --git a/suites/stress/bench/tasks/kclient_workunit_suites_fsx.yaml b/suites/stress/bench/tasks/kclient_workunit_suites_fsx.yaml
new file mode 100644
index 000000000..a0d2e765b
--- /dev/null
+++ b/suites/stress/bench/tasks/kclient_workunit_suites_fsx.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+- kclient:
+- workunit:
+ clients:
+ all:
+ - suites/fsx.sh
diff --git a/suites/stress/thrash/% b/suites/stress/thrash/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/stress/thrash/clusters/16-osd.yaml b/suites/stress/thrash/clusters/16-osd.yaml
new file mode 100644
index 000000000..373dd4052
--- /dev/null
+++ b/suites/stress/thrash/clusters/16-osd.yaml
@@ -0,0 +1,18 @@
+roles:
+- [mon.0, mds.a, osd.0]
+- [mon.1, osd.1]
+- [mon.2, osd.2]
+- [osd.3]
+- [osd.4]
+- [osd.5]
+- [osd.6]
+- [osd.7]
+- [osd.8]
+- [osd.9]
+- [osd.10]
+- [osd.11]
+- [osd.12]
+- [osd.13]
+- [osd.14]
+- [osd.15]
+- [client.0]
diff --git a/suites/stress/thrash/clusters/3-osd-1-machine.yaml b/suites/stress/thrash/clusters/3-osd-1-machine.yaml
new file mode 100644
index 000000000..d8ff594b9
--- /dev/null
+++ b/suites/stress/thrash/clusters/3-osd-1-machine.yaml
@@ -0,0 +1,3 @@
+roles:
+- [mon.0, mds.a, osd.0, osd.1, osd.2]
+- [mon.1, mon.2, client.0]
diff --git a/suites/stress/thrash/clusters/8-osd.yaml b/suites/stress/thrash/clusters/8-osd.yaml
new file mode 100644
index 000000000..3b131054e
--- /dev/null
+++ b/suites/stress/thrash/clusters/8-osd.yaml
@@ -0,0 +1,10 @@
+roles:
+- [mon.0, mds.a, osd.0]
+- [mon.1, osd.1]
+- [mon.2, osd.2]
+- [osd.3]
+- [osd.4]
+- [osd.5]
+- [osd.6]
+- [osd.7]
+- [client.0]
diff --git a/suites/stress/thrash/fs/btrfs.yaml b/suites/stress/thrash/fs/btrfs.yaml
new file mode 100644
index 000000000..4c7af3115
--- /dev/null
+++ b/suites/stress/thrash/fs/btrfs.yaml
@@ -0,0 +1,6 @@
+overrides:
+ ceph:
+ fs: btrfs
+ conf:
+ osd:
+ osd op thread timeout: 60
diff --git a/suites/stress/thrash/fs/none.yaml b/suites/stress/thrash/fs/none.yaml
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/stress/thrash/fs/xfs.yaml b/suites/stress/thrash/fs/xfs.yaml
new file mode 100644
index 000000000..bfc3d618f
--- /dev/null
+++ b/suites/stress/thrash/fs/xfs.yaml
@@ -0,0 +1,3 @@
+overrides:
+ ceph:
+ fs: xfs
diff --git a/suites/stress/thrash/thrashers/default.yaml b/suites/stress/thrash/thrashers/default.yaml
new file mode 100644
index 000000000..b822d7422
--- /dev/null
+++ b/suites/stress/thrash/thrashers/default.yaml
@@ -0,0 +1,8 @@
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+- thrashosds:
+ thrash_primary_affinity: false
diff --git a/suites/stress/thrash/thrashers/fast.yaml b/suites/stress/thrash/thrashers/fast.yaml
new file mode 100644
index 000000000..e2209159b
--- /dev/null
+++ b/suites/stress/thrash/thrashers/fast.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+- thrashosds:
+ thrash_primary_affinity: false
+ op_delay: 1
+ chance_down: 10
diff --git a/suites/stress/thrash/thrashers/more-down.yaml b/suites/stress/thrash/thrashers/more-down.yaml
new file mode 100644
index 000000000..ca1afc2e7
--- /dev/null
+++ b/suites/stress/thrash/thrashers/more-down.yaml
@@ -0,0 +1,9 @@
+tasks:
+- install:
+- ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+- thrashosds:
+ thrash_primary_affinity: false
+ chance_down: 50
diff --git a/suites/stress/thrash/workloads/bonnie_cfuse.yaml b/suites/stress/thrash/workloads/bonnie_cfuse.yaml
new file mode 100644
index 000000000..912f12d6c
--- /dev/null
+++ b/suites/stress/thrash/workloads/bonnie_cfuse.yaml
@@ -0,0 +1,6 @@
+tasks:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/bonnie.sh
diff --git a/suites/stress/thrash/workloads/iozone_cfuse.yaml b/suites/stress/thrash/workloads/iozone_cfuse.yaml
new file mode 100644
index 000000000..18a6051be
--- /dev/null
+++ b/suites/stress/thrash/workloads/iozone_cfuse.yaml
@@ -0,0 +1,6 @@
+tasks:
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/iozone.sh
diff --git a/suites/stress/thrash/workloads/radosbench.yaml b/suites/stress/thrash/workloads/radosbench.yaml
new file mode 100644
index 000000000..3940870fc
--- /dev/null
+++ b/suites/stress/thrash/workloads/radosbench.yaml
@@ -0,0 +1,4 @@
+tasks:
+- radosbench:
+ clients: [client.0]
+ time: 1800
diff --git a/suites/stress/thrash/workloads/readwrite.yaml b/suites/stress/thrash/workloads/readwrite.yaml
new file mode 100644
index 000000000..c53e52b08
--- /dev/null
+++ b/suites/stress/thrash/workloads/readwrite.yaml
@@ -0,0 +1,9 @@
+tasks:
+- rados:
+ clients: [client.0]
+ ops: 4000
+ objects: 500
+ op_weights:
+ read: 45
+ write: 45
+ delete: 10
diff --git a/suites/upgrade-cuttlefish/fs/% b/suites/upgrade-cuttlefish/fs/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade-cuttlefish/fs/0-cluster/start.yaml b/suites/upgrade-cuttlefish/fs/0-cluster/start.yaml
new file mode 100644
index 000000000..c1acc4e8a
--- /dev/null
+++ b/suites/upgrade-cuttlefish/fs/0-cluster/start.yaml
@@ -0,0 +1,17 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - scrub
+ fs: xfs
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+- - mon.b
+ - mon.c
+ - osd.3
+ - osd.4
+ - osd.5
+ - client.0
diff --git a/suites/upgrade-cuttlefish/fs/1-cuttlefish-install/bobtail.v0.61.5.yaml b/suites/upgrade-cuttlefish/fs/1-cuttlefish-install/bobtail.v0.61.5.yaml
new file mode 100644
index 000000000..286cdd666
--- /dev/null
+++ b/suites/upgrade-cuttlefish/fs/1-cuttlefish-install/bobtail.v0.61.5.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+ branch: bobtail
+- ceph:
+- install.upgrade:
+ all:
+ tag: v0.61.5
+- ceph.restart:
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade-cuttlefish/fs/1-cuttlefish-install/v0.61.5.yaml b/suites/upgrade-cuttlefish/fs/1-cuttlefish-install/v0.61.5.yaml
new file mode 100644
index 000000000..07d04317e
--- /dev/null
+++ b/suites/upgrade-cuttlefish/fs/1-cuttlefish-install/v0.61.5.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+ tag: v0.61.5
+- ceph:
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade-cuttlefish/fs/1-cuttlefish-install/v0.61.6.yaml b/suites/upgrade-cuttlefish/fs/1-cuttlefish-install/v0.61.6.yaml
new file mode 100644
index 000000000..9d74ab38f
--- /dev/null
+++ b/suites/upgrade-cuttlefish/fs/1-cuttlefish-install/v0.61.6.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+ tag: v0.61.6
+- ceph:
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade-cuttlefish/fs/2-workload/blogbench.yaml b/suites/upgrade-cuttlefish/fs/2-workload/blogbench.yaml
new file mode 100644
index 000000000..0cd59eaaf
--- /dev/null
+++ b/suites/upgrade-cuttlefish/fs/2-workload/blogbench.yaml
@@ -0,0 +1,5 @@
+workload:
+ workunit:
+ clients:
+ all:
+ - suites/blogbench.sh
diff --git a/suites/upgrade-cuttlefish/fs/3-upgrade-sequence/upgrade-mds-mon-osd.yaml b/suites/upgrade-cuttlefish/fs/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
new file mode 100644
index 000000000..c97aef77e
--- /dev/null
+++ b/suites/upgrade-cuttlefish/fs/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: cuttlefish
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
diff --git a/suites/upgrade-cuttlefish/fs/3-upgrade-sequence/upgrade-mon-osd-mds.yaml b/suites/upgrade-cuttlefish/fs/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
new file mode 100644
index 000000000..9d06ef37d
--- /dev/null
+++ b/suites/upgrade-cuttlefish/fs/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: cuttlefish
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
diff --git a/suites/upgrade-cuttlefish/fs/3-upgrade-sequence/upgrade-osd-mon-mds.yaml b/suites/upgrade-cuttlefish/fs/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
new file mode 100644
index 000000000..dd76b10b5
--- /dev/null
+++ b/suites/upgrade-cuttlefish/fs/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: cuttlefish
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
diff --git a/suites/upgrade-cuttlefish/fs/4-final/monthrash.yaml b/suites/upgrade-cuttlefish/fs/4-final/monthrash.yaml
new file mode 100644
index 000000000..13af446eb
--- /dev/null
+++ b/suites/upgrade-cuttlefish/fs/4-final/monthrash.yaml
@@ -0,0 +1,10 @@
+tasks:
+- mon_thrash:
+ revive_delay: 20
+ thrash_delay: 1
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - suites/dbench.sh
+
diff --git a/suites/upgrade-cuttlefish/fs/4-final/osdthrash.yaml b/suites/upgrade-cuttlefish/fs/4-final/osdthrash.yaml
new file mode 100644
index 000000000..9c5484254
--- /dev/null
+++ b/suites/upgrade-cuttlefish/fs/4-final/osdthrash.yaml
@@ -0,0 +1,17 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+tasks:
+- thrashosds:
+ thrash_primary_affinity: false
+ timeout: 1200
+ chance_pgnum_grow: 1
+ chance_pgpnum_fix: 1
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/iogen.sh
+
diff --git a/suites/upgrade-cuttlefish/rados-older/% b/suites/upgrade-cuttlefish/rados-older/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade-cuttlefish/rados-older/0-cluster/start.yaml b/suites/upgrade-cuttlefish/rados-older/0-cluster/start.yaml
new file mode 100644
index 000000000..8626abc26
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados-older/0-cluster/start.yaml
@@ -0,0 +1,20 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - scrub
+ conf:
+ paxos service trim min: 5
+ mon min osdmap epochs: 25
+ fs: xfs
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+- - mon.b
+ - mon.c
+ - osd.3
+ - osd.4
+ - osd.5
+ - client.0
diff --git a/suites/upgrade-cuttlefish/rados-older/1-install/bobtail.yaml b/suites/upgrade-cuttlefish/rados-older/1-install/bobtail.yaml
new file mode 100644
index 000000000..21dc2bb2b
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados-older/1-install/bobtail.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install:
+ branch: bobtail
+- ceph:
diff --git a/suites/upgrade-cuttlefish/rados-older/1-install/v0.61.1.yaml b/suites/upgrade-cuttlefish/rados-older/1-install/v0.61.1.yaml
new file mode 100644
index 000000000..c77ab27ba
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados-older/1-install/v0.61.1.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install:
+ tag: v0.61.1
+- ceph:
diff --git a/suites/upgrade-cuttlefish/rados-older/2-upgrade/v0.61.3.yaml b/suites/upgrade-cuttlefish/rados-older/2-upgrade/v0.61.3.yaml
new file mode 100644
index 000000000..aca276b8d
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados-older/2-upgrade/v0.61.3.yaml
@@ -0,0 +1,5 @@
+tasks:
+- install.upgrade:
+ all:
+ tag: v0.61.3
+- ceph.restart:
diff --git a/suites/upgrade-cuttlefish/rados-older/2-upgrade/v0.61.4.yaml b/suites/upgrade-cuttlefish/rados-older/2-upgrade/v0.61.4.yaml
new file mode 100644
index 000000000..c44994e5e
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados-older/2-upgrade/v0.61.4.yaml
@@ -0,0 +1,5 @@
+tasks:
+- install.upgrade:
+ all:
+ tag: v0.61.4
+- ceph.restart:
diff --git a/suites/upgrade-cuttlefish/rados-older/2-upgrade/v0.61.5.yaml b/suites/upgrade-cuttlefish/rados-older/2-upgrade/v0.61.5.yaml
new file mode 100644
index 000000000..d46a1a152
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados-older/2-upgrade/v0.61.5.yaml
@@ -0,0 +1,5 @@
+tasks:
+- install.upgrade:
+ all:
+ tag: v0.61.5
+- ceph.restart:
diff --git a/suites/upgrade-cuttlefish/rados-older/3-rolling-upgrade/all.yaml b/suites/upgrade-cuttlefish/rados-older/3-rolling-upgrade/all.yaml
new file mode 100644
index 000000000..fe892358d
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados-older/3-rolling-upgrade/all.yaml
@@ -0,0 +1,4 @@
+tasks:
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade-cuttlefish/rados-older/4-upgrade-sequence/upgrade-mds-mon-osd.yaml b/suites/upgrade-cuttlefish/rados-older/4-upgrade-sequence/upgrade-mds-mon-osd.yaml
new file mode 100644
index 000000000..e70e5d0cf
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados-older/4-upgrade-sequence/upgrade-mds-mon-osd.yaml
@@ -0,0 +1,39 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: cuttlefish
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart:
+ daemons: [mon.a]
+ wait-for-healthy: false
+ wait-for-osds-up: true
+ - sleep:
+ duration: 60
+ - ceph.restart:
+ daemons: [mon.b]
+ wait-for-healthy: false
+ wait-for-osds-up: true
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
diff --git a/suites/upgrade-cuttlefish/rados-older/4-upgrade-sequence/upgrade-mon-osd-mds.yaml b/suites/upgrade-cuttlefish/rados-older/4-upgrade-sequence/upgrade-mon-osd-mds.yaml
new file mode 100644
index 000000000..ed25b7015
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados-older/4-upgrade-sequence/upgrade-mon-osd-mds.yaml
@@ -0,0 +1,39 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: cuttlefish
+ - ceph.restart:
+ daemons: [mon.a]
+ wait-for-healthy: false
+ wait-for-osds-up: true
+ - sleep:
+ duration: 60
+ - ceph.restart:
+ daemons: [mon.b]
+ wait-for-healthy: false
+ wait-for-osds-up: true
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
diff --git a/suites/upgrade-cuttlefish/rados-older/4-upgrade-sequence/upgrade-osd-mon-mds.yaml b/suites/upgrade-cuttlefish/rados-older/4-upgrade-sequence/upgrade-osd-mon-mds.yaml
new file mode 100644
index 000000000..33368cd8d
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados-older/4-upgrade-sequence/upgrade-osd-mon-mds.yaml
@@ -0,0 +1,41 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: cuttlefish
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
+ - sleep:
+ duration: 60
+ - ceph.restart:
+ daemons: [mon.a]
+ wait-for-healthy: false
+ wait-for-osds-up: true
+ - sleep:
+ duration: 60
+ - ceph.restart:
+ daemons: [mon.b]
+ wait-for-healthy: false
+ wait-for-osds-up: true
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
diff --git a/suites/upgrade-cuttlefish/rados-older/5-workload/testrados.yaml b/suites/upgrade-cuttlefish/rados-older/5-workload/testrados.yaml
new file mode 100644
index 000000000..8eaab19fd
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados-older/5-workload/testrados.yaml
@@ -0,0 +1,13 @@
+workload:
+ rados:
+ clients: [client.0]
+ ops: 2000
+ objects: 50
+ op_weights:
+ read: 100
+ write: 100
+ delete: 50
+ snap_create: 50
+ snap_remove: 50
+ rollback: 50
+
diff --git a/suites/upgrade-cuttlefish/rados-older/6-final/monthrash.yaml b/suites/upgrade-cuttlefish/rados-older/6-final/monthrash.yaml
new file mode 100644
index 000000000..810ba1b30
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados-older/6-final/monthrash.yaml
@@ -0,0 +1,9 @@
+tasks:
+- mon_thrash:
+ revive_delay: 20
+ thrash_delay: 1
+- workunit:
+ clients:
+ client.0:
+ - rados/test.sh
+
diff --git a/suites/upgrade-cuttlefish/rados-older/6-final/osdthrash.yaml b/suites/upgrade-cuttlefish/rados-older/6-final/osdthrash.yaml
new file mode 100644
index 000000000..32c3b5a1b
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados-older/6-final/osdthrash.yaml
@@ -0,0 +1,23 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+tasks:
+- thrashosds:
+ thrash_primary_affinity: false
+ timeout: 1200
+ chance_pgnum_grow: 1
+ chance_pgpnum_fix: 1
+- rados:
+ clients: [client.0]
+ ops: 2000
+ objects: 50
+ op_weights:
+ read: 100
+ write: 100
+ delete: 50
+ snap_create: 50
+ snap_remove: 50
+ rollback: 50
+
diff --git a/suites/upgrade-cuttlefish/rados/% b/suites/upgrade-cuttlefish/rados/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade-cuttlefish/rados/0-cluster/start.yaml b/suites/upgrade-cuttlefish/rados/0-cluster/start.yaml
new file mode 100644
index 000000000..c1acc4e8a
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados/0-cluster/start.yaml
@@ -0,0 +1,17 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - scrub
+ fs: xfs
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+- - mon.b
+ - mon.c
+ - osd.3
+ - osd.4
+ - osd.5
+ - client.0
diff --git a/suites/upgrade-cuttlefish/rados/1-cuttlefish-install/bobtail.v0.61.5.yaml b/suites/upgrade-cuttlefish/rados/1-cuttlefish-install/bobtail.v0.61.5.yaml
new file mode 100644
index 000000000..286cdd666
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados/1-cuttlefish-install/bobtail.v0.61.5.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+ branch: bobtail
+- ceph:
+- install.upgrade:
+ all:
+ tag: v0.61.5
+- ceph.restart:
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade-cuttlefish/rados/1-cuttlefish-install/v0.61.5.yaml b/suites/upgrade-cuttlefish/rados/1-cuttlefish-install/v0.61.5.yaml
new file mode 100644
index 000000000..07d04317e
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados/1-cuttlefish-install/v0.61.5.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+ tag: v0.61.5
+- ceph:
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade-cuttlefish/rados/1-cuttlefish-install/v0.61.6.yaml b/suites/upgrade-cuttlefish/rados/1-cuttlefish-install/v0.61.6.yaml
new file mode 100644
index 000000000..9d74ab38f
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados/1-cuttlefish-install/v0.61.6.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+ tag: v0.61.6
+- ceph:
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade-cuttlefish/rados/2-workload/testrados.yaml b/suites/upgrade-cuttlefish/rados/2-workload/testrados.yaml
new file mode 100644
index 000000000..8eaab19fd
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados/2-workload/testrados.yaml
@@ -0,0 +1,13 @@
+workload:
+ rados:
+ clients: [client.0]
+ ops: 2000
+ objects: 50
+ op_weights:
+ read: 100
+ write: 100
+ delete: 50
+ snap_create: 50
+ snap_remove: 50
+ rollback: 50
+
diff --git a/suites/upgrade-cuttlefish/rados/3-upgrade-sequence/upgrade-mds-mon-osd.yaml b/suites/upgrade-cuttlefish/rados/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
new file mode 100644
index 000000000..c97aef77e
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: cuttlefish
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
diff --git a/suites/upgrade-cuttlefish/rados/3-upgrade-sequence/upgrade-mon-osd-mds.yaml b/suites/upgrade-cuttlefish/rados/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
new file mode 100644
index 000000000..9d06ef37d
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: cuttlefish
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
diff --git a/suites/upgrade-cuttlefish/rados/3-upgrade-sequence/upgrade-osd-mon-mds.yaml b/suites/upgrade-cuttlefish/rados/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
new file mode 100644
index 000000000..c061399ad
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
@@ -0,0 +1,35 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: cuttlefish
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
diff --git a/suites/upgrade-cuttlefish/rados/4-final/monthrash.yaml b/suites/upgrade-cuttlefish/rados/4-final/monthrash.yaml
new file mode 100644
index 000000000..810ba1b30
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados/4-final/monthrash.yaml
@@ -0,0 +1,9 @@
+tasks:
+- mon_thrash:
+ revive_delay: 20
+ thrash_delay: 1
+- workunit:
+ clients:
+ client.0:
+ - rados/test.sh
+
diff --git a/suites/upgrade-cuttlefish/rados/4-final/osdthrash.yaml b/suites/upgrade-cuttlefish/rados/4-final/osdthrash.yaml
new file mode 100644
index 000000000..32c3b5a1b
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rados/4-final/osdthrash.yaml
@@ -0,0 +1,23 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+tasks:
+- thrashosds:
+ thrash_primary_affinity: false
+ timeout: 1200
+ chance_pgnum_grow: 1
+ chance_pgpnum_fix: 1
+- rados:
+ clients: [client.0]
+ ops: 2000
+ objects: 50
+ op_weights:
+ read: 100
+ write: 100
+ delete: 50
+ snap_create: 50
+ snap_remove: 50
+ rollback: 50
+
diff --git a/suites/upgrade-cuttlefish/rbd/% b/suites/upgrade-cuttlefish/rbd/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade-cuttlefish/rbd/0-cluster/start.yaml b/suites/upgrade-cuttlefish/rbd/0-cluster/start.yaml
new file mode 100644
index 000000000..c1acc4e8a
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rbd/0-cluster/start.yaml
@@ -0,0 +1,17 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - scrub
+ fs: xfs
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+- - mon.b
+ - mon.c
+ - osd.3
+ - osd.4
+ - osd.5
+ - client.0
diff --git a/suites/upgrade-cuttlefish/rbd/1-cuttlefish-install/bobtail.v0.61.5.yaml b/suites/upgrade-cuttlefish/rbd/1-cuttlefish-install/bobtail.v0.61.5.yaml
new file mode 100644
index 000000000..286cdd666
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rbd/1-cuttlefish-install/bobtail.v0.61.5.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+ branch: bobtail
+- ceph:
+- install.upgrade:
+ all:
+ tag: v0.61.5
+- ceph.restart:
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade-cuttlefish/rbd/1-cuttlefish-install/v0.61.5.yaml b/suites/upgrade-cuttlefish/rbd/1-cuttlefish-install/v0.61.5.yaml
new file mode 100644
index 000000000..07d04317e
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rbd/1-cuttlefish-install/v0.61.5.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+ tag: v0.61.5
+- ceph:
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade-cuttlefish/rbd/1-cuttlefish-install/v0.61.6.yaml b/suites/upgrade-cuttlefish/rbd/1-cuttlefish-install/v0.61.6.yaml
new file mode 100644
index 000000000..9d74ab38f
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rbd/1-cuttlefish-install/v0.61.6.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+ tag: v0.61.6
+- ceph:
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade-cuttlefish/rbd/2-workload/rbd.yaml b/suites/upgrade-cuttlefish/rbd/2-workload/rbd.yaml
new file mode 100644
index 000000000..ce2fabe03
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rbd/2-workload/rbd.yaml
@@ -0,0 +1,14 @@
+workload:
+ sequential:
+ - workunit:
+ clients:
+ client.0:
+ - rbd/import_export.sh
+ env:
+ RBD_CREATE_ARGS: --new-format
+ - workunit:
+ clients:
+ client.0:
+ - cls/test_cls_rbd.sh
+
+
diff --git a/suites/upgrade-cuttlefish/rbd/3-upgrade-sequence/upgrade-mds-mon-osd.yaml b/suites/upgrade-cuttlefish/rbd/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
new file mode 100644
index 000000000..c97aef77e
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rbd/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: cuttlefish
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
diff --git a/suites/upgrade-cuttlefish/rbd/3-upgrade-sequence/upgrade-mon-osd-mds.yaml b/suites/upgrade-cuttlefish/rbd/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
new file mode 100644
index 000000000..9d06ef37d
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rbd/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: cuttlefish
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
diff --git a/suites/upgrade-cuttlefish/rbd/3-upgrade-sequence/upgrade-osd-mon-mds.yaml b/suites/upgrade-cuttlefish/rbd/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
new file mode 100644
index 000000000..dd76b10b5
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rbd/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: cuttlefish
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
diff --git a/suites/upgrade-cuttlefish/rbd/4-final/monthrash.yaml b/suites/upgrade-cuttlefish/rbd/4-final/monthrash.yaml
new file mode 100644
index 000000000..593191c24
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rbd/4-final/monthrash.yaml
@@ -0,0 +1,11 @@
+tasks:
+- mon_thrash:
+ revive_delay: 20
+ thrash_delay: 1
+- workunit:
+ clients:
+ client.0:
+ - rbd/copy.sh
+ env:
+ RBD_CREATE_ARGS: --new-format
+
diff --git a/suites/upgrade-cuttlefish/rbd/4-final/osdthrash.yaml b/suites/upgrade-cuttlefish/rbd/4-final/osdthrash.yaml
new file mode 100644
index 000000000..636351548
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rbd/4-final/osdthrash.yaml
@@ -0,0 +1,16 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+tasks:
+- thrashosds:
+ thrash_primary_affinity: false
+ timeout: 1200
+ chance_pgnum_grow: 1
+ chance_pgpnum_fix: 1
+- workunit:
+ clients:
+ client.0:
+ - rbd/test_lock_fence.sh
+
diff --git a/suites/upgrade-cuttlefish/rgw/% b/suites/upgrade-cuttlefish/rgw/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade-cuttlefish/rgw/0-cluster/start.yaml b/suites/upgrade-cuttlefish/rgw/0-cluster/start.yaml
new file mode 100644
index 000000000..c1acc4e8a
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rgw/0-cluster/start.yaml
@@ -0,0 +1,17 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - scrub
+ fs: xfs
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+- - mon.b
+ - mon.c
+ - osd.3
+ - osd.4
+ - osd.5
+ - client.0
diff --git a/suites/upgrade-cuttlefish/rgw/1-cuttlefish-install/bobtail.v0.61.5.yaml b/suites/upgrade-cuttlefish/rgw/1-cuttlefish-install/bobtail.v0.61.5.yaml
new file mode 100644
index 000000000..286cdd666
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rgw/1-cuttlefish-install/bobtail.v0.61.5.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+ branch: bobtail
+- ceph:
+- install.upgrade:
+ all:
+ tag: v0.61.5
+- ceph.restart:
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade-cuttlefish/rgw/1-cuttlefish-install/v0.61.5.yaml b/suites/upgrade-cuttlefish/rgw/1-cuttlefish-install/v0.61.5.yaml
new file mode 100644
index 000000000..07d04317e
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rgw/1-cuttlefish-install/v0.61.5.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+ tag: v0.61.5
+- ceph:
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade-cuttlefish/rgw/1-cuttlefish-install/v0.61.6.yaml b/suites/upgrade-cuttlefish/rgw/1-cuttlefish-install/v0.61.6.yaml
new file mode 100644
index 000000000..9d74ab38f
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rgw/1-cuttlefish-install/v0.61.6.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+ tag: v0.61.6
+- ceph:
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade-cuttlefish/rgw/2-workload/testrgw.yaml b/suites/upgrade-cuttlefish/rgw/2-workload/testrgw.yaml
new file mode 100644
index 000000000..f1b2f3e88
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rgw/2-workload/testrgw.yaml
@@ -0,0 +1,6 @@
+workload:
+ rgw: [client.0]
+ s3tests:
+ client.0:
+ rgw_server: client.0
+
diff --git a/suites/upgrade-cuttlefish/rgw/3-upgrade-sequence/upgrade-mds-mon-osd.yaml b/suites/upgrade-cuttlefish/rgw/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
new file mode 100644
index 000000000..0de4f185f
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rgw/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
@@ -0,0 +1,36 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: cuttlefish
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
+ - sleep:
+ duration: 30
+ - ceph.restart: [rgw.client.0]
diff --git a/suites/upgrade-cuttlefish/rgw/3-upgrade-sequence/upgrade-mon-osd-mds.yaml b/suites/upgrade-cuttlefish/rgw/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
new file mode 100644
index 000000000..c7fa40f1f
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rgw/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
@@ -0,0 +1,36 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: cuttlefish
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
+ - sleep:
+ duration: 30
+ - ceph.restart: [rgw.client.0]
diff --git a/suites/upgrade-cuttlefish/rgw/3-upgrade-sequence/upgrade-osd-mon-mds.yaml b/suites/upgrade-cuttlefish/rgw/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
new file mode 100644
index 000000000..0d0639ed7
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rgw/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
@@ -0,0 +1,36 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: cuttlefish
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [rgw.client.0]
diff --git a/suites/upgrade-cuttlefish/rgw/4-final/monthrash.yaml b/suites/upgrade-cuttlefish/rgw/4-final/monthrash.yaml
new file mode 100644
index 000000000..9361edc80
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rgw/4-final/monthrash.yaml
@@ -0,0 +1,8 @@
+tasks:
+- mon_thrash:
+ revive_delay: 20
+ thrash_delay: 1
+- swift:
+ client.0:
+ rgw_server: client.0
+
diff --git a/suites/upgrade-cuttlefish/rgw/4-final/osdthrash.yaml b/suites/upgrade-cuttlefish/rgw/4-final/osdthrash.yaml
new file mode 100644
index 000000000..4f84cdba7
--- /dev/null
+++ b/suites/upgrade-cuttlefish/rgw/4-final/osdthrash.yaml
@@ -0,0 +1,15 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+tasks:
+- thrashosds:
+ thrash_primary_affinity: false
+ timeout: 1200
+ chance_pgnum_grow: 1
+ chance_pgpnum_fix: 1
+- swift:
+ client.0:
+ rgw_server: client.0
+
diff --git a/suites/upgrade-fs/fs/% b/suites/upgrade-fs/fs/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade-fs/fs/0-cluster/start.yaml b/suites/upgrade-fs/fs/0-cluster/start.yaml
new file mode 100644
index 000000000..01747e420
--- /dev/null
+++ b/suites/upgrade-fs/fs/0-cluster/start.yaml
@@ -0,0 +1,10 @@
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+- - mon.b
+ - mon.c
+ - osd.2
+ - osd.3
+- - client.0
diff --git a/suites/upgrade-fs/fs/1-cuttlefish-install/cuttlefish.yaml b/suites/upgrade-fs/fs/1-cuttlefish-install/cuttlefish.yaml
new file mode 100644
index 000000000..e427343d8
--- /dev/null
+++ b/suites/upgrade-fs/fs/1-cuttlefish-install/cuttlefish.yaml
@@ -0,0 +1,6 @@
+tasks:
+- install:
+ branch: cuttlefish
+- ceph:
+ fs: xfs
+- ceph-fuse:
diff --git a/suites/upgrade-fs/fs/2-cuttlefish-workload/blogbench.yaml b/suites/upgrade-fs/fs/2-cuttlefish-workload/blogbench.yaml
new file mode 100644
index 000000000..50161b081
--- /dev/null
+++ b/suites/upgrade-fs/fs/2-cuttlefish-workload/blogbench.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: cuttlefish
+ clients:
+ client.0:
+ - suites/blogbench.sh
diff --git a/suites/upgrade-fs/fs/2-cuttlefish-workload/dbench.yaml b/suites/upgrade-fs/fs/2-cuttlefish-workload/dbench.yaml
new file mode 100644
index 000000000..3bb9040e2
--- /dev/null
+++ b/suites/upgrade-fs/fs/2-cuttlefish-workload/dbench.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: cuttlefish
+ clients:
+ all:
+ - suites/dbench.sh
diff --git a/suites/upgrade-fs/fs/2-cuttlefish-workload/iogen.yaml b/suites/upgrade-fs/fs/2-cuttlefish-workload/iogen.yaml
new file mode 100644
index 000000000..c832d2f5b
--- /dev/null
+++ b/suites/upgrade-fs/fs/2-cuttlefish-workload/iogen.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: cuttlefish
+ clients:
+ client.0:
+ - suites/iogen.sh
diff --git a/suites/upgrade-fs/fs/3-upgrade/next.yaml b/suites/upgrade-fs/fs/3-upgrade/next.yaml
new file mode 100644
index 000000000..3e8e04cad
--- /dev/null
+++ b/suites/upgrade-fs/fs/3-upgrade/next.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install.upgrade:
+ all:
+ branch: next
diff --git a/suites/upgrade-fs/fs/4-restart/mds-mon-osd.yaml b/suites/upgrade-fs/fs/4-restart/mds-mon-osd.yaml
new file mode 100644
index 000000000..d21800684
--- /dev/null
+++ b/suites/upgrade-fs/fs/4-restart/mds-mon-osd.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [mds.a, mon.a, mon.b, mon.c, osd.0, osd.1, osd.2, osd.3]
diff --git a/suites/upgrade-fs/fs/4-restart/mon-mds-osd.yaml b/suites/upgrade-fs/fs/4-restart/mon-mds-osd.yaml
new file mode 100644
index 000000000..78e14e947
--- /dev/null
+++ b/suites/upgrade-fs/fs/4-restart/mon-mds-osd.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1, osd.2, osd.3]
diff --git a/suites/upgrade-fs/fs/4-restart/osd-mds-mon.yaml b/suites/upgrade-fs/fs/4-restart/osd-mds-mon.yaml
new file mode 100644
index 000000000..dbcd013b3
--- /dev/null
+++ b/suites/upgrade-fs/fs/4-restart/osd-mds-mon.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [osd.0, osd.1, osd.2, osd.3, mds.a, mon.a, mon.b, mon.c]
diff --git a/suites/upgrade-fs/fs/5-next-workload/fsstress.yaml b/suites/upgrade-fs/fs/5-next-workload/fsstress.yaml
new file mode 100644
index 000000000..101b1ca5b
--- /dev/null
+++ b/suites/upgrade-fs/fs/5-next-workload/fsstress.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: next
+ clients:
+ client.0:
+ - suites/fsstress.sh
diff --git a/suites/upgrade-fs/fs/5-next-workload/iogen.yaml b/suites/upgrade-fs/fs/5-next-workload/iogen.yaml
new file mode 100644
index 000000000..247d8072d
--- /dev/null
+++ b/suites/upgrade-fs/fs/5-next-workload/iogen.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: next
+ clients:
+ all:
+ - suites/iogen.sh
diff --git a/suites/upgrade-fs/fs/5-next-workload/kernel-untar-build.yaml b/suites/upgrade-fs/fs/5-next-workload/kernel-untar-build.yaml
new file mode 100644
index 000000000..7415dd9b4
--- /dev/null
+++ b/suites/upgrade-fs/fs/5-next-workload/kernel-untar-build.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: next
+ clients:
+ all:
+ - kernel_untar_build.sh
diff --git a/suites/upgrade-fs/fs/5-next-workload/tiobench.yaml b/suites/upgrade-fs/fs/5-next-workload/tiobench.yaml
new file mode 100644
index 000000000..20e99edb1
--- /dev/null
+++ b/suites/upgrade-fs/fs/5-next-workload/tiobench.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: next
+ clients:
+ all:
+ - suites/tiobench.sh
diff --git a/suites/upgrade-parallel/fs/% b/suites/upgrade-parallel/fs/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade-parallel/fs/0-cluster/start.yaml b/suites/upgrade-parallel/fs/0-cluster/start.yaml
new file mode 100644
index 000000000..01747e420
--- /dev/null
+++ b/suites/upgrade-parallel/fs/0-cluster/start.yaml
@@ -0,0 +1,10 @@
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+- - mon.b
+ - mon.c
+ - osd.2
+ - osd.3
+- - client.0
diff --git a/suites/upgrade-parallel/fs/1-cuttlefish-install/cuttlefish.yaml b/suites/upgrade-parallel/fs/1-cuttlefish-install/cuttlefish.yaml
new file mode 100644
index 000000000..a2fa7e4a8
--- /dev/null
+++ b/suites/upgrade-parallel/fs/1-cuttlefish-install/cuttlefish.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+ branch: cuttlefish
+- ceph:
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade-parallel/fs/2-workload/blogbench.yaml b/suites/upgrade-parallel/fs/2-workload/blogbench.yaml
new file mode 100644
index 000000000..0cd59eaaf
--- /dev/null
+++ b/suites/upgrade-parallel/fs/2-workload/blogbench.yaml
@@ -0,0 +1,5 @@
+workload:
+ workunit:
+ clients:
+ all:
+ - suites/blogbench.sh
diff --git a/suites/upgrade-parallel/fs/3-upgrade-sequence/upgrade-all.yaml b/suites/upgrade-parallel/fs/3-upgrade-sequence/upgrade-all.yaml
new file mode 100644
index 000000000..079638bce
--- /dev/null
+++ b/suites/upgrade-parallel/fs/3-upgrade-sequence/upgrade-all.yaml
@@ -0,0 +1,6 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: next
+ - ceph.restart: [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1, osd.2, osd.3]
diff --git a/suites/upgrade-parallel/fs/distro b/suites/upgrade-parallel/fs/distro
new file mode 120000
index 000000000..3a0ac71c8
--- /dev/null
+++ b/suites/upgrade-parallel/fs/distro
@@ -0,0 +1 @@
+../rados/distro
\ No newline at end of file
diff --git a/suites/upgrade-parallel/rados/% b/suites/upgrade-parallel/rados/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade-parallel/rados/0-cluster/start.yaml b/suites/upgrade-parallel/rados/0-cluster/start.yaml
new file mode 100644
index 000000000..01747e420
--- /dev/null
+++ b/suites/upgrade-parallel/rados/0-cluster/start.yaml
@@ -0,0 +1,10 @@
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+- - mon.b
+ - mon.c
+ - osd.2
+ - osd.3
+- - client.0
diff --git a/suites/upgrade-parallel/rados/1-cuttlefish-install/cuttlefish.yaml b/suites/upgrade-parallel/rados/1-cuttlefish-install/cuttlefish.yaml
new file mode 100644
index 000000000..a2fa7e4a8
--- /dev/null
+++ b/suites/upgrade-parallel/rados/1-cuttlefish-install/cuttlefish.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+ branch: cuttlefish
+- ceph:
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade-parallel/rados/2-workload/loadgenbig.yaml b/suites/upgrade-parallel/rados/2-workload/loadgenbig.yaml
new file mode 100644
index 000000000..85e57fcf1
--- /dev/null
+++ b/suites/upgrade-parallel/rados/2-workload/loadgenbig.yaml
@@ -0,0 +1,6 @@
+workload:
+ workunit:
+ branch: cuttlefish
+ clients:
+ all:
+ - rados/load-gen-big.sh
diff --git a/suites/upgrade-parallel/rados/2-workload/loadgenmix.yaml b/suites/upgrade-parallel/rados/2-workload/loadgenmix.yaml
new file mode 100644
index 000000000..c712576ff
--- /dev/null
+++ b/suites/upgrade-parallel/rados/2-workload/loadgenmix.yaml
@@ -0,0 +1,6 @@
+workload:
+ workunit:
+ branch: cuttlefish
+ clients:
+ client.0:
+ - rados/load-gen-mix.sh
diff --git a/suites/upgrade-parallel/rados/3-upgrade-sequence/upgrade-all.yaml b/suites/upgrade-parallel/rados/3-upgrade-sequence/upgrade-all.yaml
new file mode 100644
index 000000000..079638bce
--- /dev/null
+++ b/suites/upgrade-parallel/rados/3-upgrade-sequence/upgrade-all.yaml
@@ -0,0 +1,6 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: next
+ - ceph.restart: [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1, osd.2, osd.3]
diff --git a/suites/upgrade-parallel/rados/3-upgrade-sequence/upgrade-mds-mon-osd.yaml b/suites/upgrade-parallel/rados/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
new file mode 100644
index 000000000..e8dea7928
--- /dev/null
+++ b/suites/upgrade-parallel/rados/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: next
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart:
+ daemons: [mon.a]
+ wait-for-healthy: false
+ wait-for-osds-up: true
+ - sleep:
+ duration: 60
+ - ceph.restart:
+ daemons: [mon.b]
+ wait-for-healthy: false
+ wait-for-osds-up: true
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.3]
diff --git a/suites/upgrade-parallel/rados/3-upgrade-sequence/upgrade-mon-osd-mds.yaml b/suites/upgrade-parallel/rados/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
new file mode 100644
index 000000000..f9688c837
--- /dev/null
+++ b/suites/upgrade-parallel/rados/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: next
+ - ceph.restart:
+ daemons: [mon.a]
+ wait-for-healthy: false
+ wait-for-osds-up: true
+ - sleep:
+ duration: 60
+ - ceph.restart:
+ daemons: [mon.b]
+ wait-for-healthy: false
+ wait-for-osds-up: true
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.3]
diff --git a/suites/upgrade-parallel/rados/3-upgrade-sequence/upgrade-osd-mon-mds.yaml b/suites/upgrade-parallel/rados/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
new file mode 100644
index 000000000..91e607bf8
--- /dev/null
+++ b/suites/upgrade-parallel/rados/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
@@ -0,0 +1,35 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: next
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 60
+ - ceph.restart:
+ daemons: [mon.a]
+ wait-for-healthy: false
+ wait-for-osds-up: true
+ - sleep:
+ duration: 60
+ - ceph.restart:
+ daemons: [mon.b]
+ wait-for-healthy: false
+ wait-for-osds-up: true
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
diff --git a/suites/upgrade-parallel/rados/distro/centos_6.4.yaml b/suites/upgrade-parallel/rados/distro/centos_6.4.yaml
new file mode 100644
index 000000000..02383cd5f
--- /dev/null
+++ b/suites/upgrade-parallel/rados/distro/centos_6.4.yaml
@@ -0,0 +1,2 @@
+os_type: centos
+os_version: "6.4"
diff --git a/suites/upgrade-parallel/rados/distro/debian_7.0.yaml b/suites/upgrade-parallel/rados/distro/debian_7.0.yaml
new file mode 100644
index 000000000..8100dc41e
--- /dev/null
+++ b/suites/upgrade-parallel/rados/distro/debian_7.0.yaml
@@ -0,0 +1,2 @@
+os_type: debian
+os_version: "7.0"
diff --git a/suites/upgrade-parallel/rados/distro/fedora_18.yaml b/suites/upgrade-parallel/rados/distro/fedora_18.yaml
new file mode 100644
index 000000000..07872aa7e
--- /dev/null
+++ b/suites/upgrade-parallel/rados/distro/fedora_18.yaml
@@ -0,0 +1,2 @@
+os_type: fedora
+os_version: "18"
diff --git a/suites/upgrade-parallel/rados/distro/rhel_6.3.yaml b/suites/upgrade-parallel/rados/distro/rhel_6.3.yaml
new file mode 100644
index 000000000..6a8edcd56
--- /dev/null
+++ b/suites/upgrade-parallel/rados/distro/rhel_6.3.yaml
@@ -0,0 +1,2 @@
+os_type: rhel
+os_version: "6.3"
diff --git a/suites/upgrade-parallel/rados/distro/ubuntu_12.04.yaml b/suites/upgrade-parallel/rados/distro/ubuntu_12.04.yaml
new file mode 100644
index 000000000..dbc3a8d9c
--- /dev/null
+++ b/suites/upgrade-parallel/rados/distro/ubuntu_12.04.yaml
@@ -0,0 +1,2 @@
+os_type: ubuntu
+os_version: "12.04"
diff --git a/suites/upgrade-parallel/rgw/% b/suites/upgrade-parallel/rgw/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade-parallel/rgw/0-cluster/start.yaml b/suites/upgrade-parallel/rgw/0-cluster/start.yaml
new file mode 100644
index 000000000..5b6d8978c
--- /dev/null
+++ b/suites/upgrade-parallel/rgw/0-cluster/start.yaml
@@ -0,0 +1,11 @@
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+- - mon.b
+ - mon.c
+ - osd.2
+ - osd.3
+- - client.0
+ - client.1
diff --git a/suites/upgrade-parallel/rgw/1-cuttlefish-install/cuttlefish.yaml b/suites/upgrade-parallel/rgw/1-cuttlefish-install/cuttlefish.yaml
new file mode 100644
index 000000000..a2fa7e4a8
--- /dev/null
+++ b/suites/upgrade-parallel/rgw/1-cuttlefish-install/cuttlefish.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install:
+ branch: cuttlefish
+- ceph:
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade-parallel/rgw/2-workload/s3tests.yaml b/suites/upgrade-parallel/rgw/2-workload/s3tests.yaml
new file mode 100644
index 000000000..8144368f8
--- /dev/null
+++ b/suites/upgrade-parallel/rgw/2-workload/s3tests.yaml
@@ -0,0 +1,8 @@
+workload:
+ sequential:
+ - rgw: [client.0]
+ - s3tests:
+ # use older tests when we are running a mix
+ client.0:
+ force-branch: cuttlefish
+ rgw_server: client.0
diff --git a/suites/upgrade-parallel/rgw/3-upgrade-sequence/upgrade-all.yaml b/suites/upgrade-parallel/rgw/3-upgrade-sequence/upgrade-all.yaml
new file mode 100644
index 000000000..e59c1331f
--- /dev/null
+++ b/suites/upgrade-parallel/rgw/3-upgrade-sequence/upgrade-all.yaml
@@ -0,0 +1,6 @@
+upgrade-sequence:
+ sequential:
+ - install.upgrade:
+ all:
+ branch: next
+ - ceph.restart: [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1, osd.2, osd.3, rgw.client.0]
diff --git a/suites/upgrade-parallel/rgw/4-final-workload/final.yaml b/suites/upgrade-parallel/rgw/4-final-workload/final.yaml
new file mode 100644
index 000000000..fb754ed0c
--- /dev/null
+++ b/suites/upgrade-parallel/rgw/4-final-workload/final.yaml
@@ -0,0 +1,5 @@
+tasks:
+- rgw: [client.1]
+- swift:
+ client.1:
+ rgw_server: client.1
diff --git a/suites/upgrade-parallel/rgw/distro b/suites/upgrade-parallel/rgw/distro
new file mode 120000
index 000000000..3a0ac71c8
--- /dev/null
+++ b/suites/upgrade-parallel/rgw/distro
@@ -0,0 +1 @@
+../rados/distro
\ No newline at end of file
diff --git a/suites/upgrade-parallel/stress-split/% b/suites/upgrade-parallel/stress-split/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade-parallel/stress-split/0-cluster/start.yaml b/suites/upgrade-parallel/stress-split/0-cluster/start.yaml
new file mode 100644
index 000000000..c4df03d9b
--- /dev/null
+++ b/suites/upgrade-parallel/stress-split/0-cluster/start.yaml
@@ -0,0 +1,12 @@
+roles:
+- - mon.a
+ - mon.b
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+- - osd.3
+ - osd.4
+ - osd.5
+ - client.0
+ - mon.c
diff --git a/suites/upgrade-parallel/stress-split/1-cuttlefish-install/cuttlefish.yaml b/suites/upgrade-parallel/stress-split/1-cuttlefish-install/cuttlefish.yaml
new file mode 100644
index 000000000..b259af972
--- /dev/null
+++ b/suites/upgrade-parallel/stress-split/1-cuttlefish-install/cuttlefish.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install:
+ branch: cuttlefish
+- ceph:
diff --git a/suites/upgrade-parallel/stress-split/2-partial-upgrade/firsthalf.yaml b/suites/upgrade-parallel/stress-split/2-partial-upgrade/firsthalf.yaml
new file mode 100644
index 000000000..b10902d84
--- /dev/null
+++ b/suites/upgrade-parallel/stress-split/2-partial-upgrade/firsthalf.yaml
@@ -0,0 +1,6 @@
+tasks:
+- install.upgrade:
+ osd.0:
+ branch: next
+- ceph.restart:
+ daemons: [osd.0, osd.1, osd.2]
diff --git a/suites/upgrade-parallel/stress-split/3-thrash/default.yaml b/suites/upgrade-parallel/stress-split/3-thrash/default.yaml
new file mode 100644
index 000000000..7fc179a59
--- /dev/null
+++ b/suites/upgrade-parallel/stress-split/3-thrash/default.yaml
@@ -0,0 +1,11 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+tasks:
+- thrashosds:
+ thrash_primary_affinity: false
+ timeout: 1200
+ chance_pgnum_grow: 1
+ chance_pgpnum_fix: 1
diff --git a/suites/upgrade-parallel/stress-split/4-mon/more.yaml b/suites/upgrade-parallel/stress-split/4-mon/more.yaml
new file mode 100644
index 000000000..b6ffb3323
--- /dev/null
+++ b/suites/upgrade-parallel/stress-split/4-mon/more.yaml
@@ -0,0 +1,5 @@
+tasks:
+- ceph.restart:
+ daemons: [mon.a]
+ wait-for-healthy: false
+ wait-for-osds-up: true
diff --git a/suites/upgrade-parallel/stress-split/5-workload/rados_api_tests.yaml b/suites/upgrade-parallel/stress-split/5-workload/rados_api_tests.yaml
new file mode 100644
index 000000000..84f35a428
--- /dev/null
+++ b/suites/upgrade-parallel/stress-split/5-workload/rados_api_tests.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: cuttlefish
+ clients:
+ client.0:
+ - rados/test.sh
diff --git a/suites/upgrade-parallel/stress-split/5-workload/radosbench.yaml b/suites/upgrade-parallel/stress-split/5-workload/radosbench.yaml
new file mode 100644
index 000000000..3940870fc
--- /dev/null
+++ b/suites/upgrade-parallel/stress-split/5-workload/radosbench.yaml
@@ -0,0 +1,4 @@
+tasks:
+- radosbench:
+ clients: [client.0]
+ time: 1800
diff --git a/suites/upgrade-parallel/stress-split/5-workload/readwrite.yaml b/suites/upgrade-parallel/stress-split/5-workload/readwrite.yaml
new file mode 100644
index 000000000..c53e52b08
--- /dev/null
+++ b/suites/upgrade-parallel/stress-split/5-workload/readwrite.yaml
@@ -0,0 +1,9 @@
+tasks:
+- rados:
+ clients: [client.0]
+ ops: 4000
+ objects: 500
+ op_weights:
+ read: 45
+ write: 45
+ delete: 10
diff --git a/suites/upgrade-parallel/stress-split/5-workload/snaps-few-objects.yaml b/suites/upgrade-parallel/stress-split/5-workload/snaps-few-objects.yaml
new file mode 100644
index 000000000..c54039766
--- /dev/null
+++ b/suites/upgrade-parallel/stress-split/5-workload/snaps-few-objects.yaml
@@ -0,0 +1,12 @@
+tasks:
+- rados:
+ clients: [client.0]
+ ops: 4000
+ objects: 50
+ op_weights:
+ read: 100
+ write: 100
+ delete: 50
+ snap_create: 50
+ snap_remove: 50
+ rollback: 50
diff --git a/suites/upgrade-parallel/stress-split/5-workload/snaps-many-objects.yaml b/suites/upgrade-parallel/stress-split/5-workload/snaps-many-objects.yaml
new file mode 100644
index 000000000..9e311c946
--- /dev/null
+++ b/suites/upgrade-parallel/stress-split/5-workload/snaps-many-objects.yaml
@@ -0,0 +1,12 @@
+tasks:
+- rados:
+ clients: [client.0]
+ ops: 4000
+ objects: 500
+ op_weights:
+ read: 100
+ write: 100
+ delete: 50
+ snap_create: 50
+ snap_remove: 50
+ rollback: 50
diff --git a/suites/upgrade-parallel/stress-split/6-next-mon/monb.yaml b/suites/upgrade-parallel/stress-split/6-next-mon/monb.yaml
new file mode 100644
index 000000000..ead956612
--- /dev/null
+++ b/suites/upgrade-parallel/stress-split/6-next-mon/monb.yaml
@@ -0,0 +1,6 @@
+tasks:
+- ceph.restart:
+ daemons: [mon.b]
+ wait-for-healthy: false
+ wait-for-osds-up: true
+- ceph.wait_for_mon_quorum: [a, b]
diff --git a/suites/upgrade-parallel/stress-split/7-workload/rados_api_tests.yaml b/suites/upgrade-parallel/stress-split/7-workload/rados_api_tests.yaml
new file mode 100644
index 000000000..84f35a428
--- /dev/null
+++ b/suites/upgrade-parallel/stress-split/7-workload/rados_api_tests.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: cuttlefish
+ clients:
+ client.0:
+ - rados/test.sh
diff --git a/suites/upgrade-parallel/stress-split/distro b/suites/upgrade-parallel/stress-split/distro
new file mode 120000
index 000000000..3a0ac71c8
--- /dev/null
+++ b/suites/upgrade-parallel/stress-split/distro
@@ -0,0 +1 @@
+../rados/distro
\ No newline at end of file
diff --git a/suites/upgrade/dumpling/fs/% b/suites/upgrade/dumpling/fs/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade/dumpling/fs/0-cluster/start.yaml b/suites/upgrade/dumpling/fs/0-cluster/start.yaml
new file mode 100644
index 000000000..c1acc4e8a
--- /dev/null
+++ b/suites/upgrade/dumpling/fs/0-cluster/start.yaml
@@ -0,0 +1,17 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - scrub
+ fs: xfs
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+- - mon.b
+ - mon.c
+ - osd.3
+ - osd.4
+ - osd.5
+ - client.0
diff --git a/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.1.yaml b/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.1.yaml
new file mode 100644
index 000000000..3475b2012
--- /dev/null
+++ b/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.1.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.1
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.10.yaml b/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.10.yaml
new file mode 100644
index 000000000..fd4852e97
--- /dev/null
+++ b/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.10.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.10
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.3.yaml b/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.3.yaml
new file mode 100644
index 000000000..503f89207
--- /dev/null
+++ b/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.3.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.3
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.5.yaml b/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.5.yaml
new file mode 100644
index 000000000..7a0a5d5ec
--- /dev/null
+++ b/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.5.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.5
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.7.yaml b/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.7.yaml
new file mode 100644
index 000000000..15fade0e6
--- /dev/null
+++ b/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.7.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.7
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.9.yaml b/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.9.yaml
new file mode 100644
index 000000000..f64168b4c
--- /dev/null
+++ b/suites/upgrade/dumpling/fs/1-dumpling-install/v0.67.9.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.9
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/fs/2-workload/blogbench.yaml b/suites/upgrade/dumpling/fs/2-workload/blogbench.yaml
new file mode 100644
index 000000000..0cd59eaaf
--- /dev/null
+++ b/suites/upgrade/dumpling/fs/2-workload/blogbench.yaml
@@ -0,0 +1,5 @@
+workload:
+ workunit:
+ clients:
+ all:
+ - suites/blogbench.sh
diff --git a/suites/upgrade/dumpling/fs/3-upgrade-sequence/upgrade-mds-mon-osd.yaml b/suites/upgrade/dumpling/fs/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
new file mode 100644
index 000000000..028fae929
--- /dev/null
+++ b/suites/upgrade/dumpling/fs/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+# - install.upgrade:
+# all:
+# branch: dumpling
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
diff --git a/suites/upgrade/dumpling/fs/3-upgrade-sequence/upgrade-mon-osd-mds.yaml b/suites/upgrade/dumpling/fs/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
new file mode 100644
index 000000000..9f9482a98
--- /dev/null
+++ b/suites/upgrade/dumpling/fs/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+# - install.upgrade:
+# all:
+# branch: dumpling
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
diff --git a/suites/upgrade/dumpling/fs/3-upgrade-sequence/upgrade-osd-mon-mds.yaml b/suites/upgrade/dumpling/fs/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
new file mode 100644
index 000000000..c583c364a
--- /dev/null
+++ b/suites/upgrade/dumpling/fs/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+# - install.upgrade:
+# all:
+# branch: dumpling
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
diff --git a/suites/upgrade/dumpling/fs/4-final/monthrash.yaml b/suites/upgrade/dumpling/fs/4-final/monthrash.yaml
new file mode 100644
index 000000000..13af446eb
--- /dev/null
+++ b/suites/upgrade/dumpling/fs/4-final/monthrash.yaml
@@ -0,0 +1,10 @@
+tasks:
+- mon_thrash:
+ revive_delay: 20
+ thrash_delay: 1
+- ceph-fuse:
+- workunit:
+ clients:
+ client.0:
+ - suites/dbench.sh
+
diff --git a/suites/upgrade/dumpling/fs/4-final/osdthrash.yaml b/suites/upgrade/dumpling/fs/4-final/osdthrash.yaml
new file mode 100644
index 000000000..e6420b631
--- /dev/null
+++ b/suites/upgrade/dumpling/fs/4-final/osdthrash.yaml
@@ -0,0 +1,18 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+ - log bound mismatch
+tasks:
+- thrashosds:
+ thrash_primary_affinity: false
+ timeout: 1200
+ chance_pgnum_grow: 1
+ chance_pgpnum_fix: 1
+- ceph-fuse:
+- workunit:
+ clients:
+ all:
+ - suites/iogen.sh
+
diff --git a/suites/upgrade/dumpling/rados/% b/suites/upgrade/dumpling/rados/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade/dumpling/rados/0-cluster/start.yaml b/suites/upgrade/dumpling/rados/0-cluster/start.yaml
new file mode 100644
index 000000000..c1acc4e8a
--- /dev/null
+++ b/suites/upgrade/dumpling/rados/0-cluster/start.yaml
@@ -0,0 +1,17 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - scrub
+ fs: xfs
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+- - mon.b
+ - mon.c
+ - osd.3
+ - osd.4
+ - osd.5
+ - client.0
diff --git a/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.1.yaml b/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.1.yaml
new file mode 100644
index 000000000..3475b2012
--- /dev/null
+++ b/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.1.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.1
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.10.yaml b/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.10.yaml
new file mode 100644
index 000000000..fd4852e97
--- /dev/null
+++ b/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.10.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.10
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.3.yaml b/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.3.yaml
new file mode 100644
index 000000000..503f89207
--- /dev/null
+++ b/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.3.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.3
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.5.yaml b/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.5.yaml
new file mode 100644
index 000000000..7a0a5d5ec
--- /dev/null
+++ b/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.5.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.5
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.7.yaml b/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.7.yaml
new file mode 100644
index 000000000..15fade0e6
--- /dev/null
+++ b/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.7.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.7
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.9.yaml b/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.9.yaml
new file mode 100644
index 000000000..f64168b4c
--- /dev/null
+++ b/suites/upgrade/dumpling/rados/1-dumpling-install/v0.67.9.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.9
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rados/2-workload/testrados.yaml b/suites/upgrade/dumpling/rados/2-workload/testrados.yaml
new file mode 100644
index 000000000..8eaab19fd
--- /dev/null
+++ b/suites/upgrade/dumpling/rados/2-workload/testrados.yaml
@@ -0,0 +1,13 @@
+workload:
+ rados:
+ clients: [client.0]
+ ops: 2000
+ objects: 50
+ op_weights:
+ read: 100
+ write: 100
+ delete: 50
+ snap_create: 50
+ snap_remove: 50
+ rollback: 50
+
diff --git a/suites/upgrade/dumpling/rados/3-upgrade-sequence/upgrade-mds-mon-osd.yaml b/suites/upgrade/dumpling/rados/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
new file mode 100644
index 000000000..028fae929
--- /dev/null
+++ b/suites/upgrade/dumpling/rados/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+# - install.upgrade:
+# all:
+# branch: dumpling
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
diff --git a/suites/upgrade/dumpling/rados/3-upgrade-sequence/upgrade-mon-osd-mds.yaml b/suites/upgrade/dumpling/rados/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
new file mode 100644
index 000000000..9f9482a98
--- /dev/null
+++ b/suites/upgrade/dumpling/rados/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+# - install.upgrade:
+# all:
+# branch: dumpling
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
diff --git a/suites/upgrade/dumpling/rados/3-upgrade-sequence/upgrade-osd-mon-mds.yaml b/suites/upgrade/dumpling/rados/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
new file mode 100644
index 000000000..4a0ac8b40
--- /dev/null
+++ b/suites/upgrade/dumpling/rados/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
@@ -0,0 +1,35 @@
+upgrade-sequence:
+ sequential:
+# - install.upgrade:
+# all:
+# branch: dumpling
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
diff --git a/suites/upgrade/dumpling/rados/4-final/monthrash.yaml b/suites/upgrade/dumpling/rados/4-final/monthrash.yaml
new file mode 100644
index 000000000..810ba1b30
--- /dev/null
+++ b/suites/upgrade/dumpling/rados/4-final/monthrash.yaml
@@ -0,0 +1,9 @@
+tasks:
+- mon_thrash:
+ revive_delay: 20
+ thrash_delay: 1
+- workunit:
+ clients:
+ client.0:
+ - rados/test.sh
+
diff --git a/suites/upgrade/dumpling/rados/4-final/osdthrash.yaml b/suites/upgrade/dumpling/rados/4-final/osdthrash.yaml
new file mode 100644
index 000000000..e0a9ec02c
--- /dev/null
+++ b/suites/upgrade/dumpling/rados/4-final/osdthrash.yaml
@@ -0,0 +1,24 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+ - log bound mismatch
+tasks:
+- thrashosds:
+ thrash_primary_affinity: false
+ timeout: 1200
+ chance_pgnum_grow: 1
+ chance_pgpnum_fix: 1
+- rados:
+ clients: [client.0]
+ ops: 2000
+ objects: 50
+ op_weights:
+ read: 100
+ write: 100
+ delete: 50
+ snap_create: 50
+ snap_remove: 50
+ rollback: 50
+
diff --git a/suites/upgrade/dumpling/rbd/% b/suites/upgrade/dumpling/rbd/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade/dumpling/rbd/0-cluster/start.yaml b/suites/upgrade/dumpling/rbd/0-cluster/start.yaml
new file mode 100644
index 000000000..c1acc4e8a
--- /dev/null
+++ b/suites/upgrade/dumpling/rbd/0-cluster/start.yaml
@@ -0,0 +1,17 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - scrub
+ fs: xfs
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+- - mon.b
+ - mon.c
+ - osd.3
+ - osd.4
+ - osd.5
+ - client.0
diff --git a/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.1.yaml b/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.1.yaml
new file mode 100644
index 000000000..3475b2012
--- /dev/null
+++ b/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.1.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.1
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.10.yaml b/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.10.yaml
new file mode 100644
index 000000000..fd4852e97
--- /dev/null
+++ b/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.10.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.10
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.3.yaml b/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.3.yaml
new file mode 100644
index 000000000..503f89207
--- /dev/null
+++ b/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.3.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.3
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.5.yaml b/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.5.yaml
new file mode 100644
index 000000000..7a0a5d5ec
--- /dev/null
+++ b/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.5.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.5
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.7.yaml b/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.7.yaml
new file mode 100644
index 000000000..15fade0e6
--- /dev/null
+++ b/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.7.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.7
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.9.yaml b/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.9.yaml
new file mode 100644
index 000000000..f64168b4c
--- /dev/null
+++ b/suites/upgrade/dumpling/rbd/1-dumpling-install/v0.67.9.yaml
@@ -0,0 +1,10 @@
+tasks:
+- install:
+ tag: v0.67.9
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rbd/2-workload/rbd.yaml b/suites/upgrade/dumpling/rbd/2-workload/rbd.yaml
new file mode 100644
index 000000000..ce2fabe03
--- /dev/null
+++ b/suites/upgrade/dumpling/rbd/2-workload/rbd.yaml
@@ -0,0 +1,14 @@
+workload:
+ sequential:
+ - workunit:
+ clients:
+ client.0:
+ - rbd/import_export.sh
+ env:
+ RBD_CREATE_ARGS: --new-format
+ - workunit:
+ clients:
+ client.0:
+ - cls/test_cls_rbd.sh
+
+
diff --git a/suites/upgrade/dumpling/rbd/3-upgrade-sequence/upgrade-mds-mon-osd.yaml b/suites/upgrade/dumpling/rbd/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
new file mode 100644
index 000000000..028fae929
--- /dev/null
+++ b/suites/upgrade/dumpling/rbd/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+# - install.upgrade:
+# all:
+# branch: dumpling
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
diff --git a/suites/upgrade/dumpling/rbd/3-upgrade-sequence/upgrade-mon-osd-mds.yaml b/suites/upgrade/dumpling/rbd/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
new file mode 100644
index 000000000..9f9482a98
--- /dev/null
+++ b/suites/upgrade/dumpling/rbd/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+# - install.upgrade:
+# all:
+# branch: dumpling
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
diff --git a/suites/upgrade/dumpling/rbd/3-upgrade-sequence/upgrade-osd-mon-mds.yaml b/suites/upgrade/dumpling/rbd/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
new file mode 100644
index 000000000..c583c364a
--- /dev/null
+++ b/suites/upgrade/dumpling/rbd/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
@@ -0,0 +1,33 @@
+upgrade-sequence:
+ sequential:
+# - install.upgrade:
+# all:
+# branch: dumpling
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
diff --git a/suites/upgrade/dumpling/rbd/4-final/monthrash.yaml b/suites/upgrade/dumpling/rbd/4-final/monthrash.yaml
new file mode 100644
index 000000000..593191c24
--- /dev/null
+++ b/suites/upgrade/dumpling/rbd/4-final/monthrash.yaml
@@ -0,0 +1,11 @@
+tasks:
+- mon_thrash:
+ revive_delay: 20
+ thrash_delay: 1
+- workunit:
+ clients:
+ client.0:
+ - rbd/copy.sh
+ env:
+ RBD_CREATE_ARGS: --new-format
+
diff --git a/suites/upgrade/dumpling/rbd/4-final/osdthrash.yaml b/suites/upgrade/dumpling/rbd/4-final/osdthrash.yaml
new file mode 100644
index 000000000..d92de013b
--- /dev/null
+++ b/suites/upgrade/dumpling/rbd/4-final/osdthrash.yaml
@@ -0,0 +1,17 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - wrongly marked me down
+ - objects unfound and apparently lost
+ - log bound mismatch
+tasks:
+- thrashosds:
+ thrash_primary_affinity: false
+ timeout: 1200
+ chance_pgnum_grow: 1
+ chance_pgpnum_fix: 1
+- workunit:
+ clients:
+ client.0:
+ - rbd/test_lock_fence.sh
+
diff --git a/suites/upgrade/dumpling/rgw/% b/suites/upgrade/dumpling/rgw/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade/dumpling/rgw/0-cluster/start.yaml b/suites/upgrade/dumpling/rgw/0-cluster/start.yaml
new file mode 100644
index 000000000..c1acc4e8a
--- /dev/null
+++ b/suites/upgrade/dumpling/rgw/0-cluster/start.yaml
@@ -0,0 +1,17 @@
+overrides:
+ ceph:
+ log-whitelist:
+ - scrub
+ fs: xfs
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+ - osd.2
+- - mon.b
+ - mon.c
+ - osd.3
+ - osd.4
+ - osd.5
+ - client.0
diff --git a/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.1.yaml b/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.1.yaml
new file mode 100644
index 000000000..f0653d6f5
--- /dev/null
+++ b/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.1.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+ tag: v0.67.1
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- rgw: [client.0]
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.10.yaml b/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.10.yaml
new file mode 100644
index 000000000..c115c85df
--- /dev/null
+++ b/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.10.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+ tag: v0.67.10
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- rgw: [client.0]
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.3.yaml b/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.3.yaml
new file mode 100644
index 000000000..430ac0c95
--- /dev/null
+++ b/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.3.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+ tag: v0.67.3
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- rgw: [client.0]
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.5.yaml b/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.5.yaml
new file mode 100644
index 000000000..2982c93ca
--- /dev/null
+++ b/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.5.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+ tag: v0.67.5
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- rgw: [client.0]
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.7.yaml b/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.7.yaml
new file mode 100644
index 000000000..b8d669848
--- /dev/null
+++ b/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.7.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+ tag: v0.67.7
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- rgw: [client.0]
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.9.yaml b/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.9.yaml
new file mode 100644
index 000000000..791c6c302
--- /dev/null
+++ b/suites/upgrade/dumpling/rgw/1-dumpling-install/v0.67.9.yaml
@@ -0,0 +1,11 @@
+tasks:
+- install:
+ tag: v0.67.9
+- ceph:
+- install.upgrade:
+ all:
+ branch: dumpling
+- rgw: [client.0]
+- parallel:
+ - workload
+ - upgrade-sequence
diff --git a/suites/upgrade/dumpling/rgw/2-workload/testrgw.yaml b/suites/upgrade/dumpling/rgw/2-workload/testrgw.yaml
new file mode 100644
index 000000000..325068112
--- /dev/null
+++ b/suites/upgrade/dumpling/rgw/2-workload/testrgw.yaml
@@ -0,0 +1,6 @@
+workload:
+ sequential:
+ - s3tests:
+ client.0:
+ rgw_server: client.0
+
diff --git a/suites/upgrade/dumpling/rgw/3-upgrade-sequence/upgrade-mds-mon-osd.yaml b/suites/upgrade/dumpling/rgw/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
new file mode 100644
index 000000000..3fafef773
--- /dev/null
+++ b/suites/upgrade/dumpling/rgw/3-upgrade-sequence/upgrade-mds-mon-osd.yaml
@@ -0,0 +1,38 @@
+upgrade-sequence:
+ sequential:
+# - install.upgrade:
+# all:
+# branch: dumpling
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [rgw.client.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
+ - sleep:
+ duration: 30
diff --git a/suites/upgrade/dumpling/rgw/3-upgrade-sequence/upgrade-mon-osd-mds.yaml b/suites/upgrade/dumpling/rgw/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
new file mode 100644
index 000000000..994b6b75a
--- /dev/null
+++ b/suites/upgrade/dumpling/rgw/3-upgrade-sequence/upgrade-mon-osd-mds.yaml
@@ -0,0 +1,38 @@
+upgrade-sequence:
+ sequential:
+# - install.upgrade:
+# all:
+# branch: dumpling
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [rgw.client.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
+ - sleep:
+ duration: 30
diff --git a/suites/upgrade/dumpling/rgw/3-upgrade-sequence/upgrade-osd-mon-mds.yaml b/suites/upgrade/dumpling/rgw/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
new file mode 100644
index 000000000..33e4dbdb4
--- /dev/null
+++ b/suites/upgrade/dumpling/rgw/3-upgrade-sequence/upgrade-osd-mon-mds.yaml
@@ -0,0 +1,38 @@
+upgrade-sequence:
+ sequential:
+# - install.upgrade:
+# all:
+# branch: dumpling
+ - ceph.restart: [osd.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.1]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.2]
+ - sleep:
+ duration: 30
+ - ceph.restart: [rgw.client.0]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.3]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.4]
+ - sleep:
+ duration: 30
+ - ceph.restart: [osd.5]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.a]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.b]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mon.c]
+ - sleep:
+ duration: 60
+ - ceph.restart: [mds.a]
+ - sleep:
+ duration: 60
diff --git a/suites/upgrade/dumpling/rgw/4-final/monthrash.yaml b/suites/upgrade/dumpling/rgw/4-final/monthrash.yaml
new file mode 100644
index 000000000..9361edc80
--- /dev/null
+++ b/suites/upgrade/dumpling/rgw/4-final/monthrash.yaml
@@ -0,0 +1,8 @@
+tasks:
+- mon_thrash:
+ revive_delay: 20
+ thrash_delay: 1
+- swift:
+ client.0:
+ rgw_server: client.0
+
diff --git a/suites/upgrade/dumpling/rgw/4-final/swift.yaml b/suites/upgrade/dumpling/rgw/4-final/swift.yaml
new file mode 100644
index 000000000..45e2fc9cc
--- /dev/null
+++ b/suites/upgrade/dumpling/rgw/4-final/swift.yaml
@@ -0,0 +1,4 @@
+tasks:
+- swift:
+ client.0:
+ rgw_server: client.0
diff --git a/suites/upgrade/mixed-cluster/% b/suites/upgrade/mixed-cluster/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade/mixed-cluster/0-cluster/start.yaml b/suites/upgrade/mixed-cluster/0-cluster/start.yaml
new file mode 100644
index 000000000..0a85eacad
--- /dev/null
+++ b/suites/upgrade/mixed-cluster/0-cluster/start.yaml
@@ -0,0 +1,11 @@
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+- - mon.b
+ - mon.c
+ - osd.2
+ - osd.3
+- - client.0
+
diff --git a/suites/upgrade/mixed-cluster/1-cuttlefish-install/cuttlefish.yaml b/suites/upgrade/mixed-cluster/1-cuttlefish-install/cuttlefish.yaml
new file mode 100644
index 000000000..50b65f72b
--- /dev/null
+++ b/suites/upgrade/mixed-cluster/1-cuttlefish-install/cuttlefish.yaml
@@ -0,0 +1,5 @@
+tasks:
+- install:
+ branch: cuttlefish
+- ceph:
+
diff --git a/suites/upgrade/mixed-cluster/2-cuttlefish-workload/api.yaml b/suites/upgrade/mixed-cluster/2-cuttlefish-workload/api.yaml
new file mode 100644
index 000000000..ad36bddb4
--- /dev/null
+++ b/suites/upgrade/mixed-cluster/2-cuttlefish-workload/api.yaml
@@ -0,0 +1,8 @@
+tasks:
+- workunit:
+ branch: cuttlefish
+ clients:
+ client.0:
+ - rados/test.sh
+ - cls
+
diff --git a/suites/upgrade/mixed-cluster/2-cuttlefish-workload/load-gen-mix.yaml b/suites/upgrade/mixed-cluster/2-cuttlefish-workload/load-gen-mix.yaml
new file mode 100644
index 000000000..7ec655c8c
--- /dev/null
+++ b/suites/upgrade/mixed-cluster/2-cuttlefish-workload/load-gen-mix.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: cuttlefish
+ clients:
+ client.0:
+ - rados/load-gen-mix.sh
diff --git a/suites/upgrade/mixed-cluster/3-partial-osds-upgrade/next.yaml b/suites/upgrade/mixed-cluster/3-partial-osds-upgrade/next.yaml
new file mode 100644
index 000000000..4f1d5d03e
--- /dev/null
+++ b/suites/upgrade/mixed-cluster/3-partial-osds-upgrade/next.yaml
@@ -0,0 +1,7 @@
+tasks:
+- install.upgrade:
+ osd.0:
+ branch: next
+ osd.2:
+ branch: next
+
diff --git a/suites/upgrade/mixed-cluster/4-osds-restart/restart.yaml b/suites/upgrade/mixed-cluster/4-osds-restart/restart.yaml
new file mode 100644
index 000000000..3a84bbb40
--- /dev/null
+++ b/suites/upgrade/mixed-cluster/4-osds-restart/restart.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [osd.0, osd.2]
diff --git a/suites/upgrade/mixed-cluster/5-next-workload/api.yaml b/suites/upgrade/mixed-cluster/5-next-workload/api.yaml
new file mode 100644
index 000000000..ad36bddb4
--- /dev/null
+++ b/suites/upgrade/mixed-cluster/5-next-workload/api.yaml
@@ -0,0 +1,8 @@
+tasks:
+- workunit:
+ branch: cuttlefish
+ clients:
+ client.0:
+ - rados/test.sh
+ - cls
+
diff --git a/suites/upgrade/mixed-cluster/5-next-workload/load-gen-big.yaml b/suites/upgrade/mixed-cluster/5-next-workload/load-gen-big.yaml
new file mode 100644
index 000000000..0f6e616a2
--- /dev/null
+++ b/suites/upgrade/mixed-cluster/5-next-workload/load-gen-big.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: cuttlefish
+ clients:
+ client.0:
+ - rados/load-gen-big.sh
diff --git a/suites/upgrade/mixed-mons/% b/suites/upgrade/mixed-mons/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade/mixed-mons/0-cluster/start.yaml b/suites/upgrade/mixed-mons/0-cluster/start.yaml
new file mode 100644
index 000000000..0a85eacad
--- /dev/null
+++ b/suites/upgrade/mixed-mons/0-cluster/start.yaml
@@ -0,0 +1,11 @@
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+- - mon.b
+ - mon.c
+ - osd.2
+ - osd.3
+- - client.0
+
diff --git a/suites/upgrade/mixed-mons/1-cuttlefish-install/cuttlefish.yaml b/suites/upgrade/mixed-mons/1-cuttlefish-install/cuttlefish.yaml
new file mode 100644
index 000000000..50b65f72b
--- /dev/null
+++ b/suites/upgrade/mixed-mons/1-cuttlefish-install/cuttlefish.yaml
@@ -0,0 +1,5 @@
+tasks:
+- install:
+ branch: cuttlefish
+- ceph:
+
diff --git a/suites/upgrade/mixed-mons/2-cuttlefish-workload/cephtool.yaml b/suites/upgrade/mixed-mons/2-cuttlefish-workload/cephtool.yaml
new file mode 100644
index 000000000..8648784fd
--- /dev/null
+++ b/suites/upgrade/mixed-mons/2-cuttlefish-workload/cephtool.yaml
@@ -0,0 +1,7 @@
+tasks:
+- workunit:
+ branch: cuttlefish
+ clients:
+ all:
+ - cephtool/test.sh
+ - mon/pool_ops.sh
diff --git a/suites/upgrade/mixed-mons/3-partial-mon-upgrade/next.yaml b/suites/upgrade/mixed-mons/3-partial-mon-upgrade/next.yaml
new file mode 100644
index 000000000..2910abc38
--- /dev/null
+++ b/suites/upgrade/mixed-mons/3-partial-mon-upgrade/next.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install.upgrade:
+ mon.a:
+ branch: next
diff --git a/suites/upgrade/mixed-mons/4-mon-restart/restart.yaml b/suites/upgrade/mixed-mons/4-mon-restart/restart.yaml
new file mode 100644
index 000000000..b6ffb3323
--- /dev/null
+++ b/suites/upgrade/mixed-mons/4-mon-restart/restart.yaml
@@ -0,0 +1,5 @@
+tasks:
+- ceph.restart:
+ daemons: [mon.a]
+ wait-for-healthy: false
+ wait-for-osds-up: true
diff --git a/suites/upgrade/mixed-mons/5-next-workload/cephtool.yaml b/suites/upgrade/mixed-mons/5-next-workload/cephtool.yaml
new file mode 100644
index 000000000..8648784fd
--- /dev/null
+++ b/suites/upgrade/mixed-mons/5-next-workload/cephtool.yaml
@@ -0,0 +1,7 @@
+tasks:
+- workunit:
+ branch: cuttlefish
+ clients:
+ all:
+ - cephtool/test.sh
+ - mon/pool_ops.sh
diff --git a/suites/upgrade/rados-double/% b/suites/upgrade/rados-double/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade/rados-double/0-cluster/start.yaml b/suites/upgrade/rados-double/0-cluster/start.yaml
new file mode 100644
index 000000000..01747e420
--- /dev/null
+++ b/suites/upgrade/rados-double/0-cluster/start.yaml
@@ -0,0 +1,10 @@
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+- - mon.b
+ - mon.c
+ - osd.2
+ - osd.3
+- - client.0
diff --git a/suites/upgrade/rados-double/1-bobtail-install/bobtail.yaml b/suites/upgrade/rados-double/1-bobtail-install/bobtail.yaml
new file mode 100644
index 000000000..c676a5582
--- /dev/null
+++ b/suites/upgrade/rados-double/1-bobtail-install/bobtail.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install:
+ branch: bobtail
+- ceph:
diff --git a/suites/upgrade/rados-double/2-bobtail-workload/api.yaml b/suites/upgrade/rados-double/2-bobtail-workload/api.yaml
new file mode 100644
index 000000000..637b7a8be
--- /dev/null
+++ b/suites/upgrade/rados-double/2-bobtail-workload/api.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: bobtail
+ clients:
+ client.0:
+ - rados/test.sh
diff --git a/suites/upgrade/rados-double/3-upgrade/cuttlefish.yaml b/suites/upgrade/rados-double/3-upgrade/cuttlefish.yaml
new file mode 100644
index 000000000..4dee94e34
--- /dev/null
+++ b/suites/upgrade/rados-double/3-upgrade/cuttlefish.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install.upgrade:
+ all:
+ branch: cuttlefish
diff --git a/suites/upgrade/rados-double/4-restart/upgrade_mon_mds_osd.yaml b/suites/upgrade/rados-double/4-restart/upgrade_mon_mds_osd.yaml
new file mode 100644
index 000000000..78e14e947
--- /dev/null
+++ b/suites/upgrade/rados-double/4-restart/upgrade_mon_mds_osd.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1, osd.2, osd.3]
diff --git a/suites/upgrade/rados-double/4-restart/upgrade_osd_mds_mon.yaml b/suites/upgrade/rados-double/4-restart/upgrade_osd_mds_mon.yaml
new file mode 100644
index 000000000..dbcd013b3
--- /dev/null
+++ b/suites/upgrade/rados-double/4-restart/upgrade_osd_mds_mon.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [osd.0, osd.1, osd.2, osd.3, mds.a, mon.a, mon.b, mon.c]
diff --git a/suites/upgrade/rados-double/5-cuttlefish-workload/api.yaml b/suites/upgrade/rados-double/5-cuttlefish-workload/api.yaml
new file mode 100644
index 000000000..665265825
--- /dev/null
+++ b/suites/upgrade/rados-double/5-cuttlefish-workload/api.yaml
@@ -0,0 +1,7 @@
+tasks:
+- workunit:
+ branch: cuttlefish
+ clients:
+ client.0:
+ - rados/test.sh
+ - cls
diff --git a/suites/upgrade/rados-double/5-cuttlefish-workload/load-gen-mix.yaml b/suites/upgrade/rados-double/5-cuttlefish-workload/load-gen-mix.yaml
new file mode 100644
index 000000000..7ec655c8c
--- /dev/null
+++ b/suites/upgrade/rados-double/5-cuttlefish-workload/load-gen-mix.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: cuttlefish
+ clients:
+ client.0:
+ - rados/load-gen-mix.sh
diff --git a/suites/upgrade/rados-double/6-upgrade-next/next.yaml b/suites/upgrade/rados-double/6-upgrade-next/next.yaml
new file mode 100644
index 000000000..3e8e04cad
--- /dev/null
+++ b/suites/upgrade/rados-double/6-upgrade-next/next.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install.upgrade:
+ all:
+ branch: next
diff --git a/suites/upgrade/rados-double/7-restart/mon-mds-osd.yaml b/suites/upgrade/rados-double/7-restart/mon-mds-osd.yaml
new file mode 100644
index 000000000..78e14e947
--- /dev/null
+++ b/suites/upgrade/rados-double/7-restart/mon-mds-osd.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1, osd.2, osd.3]
diff --git a/suites/upgrade/rados-double/7-restart/osd-mds-mon.yaml b/suites/upgrade/rados-double/7-restart/osd-mds-mon.yaml
new file mode 100644
index 000000000..dbcd013b3
--- /dev/null
+++ b/suites/upgrade/rados-double/7-restart/osd-mds-mon.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [osd.0, osd.1, osd.2, osd.3, mds.a, mon.a, mon.b, mon.c]
diff --git a/suites/upgrade/rados-double/8-next-workload/api.yaml b/suites/upgrade/rados-double/8-next-workload/api.yaml
new file mode 100644
index 000000000..294713cf2
--- /dev/null
+++ b/suites/upgrade/rados-double/8-next-workload/api.yaml
@@ -0,0 +1,7 @@
+tasks:
+- workunit:
+ branch: next
+ clients:
+ client.0:
+ - rados/test.sh
+ - cls
diff --git a/suites/upgrade/rados-double/8-next-workload/snaps-few-objects.yaml b/suites/upgrade/rados-double/8-next-workload/snaps-few-objects.yaml
new file mode 100644
index 000000000..c54039766
--- /dev/null
+++ b/suites/upgrade/rados-double/8-next-workload/snaps-few-objects.yaml
@@ -0,0 +1,12 @@
+tasks:
+- rados:
+ clients: [client.0]
+ ops: 4000
+ objects: 50
+ op_weights:
+ read: 100
+ write: 100
+ delete: 50
+ snap_create: 50
+ snap_remove: 50
+ rollback: 50
diff --git a/suites/upgrade/rados/% b/suites/upgrade/rados/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade/rados/0-cluster/start.yaml b/suites/upgrade/rados/0-cluster/start.yaml
new file mode 100644
index 000000000..01747e420
--- /dev/null
+++ b/suites/upgrade/rados/0-cluster/start.yaml
@@ -0,0 +1,10 @@
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+- - mon.b
+ - mon.c
+ - osd.2
+ - osd.3
+- - client.0
diff --git a/suites/upgrade/rados/1-cuttlefish-install/cuttlefish.yaml b/suites/upgrade/rados/1-cuttlefish-install/cuttlefish.yaml
new file mode 100644
index 000000000..b259af972
--- /dev/null
+++ b/suites/upgrade/rados/1-cuttlefish-install/cuttlefish.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install:
+ branch: cuttlefish
+- ceph:
diff --git a/suites/upgrade/rados/2-cuttlefish-workload/api.yaml b/suites/upgrade/rados/2-cuttlefish-workload/api.yaml
new file mode 100644
index 000000000..665265825
--- /dev/null
+++ b/suites/upgrade/rados/2-cuttlefish-workload/api.yaml
@@ -0,0 +1,7 @@
+tasks:
+- workunit:
+ branch: cuttlefish
+ clients:
+ client.0:
+ - rados/test.sh
+ - cls
diff --git a/suites/upgrade/rados/2-cuttlefish-workload/load-gen-mix.yaml b/suites/upgrade/rados/2-cuttlefish-workload/load-gen-mix.yaml
new file mode 100644
index 000000000..7ec655c8c
--- /dev/null
+++ b/suites/upgrade/rados/2-cuttlefish-workload/load-gen-mix.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: cuttlefish
+ clients:
+ client.0:
+ - rados/load-gen-mix.sh
diff --git a/suites/upgrade/rados/3-upgrade/next.yaml b/suites/upgrade/rados/3-upgrade/next.yaml
new file mode 100644
index 000000000..3e8e04cad
--- /dev/null
+++ b/suites/upgrade/rados/3-upgrade/next.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install.upgrade:
+ all:
+ branch: next
diff --git a/suites/upgrade/rados/4-restart/upgrade_mds_mon_osd.yaml b/suites/upgrade/rados/4-restart/upgrade_mds_mon_osd.yaml
new file mode 100644
index 000000000..d21800684
--- /dev/null
+++ b/suites/upgrade/rados/4-restart/upgrade_mds_mon_osd.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [mds.a, mon.a, mon.b, mon.c, osd.0, osd.1, osd.2, osd.3]
diff --git a/suites/upgrade/rados/4-restart/upgrade_mds_osd_mon.yaml b/suites/upgrade/rados/4-restart/upgrade_mds_osd_mon.yaml
new file mode 100644
index 000000000..a8508353e
--- /dev/null
+++ b/suites/upgrade/rados/4-restart/upgrade_mds_osd_mon.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [mds.a, osd.0, osd.1, osd.2, osd.3, mon.a, mon.b, mon.c]
diff --git a/suites/upgrade/rados/4-restart/upgrade_mon_mds_osd.yaml b/suites/upgrade/rados/4-restart/upgrade_mon_mds_osd.yaml
new file mode 100644
index 000000000..78e14e947
--- /dev/null
+++ b/suites/upgrade/rados/4-restart/upgrade_mon_mds_osd.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1, osd.2, osd.3]
diff --git a/suites/upgrade/rados/4-restart/upgrade_mon_osd_mds.yaml b/suites/upgrade/rados/4-restart/upgrade_mon_osd_mds.yaml
new file mode 100644
index 000000000..31a79e459
--- /dev/null
+++ b/suites/upgrade/rados/4-restart/upgrade_mon_osd_mds.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [mon.a, mon.b, mon.c, osd.0, osd.1, osd.2, osd.3, mds.a]
diff --git a/suites/upgrade/rados/4-restart/upgrade_osd_mds_mon.yaml b/suites/upgrade/rados/4-restart/upgrade_osd_mds_mon.yaml
new file mode 100644
index 000000000..dbcd013b3
--- /dev/null
+++ b/suites/upgrade/rados/4-restart/upgrade_osd_mds_mon.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [osd.0, osd.1, osd.2, osd.3, mds.a, mon.a, mon.b, mon.c]
diff --git a/suites/upgrade/rados/4-restart/upgrade_osd_mon_mds.yaml b/suites/upgrade/rados/4-restart/upgrade_osd_mon_mds.yaml
new file mode 100644
index 000000000..e8fe288f6
--- /dev/null
+++ b/suites/upgrade/rados/4-restart/upgrade_osd_mon_mds.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [osd.0, osd.1, osd.2, osd.3, mon.a, mon.b, mon.c, mds.a]
diff --git a/suites/upgrade/rados/5-next-workload/api.yaml b/suites/upgrade/rados/5-next-workload/api.yaml
new file mode 100644
index 000000000..294713cf2
--- /dev/null
+++ b/suites/upgrade/rados/5-next-workload/api.yaml
@@ -0,0 +1,7 @@
+tasks:
+- workunit:
+ branch: next
+ clients:
+ client.0:
+ - rados/test.sh
+ - cls
diff --git a/suites/upgrade/rados/5-next-workload/snaps-few-objects.yaml b/suites/upgrade/rados/5-next-workload/snaps-few-objects.yaml
new file mode 100644
index 000000000..c54039766
--- /dev/null
+++ b/suites/upgrade/rados/5-next-workload/snaps-few-objects.yaml
@@ -0,0 +1,12 @@
+tasks:
+- rados:
+ clients: [client.0]
+ ops: 4000
+ objects: 50
+ op_weights:
+ read: 100
+ write: 100
+ delete: 50
+ snap_create: 50
+ snap_remove: 50
+ rollback: 50
diff --git a/suites/upgrade/rbd-double/% b/suites/upgrade/rbd-double/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade/rbd-double/0-cluster/start.yaml b/suites/upgrade/rbd-double/0-cluster/start.yaml
new file mode 100644
index 000000000..01747e420
--- /dev/null
+++ b/suites/upgrade/rbd-double/0-cluster/start.yaml
@@ -0,0 +1,10 @@
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+- - mon.b
+ - mon.c
+ - osd.2
+ - osd.3
+- - client.0
diff --git a/suites/upgrade/rbd-double/1-bobtail-install/bobtail.yaml b/suites/upgrade/rbd-double/1-bobtail-install/bobtail.yaml
new file mode 100644
index 000000000..c676a5582
--- /dev/null
+++ b/suites/upgrade/rbd-double/1-bobtail-install/bobtail.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install:
+ branch: bobtail
+- ceph:
diff --git a/suites/upgrade/rbd-double/2-bobtail-workload/import_export.yaml b/suites/upgrade/rbd-double/2-bobtail-workload/import_export.yaml
new file mode 100644
index 000000000..9123db83b
--- /dev/null
+++ b/suites/upgrade/rbd-double/2-bobtail-workload/import_export.yaml
@@ -0,0 +1,8 @@
+tasks:
+- workunit:
+ branch: bobtail
+ clients:
+ client.0:
+ - rbd/import_export.sh
+ env:
+ RBD_CREATE_ARGS: --new-format
diff --git a/suites/upgrade/rbd-double/3-upgrade/cuttlefish.yaml b/suites/upgrade/rbd-double/3-upgrade/cuttlefish.yaml
new file mode 100644
index 000000000..4dee94e34
--- /dev/null
+++ b/suites/upgrade/rbd-double/3-upgrade/cuttlefish.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install.upgrade:
+ all:
+ branch: cuttlefish
diff --git a/suites/upgrade/rbd-double/4-restart/upgrade_mon_mds_osd.yaml b/suites/upgrade/rbd-double/4-restart/upgrade_mon_mds_osd.yaml
new file mode 100644
index 000000000..78e14e947
--- /dev/null
+++ b/suites/upgrade/rbd-double/4-restart/upgrade_mon_mds_osd.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1, osd.2, osd.3]
diff --git a/suites/upgrade/rbd-double/4-restart/upgrade_osd_mds_mon.yaml b/suites/upgrade/rbd-double/4-restart/upgrade_osd_mds_mon.yaml
new file mode 100644
index 000000000..dbcd013b3
--- /dev/null
+++ b/suites/upgrade/rbd-double/4-restart/upgrade_osd_mds_mon.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [osd.0, osd.1, osd.2, osd.3, mds.a, mon.a, mon.b, mon.c]
diff --git a/suites/upgrade/rbd-double/5-cuttlefish-workload/api.yaml b/suites/upgrade/rbd-double/5-cuttlefish-workload/api.yaml
new file mode 100644
index 000000000..f0f81ff8a
--- /dev/null
+++ b/suites/upgrade/rbd-double/5-cuttlefish-workload/api.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: cuttlefish
+ clients:
+ client.0:
+ - rbd/test_librbd.sh
diff --git a/suites/upgrade/rbd-double/5-cuttlefish-workload/cls.yaml b/suites/upgrade/rbd-double/5-cuttlefish-workload/cls.yaml
new file mode 100644
index 000000000..520b584c0
--- /dev/null
+++ b/suites/upgrade/rbd-double/5-cuttlefish-workload/cls.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: cuttlefish
+ clients:
+ client.0:
+ - cls/test_cls_rbd.sh
diff --git a/suites/upgrade/rbd-double/6-upgrade-next/next.yaml b/suites/upgrade/rbd-double/6-upgrade-next/next.yaml
new file mode 100644
index 000000000..3e8e04cad
--- /dev/null
+++ b/suites/upgrade/rbd-double/6-upgrade-next/next.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install.upgrade:
+ all:
+ branch: next
diff --git a/suites/upgrade/rbd-double/7-restart/mon-mds-osd.yaml b/suites/upgrade/rbd-double/7-restart/mon-mds-osd.yaml
new file mode 100644
index 000000000..78e14e947
--- /dev/null
+++ b/suites/upgrade/rbd-double/7-restart/mon-mds-osd.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1, osd.2, osd.3]
diff --git a/suites/upgrade/rbd-double/7-restart/osd-mds-mon.yaml b/suites/upgrade/rbd-double/7-restart/osd-mds-mon.yaml
new file mode 100644
index 000000000..dbcd013b3
--- /dev/null
+++ b/suites/upgrade/rbd-double/7-restart/osd-mds-mon.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [osd.0, osd.1, osd.2, osd.3, mds.a, mon.a, mon.b, mon.c]
diff --git a/suites/upgrade/rbd-double/8-next-workload/import-export.yaml b/suites/upgrade/rbd-double/8-next-workload/import-export.yaml
new file mode 100644
index 000000000..c603b5326
--- /dev/null
+++ b/suites/upgrade/rbd-double/8-next-workload/import-export.yaml
@@ -0,0 +1,8 @@
+tasks:
+- workunit:
+ branch: next
+ clients:
+ client.0:
+ - rbd/import_export.sh
+ env:
+ RBD_CREATE_ARGS: --new-format
diff --git a/suites/upgrade/rbd-double/8-next-workload/python.yaml b/suites/upgrade/rbd-double/8-next-workload/python.yaml
new file mode 100644
index 000000000..8a98bc91f
--- /dev/null
+++ b/suites/upgrade/rbd-double/8-next-workload/python.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: next
+ clients:
+ client.0:
+ - rbd/test_librbd_python.sh
diff --git a/suites/upgrade/rbd/% b/suites/upgrade/rbd/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade/rbd/a/start.yaml b/suites/upgrade/rbd/a/start.yaml
new file mode 100644
index 000000000..cd071f9cf
--- /dev/null
+++ b/suites/upgrade/rbd/a/start.yaml
@@ -0,0 +1,14 @@
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+- - mon.b
+ - mon.c
+ - osd.2
+ - osd.3
+- - client.0
+tasks:
+- install:
+ branch: bobtail
+- ceph:
diff --git a/suites/upgrade/rbd/b/import_export.yaml b/suites/upgrade/rbd/b/import_export.yaml
new file mode 100644
index 000000000..9123db83b
--- /dev/null
+++ b/suites/upgrade/rbd/b/import_export.yaml
@@ -0,0 +1,8 @@
+tasks:
+- workunit:
+ branch: bobtail
+ clients:
+ client.0:
+ - rbd/import_export.sh
+ env:
+ RBD_CREATE_ARGS: --new-format
diff --git a/suites/upgrade/rbd/c/upgrade.yaml b/suites/upgrade/rbd/c/upgrade.yaml
new file mode 100644
index 000000000..3e8e04cad
--- /dev/null
+++ b/suites/upgrade/rbd/c/upgrade.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install.upgrade:
+ all:
+ branch: next
diff --git a/suites/upgrade/rbd/d/mon-osd-mds.yaml b/suites/upgrade/rbd/d/mon-osd-mds.yaml
new file mode 100644
index 000000000..31a79e459
--- /dev/null
+++ b/suites/upgrade/rbd/d/mon-osd-mds.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [mon.a, mon.b, mon.c, osd.0, osd.1, osd.2, osd.3, mds.a]
diff --git a/suites/upgrade/rbd/d/osd-mon-mds.yaml b/suites/upgrade/rbd/d/osd-mon-mds.yaml
new file mode 100644
index 000000000..e8fe288f6
--- /dev/null
+++ b/suites/upgrade/rbd/d/osd-mon-mds.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [osd.0, osd.1, osd.2, osd.3, mon.a, mon.b, mon.c, mds.a]
diff --git a/suites/upgrade/rbd/e/api.yaml b/suites/upgrade/rbd/e/api.yaml
new file mode 100644
index 000000000..405a4932d
--- /dev/null
+++ b/suites/upgrade/rbd/e/api.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: next
+ clients:
+ client.0:
+ - rbd/test_librbd.sh
diff --git a/suites/upgrade/rbd/e/cls.yaml b/suites/upgrade/rbd/e/cls.yaml
new file mode 100644
index 000000000..ee960fed0
--- /dev/null
+++ b/suites/upgrade/rbd/e/cls.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: next
+ clients:
+ client.0:
+ - cls/test_cls_rbd.sh
diff --git a/suites/upgrade/rbd/e/import-export.yaml b/suites/upgrade/rbd/e/import-export.yaml
new file mode 100644
index 000000000..c603b5326
--- /dev/null
+++ b/suites/upgrade/rbd/e/import-export.yaml
@@ -0,0 +1,8 @@
+tasks:
+- workunit:
+ branch: next
+ clients:
+ client.0:
+ - rbd/import_export.sh
+ env:
+ RBD_CREATE_ARGS: --new-format
diff --git a/suites/upgrade/rbd/e/python.yaml b/suites/upgrade/rbd/e/python.yaml
new file mode 100644
index 000000000..8a98bc91f
--- /dev/null
+++ b/suites/upgrade/rbd/e/python.yaml
@@ -0,0 +1,6 @@
+tasks:
+- workunit:
+ branch: next
+ clients:
+ client.0:
+ - rbd/test_librbd_python.sh
diff --git a/suites/upgrade/rgw-double/% b/suites/upgrade/rgw-double/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade/rgw-double/0-cluster/start.yaml b/suites/upgrade/rgw-double/0-cluster/start.yaml
new file mode 100644
index 000000000..01747e420
--- /dev/null
+++ b/suites/upgrade/rgw-double/0-cluster/start.yaml
@@ -0,0 +1,10 @@
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+- - mon.b
+ - mon.c
+ - osd.2
+ - osd.3
+- - client.0
diff --git a/suites/upgrade/rgw-double/1-bobtail-install/bobtail.yaml b/suites/upgrade/rgw-double/1-bobtail-install/bobtail.yaml
new file mode 100644
index 000000000..ca81c710b
--- /dev/null
+++ b/suites/upgrade/rgw-double/1-bobtail-install/bobtail.yaml
@@ -0,0 +1,5 @@
+tasks:
+- install:
+ branch: bobtail
+- ceph:
+- rgw:
diff --git a/suites/upgrade/rgw-double/2-bobtail-workload/s3tests.yaml b/suites/upgrade/rgw-double/2-bobtail-workload/s3tests.yaml
new file mode 100644
index 000000000..7397ae687
--- /dev/null
+++ b/suites/upgrade/rgw-double/2-bobtail-workload/s3tests.yaml
@@ -0,0 +1,5 @@
+tasks:
+- s3tests:
+ client.0:
+ force-branch: bobtail
+ rgw_server: client.0
diff --git a/suites/upgrade/rgw-double/3-upgrade/cuttlefish.yaml b/suites/upgrade/rgw-double/3-upgrade/cuttlefish.yaml
new file mode 100644
index 000000000..4dee94e34
--- /dev/null
+++ b/suites/upgrade/rgw-double/3-upgrade/cuttlefish.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install.upgrade:
+ all:
+ branch: cuttlefish
diff --git a/suites/upgrade/rgw-double/4-restart/upgrade_mon_mds_osd.yaml b/suites/upgrade/rgw-double/4-restart/upgrade_mon_mds_osd.yaml
new file mode 100644
index 000000000..86665905d
--- /dev/null
+++ b/suites/upgrade/rgw-double/4-restart/upgrade_mon_mds_osd.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1, osd.2, osd.3, rgw.client.0]
diff --git a/suites/upgrade/rgw-double/4-restart/upgrade_osd_mds_mon.yaml b/suites/upgrade/rgw-double/4-restart/upgrade_osd_mds_mon.yaml
new file mode 100644
index 000000000..425cf6082
--- /dev/null
+++ b/suites/upgrade/rgw-double/4-restart/upgrade_osd_mds_mon.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [osd.0, osd.1, osd.2, osd.3, mds.a, mon.a, mon.b, mon.c, rgw.client.0]
diff --git a/suites/upgrade/rgw-double/5-cuttlefish-workload/readwrite.yaml b/suites/upgrade/rgw-double/5-cuttlefish-workload/readwrite.yaml
new file mode 100644
index 000000000..d3166f117
--- /dev/null
+++ b/suites/upgrade/rgw-double/5-cuttlefish-workload/readwrite.yaml
@@ -0,0 +1,13 @@
+tasks:
+- s3readwrite:
+ client.0:
+ rgw_server: client.0
+ readwrite:
+ bucket: rwtest
+ readers: 10
+ writers: 3
+ duration: 300
+ files:
+ num: 10
+ size: 2000
+ stddev: 500
diff --git a/suites/upgrade/rgw-double/5-cuttlefish-workload/s3tests.yaml b/suites/upgrade/rgw-double/5-cuttlefish-workload/s3tests.yaml
new file mode 100644
index 000000000..573cffbc3
--- /dev/null
+++ b/suites/upgrade/rgw-double/5-cuttlefish-workload/s3tests.yaml
@@ -0,0 +1,4 @@
+tasks:
+- s3tests:
+ client.0:
+ rgw_server: client.0
diff --git a/suites/upgrade/rgw-double/5-cuttlefish-workload/swift.yaml b/suites/upgrade/rgw-double/5-cuttlefish-workload/swift.yaml
new file mode 100644
index 000000000..45e2fc9cc
--- /dev/null
+++ b/suites/upgrade/rgw-double/5-cuttlefish-workload/swift.yaml
@@ -0,0 +1,4 @@
+tasks:
+- swift:
+ client.0:
+ rgw_server: client.0
diff --git a/suites/upgrade/rgw-double/6-upgrade-next/next.yaml b/suites/upgrade/rgw-double/6-upgrade-next/next.yaml
new file mode 100644
index 000000000..3e8e04cad
--- /dev/null
+++ b/suites/upgrade/rgw-double/6-upgrade-next/next.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install.upgrade:
+ all:
+ branch: next
diff --git a/suites/upgrade/rgw-double/7-restart/mon-mds-osd.yaml b/suites/upgrade/rgw-double/7-restart/mon-mds-osd.yaml
new file mode 100644
index 000000000..86665905d
--- /dev/null
+++ b/suites/upgrade/rgw-double/7-restart/mon-mds-osd.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1, osd.2, osd.3, rgw.client.0]
diff --git a/suites/upgrade/rgw-double/7-restart/osd-mds-mon.yaml b/suites/upgrade/rgw-double/7-restart/osd-mds-mon.yaml
new file mode 100644
index 000000000..425cf6082
--- /dev/null
+++ b/suites/upgrade/rgw-double/7-restart/osd-mds-mon.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [osd.0, osd.1, osd.2, osd.3, mds.a, mon.a, mon.b, mon.c, rgw.client.0]
diff --git a/suites/upgrade/rgw-double/8-next-workload/readwrite.yaml b/suites/upgrade/rgw-double/8-next-workload/readwrite.yaml
new file mode 100644
index 000000000..d3166f117
--- /dev/null
+++ b/suites/upgrade/rgw-double/8-next-workload/readwrite.yaml
@@ -0,0 +1,13 @@
+tasks:
+- s3readwrite:
+ client.0:
+ rgw_server: client.0
+ readwrite:
+ bucket: rwtest
+ readers: 10
+ writers: 3
+ duration: 300
+ files:
+ num: 10
+ size: 2000
+ stddev: 500
diff --git a/suites/upgrade/rgw-double/8-next-workload/s3tests.yaml b/suites/upgrade/rgw-double/8-next-workload/s3tests.yaml
new file mode 100644
index 000000000..573cffbc3
--- /dev/null
+++ b/suites/upgrade/rgw-double/8-next-workload/s3tests.yaml
@@ -0,0 +1,4 @@
+tasks:
+- s3tests:
+ client.0:
+ rgw_server: client.0
diff --git a/suites/upgrade/rgw-double/8-next-workload/swift.yaml b/suites/upgrade/rgw-double/8-next-workload/swift.yaml
new file mode 100644
index 000000000..45e2fc9cc
--- /dev/null
+++ b/suites/upgrade/rgw-double/8-next-workload/swift.yaml
@@ -0,0 +1,4 @@
+tasks:
+- swift:
+ client.0:
+ rgw_server: client.0
diff --git a/suites/upgrade/rgw/% b/suites/upgrade/rgw/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade/rgw/a/start.yaml b/suites/upgrade/rgw/a/start.yaml
new file mode 100644
index 000000000..8b1ebbe2c
--- /dev/null
+++ b/suites/upgrade/rgw/a/start.yaml
@@ -0,0 +1,20 @@
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+- - mon.b
+ - mon.c
+ - osd.2
+ - osd.3
+ - client.1
+- - client.0
+tasks:
+- install:
+ branch: bobtail
+- ceph:
+ conf:
+ client:
+ client mount timeout: 600
+ rgw init timeout: 600
+- rgw: [client.0]
diff --git a/suites/upgrade/rgw/b/s3readwrite.yaml b/suites/upgrade/rgw/b/s3readwrite.yaml
new file mode 100644
index 000000000..d3166f117
--- /dev/null
+++ b/suites/upgrade/rgw/b/s3readwrite.yaml
@@ -0,0 +1,13 @@
+tasks:
+- s3readwrite:
+ client.0:
+ rgw_server: client.0
+ readwrite:
+ bucket: rwtest
+ readers: 10
+ writers: 3
+ duration: 300
+ files:
+ num: 10
+ size: 2000
+ stddev: 500
diff --git a/suites/upgrade/rgw/b/s3tests.yaml b/suites/upgrade/rgw/b/s3tests.yaml
new file mode 100644
index 000000000..8020d793c
--- /dev/null
+++ b/suites/upgrade/rgw/b/s3tests.yaml
@@ -0,0 +1,5 @@
+tasks:
+- s3tests:
+ client.0:
+ rgw_server: client.0
+ force-branch: bobtail
diff --git a/suites/upgrade/rgw/b/swift.yaml b/suites/upgrade/rgw/b/swift.yaml
new file mode 100644
index 000000000..45e2fc9cc
--- /dev/null
+++ b/suites/upgrade/rgw/b/swift.yaml
@@ -0,0 +1,4 @@
+tasks:
+- swift:
+ client.0:
+ rgw_server: client.0
diff --git a/suites/upgrade/rgw/c/upgrade.yaml b/suites/upgrade/rgw/c/upgrade.yaml
new file mode 100644
index 000000000..3e8e04cad
--- /dev/null
+++ b/suites/upgrade/rgw/c/upgrade.yaml
@@ -0,0 +1,4 @@
+tasks:
+- install.upgrade:
+ all:
+ branch: next
diff --git a/suites/upgrade/rgw/d/mon-osd-mds.yaml b/suites/upgrade/rgw/d/mon-osd-mds.yaml
new file mode 100644
index 000000000..ea8a58ccd
--- /dev/null
+++ b/suites/upgrade/rgw/d/mon-osd-mds.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [mon.a, mon.b, mon.c, osd.0, osd.1, osd.2, osd.3, mds.a, rgw.client.0]
diff --git a/suites/upgrade/rgw/d/osd-mon-mds.yaml b/suites/upgrade/rgw/d/osd-mon-mds.yaml
new file mode 100644
index 000000000..f9606ef70
--- /dev/null
+++ b/suites/upgrade/rgw/d/osd-mon-mds.yaml
@@ -0,0 +1,2 @@
+tasks:
+- ceph.restart: [osd.0, osd.1, osd.2, osd.3, mon.a, mon.b, mon.c, mds.a, rgw.client.0]
diff --git a/suites/upgrade/rgw/e/readwrite.yaml b/suites/upgrade/rgw/e/readwrite.yaml
new file mode 100644
index 000000000..d3166f117
--- /dev/null
+++ b/suites/upgrade/rgw/e/readwrite.yaml
@@ -0,0 +1,13 @@
+tasks:
+- s3readwrite:
+ client.0:
+ rgw_server: client.0
+ readwrite:
+ bucket: rwtest
+ readers: 10
+ writers: 3
+ duration: 300
+ files:
+ num: 10
+ size: 2000
+ stddev: 500
diff --git a/suites/upgrade/rgw/e/s3tests.yaml b/suites/upgrade/rgw/e/s3tests.yaml
new file mode 100644
index 000000000..573cffbc3
--- /dev/null
+++ b/suites/upgrade/rgw/e/s3tests.yaml
@@ -0,0 +1,4 @@
+tasks:
+- s3tests:
+ client.0:
+ rgw_server: client.0
diff --git a/suites/upgrade/rgw/e/swift.yaml b/suites/upgrade/rgw/e/swift.yaml
new file mode 100644
index 000000000..45e2fc9cc
--- /dev/null
+++ b/suites/upgrade/rgw/e/swift.yaml
@@ -0,0 +1,4 @@
+tasks:
+- swift:
+ client.0:
+ rgw_server: client.0
diff --git a/suites/upgrade/singleton/% b/suites/upgrade/singleton/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade/singleton/all/basic-test.yaml b/suites/upgrade/singleton/all/basic-test.yaml
new file mode 100644
index 000000000..452895f06
--- /dev/null
+++ b/suites/upgrade/singleton/all/basic-test.yaml
@@ -0,0 +1,32 @@
+roles:
+- - mon.a
+ - mds.0
+ - osd.0
+ - osd.1
+- - mon.b
+ - osd.2
+ - osd.3
+- - client.0
+
+tasks:
+- install:
+ branch: bobtail
+- ceph:
+ conf:
+ mds:
+ debug mds: 20
+ debug ms: 1
+ client:
+ debug ms: 1
+ debug client: 20
+- install.upgrade:
+ all:
+ branch: next
+- ceph.restart:
+- ceph-fuse: [client.0]
+- workunit:
+ branch: next
+ clients:
+ client.0:
+ - suites/dbench.sh
+
diff --git a/suites/upgrade/singleton/all/basic-upgrade.yaml b/suites/upgrade/singleton/all/basic-upgrade.yaml
new file mode 100644
index 000000000..db30f0066
--- /dev/null
+++ b/suites/upgrade/singleton/all/basic-upgrade.yaml
@@ -0,0 +1,25 @@
+roles:
+- - mon.a
+ - mds.0
+ - osd.0
+ - osd.1
+- - mon.b
+ - osd.2
+ - osd.3
+- - client.0
+
+tasks:
+- install:
+ branch: bobtail
+- ceph:
+- install.upgrade:
+ all:
+ branch: next
+- ceph.restart:
+- ceph-fuse: [client.0]
+- workunit:
+ branch: next
+ clients:
+ client.0:
+ - suites/dbench.sh
+
diff --git a/suites/upgrade/testing_9419/% b/suites/upgrade/testing_9419/%
new file mode 100644
index 000000000..e69de29bb
diff --git a/suites/upgrade/testing_9419/0-cluster/start.yaml b/suites/upgrade/testing_9419/0-cluster/start.yaml
new file mode 100644
index 000000000..e3d7f85f9
--- /dev/null
+++ b/suites/upgrade/testing_9419/0-cluster/start.yaml
@@ -0,0 +1,19 @@
+overrides:
+ ceph:
+ conf:
+ mon:
+ mon warn on legacy crush tunables: false
+ log-whitelist:
+ - scrub mismatch
+ - ScrubResult
+roles:
+- - mon.a
+ - mds.a
+ - osd.0
+ - osd.1
+- - mon.b
+ - mon.c
+ - osd.2
+ - osd.3
+- - client.0
+ - client.1
diff --git a/suites/upgrade/testing_9419/1-install-dumpling/dumpling.yaml b/suites/upgrade/testing_9419/1-install-dumpling/dumpling.yaml
new file mode 100644
index 000000000..912ff3d18
--- /dev/null
+++ b/suites/upgrade/testing_9419/1-install-dumpling/dumpling.yaml
@@ -0,0 +1,6 @@
+tasks:
+- install:
+ branch: dumpling
+- print: "**** done dumpling"
+- ceph:
+ fs: xfs
diff --git a/suites/upgrade/testing_9419/2-giant-upgrade/giant.yaml b/suites/upgrade/testing_9419/2-giant-upgrade/giant.yaml
new file mode 100644
index 000000000..45596183b
--- /dev/null
+++ b/suites/upgrade/testing_9419/2-giant-upgrade/giant.yaml
@@ -0,0 +1,20 @@
+tasks:
+ - install.upgrade:
+ client.0:
+ # client.1 will be upgraded as well as it's on the same host as client.0
+ - print: "**** done install.upgrade on clinet.0 and client.1"
+ #- ceph.restart:
+ - install.upgrade:
+ mon.a:
+ mon.b:
+ # osd.0:
+ # osd.1:
+ # osd.2:
+ #- ceph.restart: [mon.a, mon.b, mon.c, mds.a, osd.0, osd.1, osd.2, osd.3]
+ - print: "**** done install.upgrade on mon.a and mon.b same host as ods.0, osd.1, osd.2"
+ - ceph.restart:
+ daemons: [osd.0, osd.1, osd.2]
+ - print: "**** done restart"
+ - sequential:
+ - workload
+ - print: "**** done workload"
diff --git a/suites/upgrade/testing_9419/3-workload/test_rbd_python.yaml b/suites/upgrade/testing_9419/3-workload/test_rbd_python.yaml
new file mode 100644
index 000000000..7e7b1f10a
--- /dev/null
+++ b/suites/upgrade/testing_9419/3-workload/test_rbd_python.yaml
@@ -0,0 +1,8 @@
+workload:
+ sequential:
+ - workunit:
+# branch: dumpling
+ clients:
+ client.0:
+ - rbd/test_librbd_python.sh
+ - print: "**** done rbd/test_librbd_python.sh"
diff --git a/tasks/__init__.py b/tasks/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/teuthology/task/admin_socket.py b/tasks/admin_socket.py
similarity index 97%
rename from teuthology/task/admin_socket.py
rename to tasks/admin_socket.py
index 81d75c723..6fe151a7f 100644
--- a/teuthology/task/admin_socket.py
+++ b/tasks/admin_socket.py
@@ -3,8 +3,9 @@
import json
import logging
import os
+import time
-from ..orchestra import run
+from teuthology.orchestra import run
from teuthology import misc as teuthology
from teuthology.parallel import parallel
@@ -73,13 +74,14 @@ def _socket_command(ctx, remote, socket_path, command, args):
proc = remote.run(
args=[
'sudo',
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'ceph',
'--admin-daemon', socket_path,
] + command.split(' ') + args,
stdout=json_fp,
+ check_status=False,
)
if proc.exitstatus == 0:
break
diff --git a/teuthology/task/apache.conf.template b/tasks/apache.conf.template
similarity index 76%
rename from teuthology/task/apache.conf.template
rename to tasks/apache.conf.template
index 8b21d650d..85744b980 100644
--- a/teuthology/task/apache.conf.template
+++ b/tasks/apache.conf.template
@@ -1,3 +1,6 @@
+
+ LoadModule version_module {mod_path}/mod_version.so
+
LoadModule env_module {mod_path}/mod_env.so
@@ -14,6 +17,18 @@
Listen {port}
ServerName {host}
+= 2.4>
+
+ LoadModule unixd_module {mod_path}/mod_unixd.so
+
+
+ LoadModule authz_core_module {mod_path}/mod_authz_core.so
+
+ User {user}
+ Group {group}
+ {apache24_modconfig}
+
+
ServerRoot {testdir}/apache
ErrorLog {testdir}/archive/apache.{client}/error.log
LogFormat "%h l %u %t \"%r\" %>s %b \"{{Referer}}i\" \"%{{User-agent}}i\"" combined
@@ -21,7 +36,7 @@ CustomLog {testdir}/archive/apache.{client}/access.log combined
PidFile {testdir}/apache/tmp.{client}/apache.pid
DocumentRoot {testdir}/apache/htdocs.{client}
FastCgiIPCDir {testdir}/apache/tmp.{client}/fastcgi_sock
-FastCgiExternalServer {testdir}/apache/htdocs.{client}/rgw.fcgi -socket rgw_sock
+FastCgiExternalServer {testdir}/apache/htdocs.{client}/rgw.fcgi -socket rgw_sock -idle-timeout {idle_timeout}
RewriteEngine On
RewriteRule ^/([a-zA-Z0-9-_.]*)([/]?.*) /rgw.fcgi?page=$1¶ms=$2&%{{QUERY_STRING}} [E=HTTP_AUTHORIZATION:%{{HTTP:Authorization}},L]
diff --git a/teuthology/task/autotest.py b/tasks/autotest.py
similarity index 99%
rename from teuthology/task/autotest.py
rename to tasks/autotest.py
index d1b22c6a4..16221bff9 100644
--- a/teuthology/task/autotest.py
+++ b/tasks/autotest.py
@@ -4,7 +4,7 @@
from teuthology import misc as teuthology
from teuthology.parallel import parallel
-from ..orchestra import run
+from teuthology.orchestra import run
log = logging.getLogger(__name__)
diff --git a/teuthology/task/blktrace.py b/tasks/blktrace.py
similarity index 94%
rename from teuthology/task/blktrace.py
rename to tasks/blktrace.py
index 3b9a7acd3..3cd18575e 100644
--- a/teuthology/task/blktrace.py
+++ b/tasks/blktrace.py
@@ -3,7 +3,7 @@
from teuthology import misc as teuthology
from teuthology import contextutil
-from ..orchestra import run
+from teuthology.orchestra import run
log = logging.getLogger(__name__)
blktrace = '/usr/sbin/blktrace'
@@ -41,7 +41,7 @@ def execute(ctx, config):
'cd',
log_dir,
run.Raw(';'),
- '{tdir}/daemon-helper'.format(tdir=testdir),
+ 'daemon-helper',
daemon_signal,
'sudo',
blktrace,
@@ -50,7 +50,7 @@ def execute(ctx, config):
'-d',
dev,
],
- wait=False,
+ wait=False,
stdin=run.PIPE,
)
procs.append(proc)
diff --git a/tasks/boto.cfg.template b/tasks/boto.cfg.template
new file mode 100644
index 000000000..cdfe8873b
--- /dev/null
+++ b/tasks/boto.cfg.template
@@ -0,0 +1,2 @@
+[Boto]
+http_socket_timeout = {idle_timeout}
diff --git a/teuthology/task/ceph.py b/tasks/ceph.py
similarity index 86%
rename from teuthology/task/ceph.py
rename to tasks/ceph.py
index 4db72943f..34657a6b8 100644
--- a/teuthology/task/ceph.py
+++ b/tasks/ceph.py
@@ -8,98 +8,12 @@
from teuthology import misc as teuthology
from teuthology import contextutil
-from ..orchestra import run
+from teuthology.orchestra import run
import ceph_client as cclient
+from teuthology.orchestra.daemon import DaemonGroup
log = logging.getLogger(__name__)
-class DaemonState(object):
- def __init__(self, remote, role, id_, *command_args, **command_kwargs):
- self.remote = remote
- self.command_args = command_args
- self.command_kwargs = command_kwargs
- self.role = role
- self.id_ = id_
- self.log = command_kwargs.get('logger', log)
- self.proc = None
-
- def stop(self):
- """
- Note: this can raise a run.CommandFailedError,
- run.CommandCrashedError, or run.ConnectionLostError.
- """
- if not self.running():
- self.log.error('tried to stop a non-running daemon')
- return
- self.proc.stdin.close()
- self.log.debug('waiting for process to exit')
- run.wait([self.proc])
- self.proc = None
- self.log.info('Stopped')
-
- def restart(self, *args, **kwargs):
- self.log.info('Restarting')
- if self.proc is not None:
- self.log.debug('stopping old one...')
- self.stop()
- cmd_args = list(self.command_args)
- cmd_args.extend(args)
- cmd_kwargs = self.command_kwargs
- cmd_kwargs.update(kwargs)
- self.proc = self.remote.run(*cmd_args, **cmd_kwargs)
- self.log.info('Started')
-
- def restart_with_args(self, extra_args):
- self.log.info('Restarting')
- if self.proc is not None:
- self.log.debug('stopping old one...')
- self.stop()
- cmd_args = list(self.command_args)
- # we only want to make a temporary mod of the args list
- # so we shallow copy the dict, and deepcopy the args list
- cmd_kwargs = self.command_kwargs.copy()
- from copy import deepcopy
- cmd_kwargs['args'] = deepcopy(self.command_kwargs['args'])
- cmd_kwargs['args'].extend(extra_args)
- self.proc = self.remote.run(*cmd_args, **cmd_kwargs)
- self.log.info('Started')
-
- def signal(self, sig):
- self.proc.stdin.write(struct.pack('!b', sig))
- self.log.info('Sent signal %d', sig)
-
- def running(self):
- return self.proc is not None
-
- def reset(self):
- self.proc = None
-
- def wait_for_exit(self):
- if self.proc:
- run.wait([self.proc])
- self.proc = None
-
-class CephState(object):
- def __init__(self):
- self.daemons = {}
-
- def add_daemon(self, remote, role, id_, *args, **kwargs):
- if role not in self.daemons:
- self.daemons[role] = {}
- if id_ in self.daemons[role]:
- self.daemons[role][id_].stop()
- self.daemons[role][id_] = None
- self.daemons[role][id_] = DaemonState(remote, role, id_, *args, **kwargs)
- self.daemons[role][id_].restart()
-
- def get_daemon(self, role, id_):
- if role not in self.daemons:
- return None
- return self.daemons[role].get(str(id_), None)
-
- def iter_daemons_of_role(self, role):
- return self.daemons.get(role, {}).values()
-
@contextlib.contextmanager
def ceph_log(ctx, config):
@@ -144,52 +58,6 @@ def ceph_log(ctx, config):
finally:
pass
-@contextlib.contextmanager
-def ship_utilities(ctx, config):
- assert config is None
- FILES = ['daemon-helper', 'adjust-ulimits', 'chdir-coredump',
- 'valgrind.supp', 'kcon_most']
- testdir = teuthology.get_testdir(ctx)
- for filename in FILES:
- log.info('Shipping %r...', filename)
- src = os.path.join(os.path.dirname(__file__), filename)
- dst = os.path.join(testdir, filename)
- with file(src, 'rb') as f:
- for rem in ctx.cluster.remotes.iterkeys():
- teuthology.write_file(
- remote=rem,
- path=dst,
- data=f,
- )
- f.seek(0)
- rem.run(
- args=[
- 'chmod',
- 'a=rx',
- '--',
- dst,
- ],
- )
-
- try:
- yield
- finally:
- log.info('Removing shipped files: %s...', ' '.join(FILES))
- filenames = (
- os.path.join(testdir, filename)
- for filename in FILES
- )
- run.wait(
- ctx.cluster.run(
- args=[
- 'rm',
- '-rf',
- '--',
- ] + list(filenames),
- wait=False,
- ),
- )
-
def assign_devs(roles, devs):
return dict(zip(roles, devs))
@@ -222,7 +90,7 @@ def valgrind_post(ctx, config):
valgrind_exception = None
for (proc, remote) in lookup_procs:
- proc.exitstatus.get()
+ proc.wait()
out = proc.stdout.getvalue()
for line in out.split('\n'):
if line == '':
@@ -395,7 +263,7 @@ def cluster(ctx, config):
ctx.cluster.only(firstmon).run(
args=[
'sudo',
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
coverage_dir,
'ceph-authtool',
@@ -406,7 +274,7 @@ def cluster(ctx, config):
ctx.cluster.only(firstmon).run(
args=[
'sudo',
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
coverage_dir,
'ceph-authtool',
@@ -434,7 +302,7 @@ def cluster(ctx, config):
ctx.cluster.only(firstmon).run(
args=[
'sudo',
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
coverage_dir,
'ceph-authtool',
@@ -478,7 +346,7 @@ def cluster(ctx, config):
run.wait(
mons.run(
args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
coverage_dir,
'osdmaptool',
@@ -506,7 +374,7 @@ def cluster(ctx, config):
'-p',
'/var/lib/ceph/mds/ceph-{id}'.format(id=id_),
run.Raw('&&'),
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
coverage_dir,
'sudo',
@@ -581,7 +449,17 @@ def cluster(ctx, config):
],
stdout=StringIO(),
)
- remote.run(args= ['yes', run.Raw('|')] + ['sudo'] + mkfs + [dev])
+
+ try:
+ remote.run(args= ['yes', run.Raw('|')] + ['sudo'] + mkfs + [dev])
+ except run.CommandFailedError:
+ # Newer btfs-tools doesn't prompt for overwrite, use -f
+ if '-f' not in mount_options:
+ mkfs_options.append('-f')
+ mkfs = ['mkfs.%s' % fs] + mkfs_options
+ log.info('%s on %s on %s' % (mkfs, dev, remote))
+ remote.run(args= ['yes', run.Raw('|')] + ['sudo'] + mkfs + [dev])
+
log.info('mount %s on %s -o %s' % (dev, remote,
','.join(mount_options)))
remote.run(
@@ -609,11 +487,10 @@ def cluster(ctx, config):
for id_ in teuthology.roles_of_type(roles_for_host, 'osd'):
remote.run(
args=[
- 'MALLOC_CHECK_=3',
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'sudo',
+ 'adjust-ulimits',
'ceph-coverage',
coverage_dir,
- 'sudo',
'ceph-osd',
'--mkfs',
'--mkkey',
@@ -667,7 +544,7 @@ def cluster(ctx, config):
mons.run(
args=[
'sudo',
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
coverage_dir,
'ceph-authtool',
@@ -694,10 +571,10 @@ def cluster(ctx, config):
)
remote.run(
args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'sudo',
+ 'adjust-ulimits',
'ceph-coverage',
coverage_dir,
- 'sudo',
'ceph-mon',
'--mkfs',
'-i', id_,
@@ -873,11 +750,11 @@ def run_daemon(ctx, config, type_):
num_active += 1
run_cmd = [
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
'ceph-coverage',
coverage_dir,
'sudo',
- '{tdir}/daemon-helper'.format(tdir=testdir),
+ 'adjust-ulimits',
+ 'daemon-helper',
daemon_signal,
]
run_cmd_tail = [
@@ -885,17 +762,19 @@ def run_daemon(ctx, config, type_):
'-f',
'-i', id_]
+ if type_ in config.get('cpu_profile', []):
+ profile_path = '/var/log/ceph/profiling-logger/%s.%s.prof' % (type_, id_)
+ run_cmd.extend([ 'env', 'CPUPROFILE=%s' % profile_path ])
+
if config.get('valgrind') is not None:
valgrind_args = None
if type_ in config['valgrind']:
valgrind_args = config['valgrind'][type_]
if name in config['valgrind']:
valgrind_args = config['valgrind'][name]
- run_cmd.extend(teuthology.get_valgrind_args(testdir, name, valgrind_args))
-
- if type_ in config.get('cpu_profile', []):
- profile_path = '/var/log/ceph/profiling-logger/%s.%s.prof' % (type_, id_)
- run_cmd.extend([ 'env', 'CPUPROFILE=%s' % profile_path ])
+ run_cmd = teuthology.get_valgrind_args(testdir, name,
+ run_cmd,
+ valgrind_args)
run_cmd.extend(run_cmd_tail)
@@ -911,7 +790,8 @@ def run_daemon(ctx, config, type_):
(mon0_remote,) = ctx.cluster.only(firstmon).remotes.keys()
mon0_remote.run(args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'sudo',
+ 'adjust-ulimits',
'ceph-coverage',
coverage_dir,
'ceph',
@@ -1119,7 +999,7 @@ def task(ctx, config):
overrides = ctx.config.get('overrides', {})
teuthology.deep_merge(config, overrides.get('ceph', {}))
- ctx.daemons = CephState()
+ ctx.daemons = DaemonGroup()
testdir = teuthology.get_testdir(ctx)
if config.get('coverage'):
@@ -1137,7 +1017,6 @@ def task(ctx, config):
with contextutil.nested(
lambda: ceph_log(ctx=ctx, config=None),
- lambda: ship_utilities(ctx=ctx, config=None),
lambda: valgrind_post(ctx=ctx, config=config),
lambda: cluster(ctx=ctx, config=dict(
conf=config.get('conf', {}),
diff --git a/teuthology/task/ceph_client.py b/tasks/ceph_client.py
similarity index 92%
rename from teuthology/task/ceph_client.py
rename to tasks/ceph_client.py
index fd4f8cb2e..6e91b9a0c 100644
--- a/teuthology/task/ceph_client.py
+++ b/tasks/ceph_client.py
@@ -1,7 +1,7 @@
import logging
from teuthology import misc as teuthology
-from ..orchestra import run
+from teuthology.orchestra import run
log = logging.getLogger(__name__)
@@ -15,7 +15,7 @@ def create_keyring(ctx):
client_keyring = '/etc/ceph/ceph.client.{id}.keyring'.format(id=id_)
remote.run(
args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
coverage_dir,
'sudo',
diff --git a/teuthology/task/ceph-deploy.py b/tasks/ceph_deploy.py
similarity index 93%
rename from teuthology/task/ceph-deploy.py
rename to tasks/ceph_deploy.py
index 193e6583e..aefefa75a 100644
--- a/teuthology/task/ceph-deploy.py
+++ b/tasks/ceph_deploy.py
@@ -7,8 +7,8 @@
from teuthology import misc as teuthology
from teuthology import contextutil
-import ceph as ceph_fn
-from ..orchestra import run
+from teuthology.task import install as install_fn
+from teuthology.orchestra import run
log = logging.getLogger(__name__)
@@ -188,25 +188,11 @@ def build_ceph_cluster(ctx, config):
if estatus_install != 0:
raise RuntimeError("ceph-deploy: Failed to install ceph")
- mon_no = None
- mon_no = config.get('mon_initial_members')
- if mon_no is not None:
- i = 0
- mon1 = []
- while(i < mon_no):
- mon1.append(mon_node[i])
- i = i + 1
- initial_mons = " ".join(mon1)
- for k in range(mon_no, len(mon_node)):
- mon_create_nodes = './ceph-deploy mon create'+" "+initial_mons+" "+mon_node[k]
- estatus_mon = execute_ceph_deploy(ctx, config, mon_create_nodes)
- if estatus_mon != 0:
- raise RuntimeError("ceph-deploy: Failed to create monitor")
- else:
- mon_create_nodes = './ceph-deploy mon create'+" "+mon_nodes
- estatus_mon = execute_ceph_deploy(ctx, config, mon_create_nodes)
- if estatus_mon != 0:
- raise RuntimeError("ceph-deploy: Failed to create monitors")
+ mon_create_nodes = './ceph-deploy mon create-initial'
+ # If the following fails, it is OK, it might just be that the monitor
+ # are taking way more than a minute/monitor to form quorum, so lets
+ # try the next block which will wait up to 15 minutes to gatherkeys.
+ estatus_mon = execute_ceph_deploy(ctx, config, mon_create_nodes)
estatus_gather = execute_ceph_deploy(ctx, config, gather_keys)
while (estatus_gather != 0):
@@ -423,7 +409,7 @@ def task(ctx, config):
assert isinstance(config['branch'], dict), 'branch must be a dictionary'
with contextutil.nested(
- lambda: ceph_fn.ship_utilities(ctx=ctx, config=None),
+ lambda: install_fn.ship_utilities(ctx=ctx, config=None),
lambda: download_ceph_deploy(ctx=ctx, config=config),
lambda: build_ceph_cluster(ctx=ctx, config=dict(
conf=config.get('conf', {}),
diff --git a/teuthology/task/ceph-fuse.py b/tasks/ceph_fuse.py
similarity index 77%
rename from teuthology/task/ceph-fuse.py
rename to tasks/ceph_fuse.py
index b0a0fe38b..692fab813 100644
--- a/teuthology/task/ceph-fuse.py
+++ b/tasks/ceph_fuse.py
@@ -1,9 +1,11 @@
import contextlib
import logging
import os
+import time
+from cStringIO import StringIO
-from teuthology import misc as teuthology
-from ..orchestra import run
+from teuthology import misc
+from teuthology.orchestra import run
log = logging.getLogger(__name__)
@@ -45,18 +47,18 @@ def task(ctx, config):
log.info('Mounting ceph-fuse clients...')
fuse_daemons = {}
- testdir = teuthology.get_testdir(ctx)
+ testdir = misc.get_testdir(ctx)
if config is None:
config = dict(('client.{id}'.format(id=id_), None)
- for id_ in teuthology.all_roles_of_type(ctx.cluster, 'client'))
+ for id_ in misc.all_roles_of_type(ctx.cluster, 'client'))
elif isinstance(config, list):
config = dict((name, None) for name in config)
overrides = ctx.config.get('overrides', {})
- teuthology.deep_merge(config, overrides.get('ceph-fuse', {}))
+ misc.deep_merge(config, overrides.get('ceph-fuse', {}))
- clients = list(teuthology.get_clients(ctx=ctx, roles=config.keys()))
+ clients = list(misc.get_clients(ctx=ctx, roles=config.keys()))
for id_, remote in clients:
client_config = config.get("client.%s" % id_)
@@ -82,10 +84,10 @@ def task(ctx, config):
run_cmd=[
'sudo',
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
- '{tdir}/daemon-helper'.format(tdir=testdir),
+ 'daemon-helper',
daemon_signal,
]
run_cmd_tail=[
@@ -97,12 +99,11 @@ def task(ctx, config):
]
if client_config.get('valgrind') is not None:
- run_cmd.extend(
- teuthology.get_valgrind_args(
- testdir,
- 'client.{id}'.format(id=id_),
- client_config.get('valgrind'),
- )
+ run_cmd = misc.get_valgrind_args(
+ testdir,
+ 'client.{id}'.format(id=id_),
+ run_cmd,
+ client_config.get('valgrind'),
)
run_cmd.extend(run_cmd_tail)
@@ -117,7 +118,7 @@ def task(ctx, config):
for id_, remote in clients:
mnt = os.path.join(testdir, 'mnt.{id}'.format(id=id_))
- teuthology.wait_until_fuse_mounted(
+ wait_until_fuse_mounted(
remote=remote,
fuse=fuse_daemons[id_],
mountpoint=mnt,
@@ -175,3 +176,27 @@ def task(ctx, config):
mnt,
],
)
+
+
+def wait_until_fuse_mounted(remote, fuse, mountpoint):
+ while True:
+ proc = remote.run(
+ args=[
+ 'stat',
+ '--file-system',
+ '--printf=%T\n',
+ '--',
+ mountpoint,
+ ],
+ stdout=StringIO(),
+ )
+ fstype = proc.stdout.getvalue().rstrip('\n')
+ if fstype == 'fuseblk':
+ break
+ log.debug('ceph-fuse not yet mounted, got fs type {fstype!r}'.format(fstype=fstype))
+
+ # it shouldn't have exited yet; exposes some trivial problems
+ assert not fuse.poll()
+
+ time.sleep(5)
+ log.info('ceph-fuse is mounted on %s', mountpoint)
diff --git a/teuthology/task/ceph_manager.py b/tasks/ceph_manager.py
similarity index 98%
rename from teuthology/task/ceph_manager.py
rename to tasks/ceph_manager.py
index 09a61e731..fbda31567 100644
--- a/teuthology/task/ceph_manager.py
+++ b/tasks/ceph_manager.py
@@ -6,7 +6,7 @@
import json
import threading
from teuthology import misc as teuthology
-from teuthology.task import ceph as ceph_task
+from . import ceph as ceph_task
class Thrasher:
def __init__(self, manager, config, logger=None):
@@ -20,11 +20,11 @@ def __init__(self, manager, config, logger=None):
self.stopping = False
self.logger = logger
self.config = config
- self.revive_timeout = self.config.get("revive_timeout", 75)
+ self.revive_timeout = self.config.get("revive_timeout", 150)
if self.config.get('powercycle'):
self.revive_timeout += 120
self.clean_wait = self.config.get('clean_wait', 0)
- self.minin = self.config.get("min_in", 2)
+ self.minin = self.config.get("min_in", 3)
num_osds = self.in_osds + self.out_osds
self.max_pgs = self.config.get("max_pgs_per_pool_osd", 1200) * num_osds
@@ -324,7 +324,7 @@ def tmp(x):
def raw_cluster_cmd(self, *args):
testdir = teuthology.get_testdir(self.ctx)
ceph_args = [
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'ceph',
@@ -339,7 +339,7 @@ def raw_cluster_cmd(self, *args):
def raw_cluster_cmd_result(self, *args):
testdir = teuthology.get_testdir(self.ctx)
ceph_args = [
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'ceph',
@@ -354,7 +354,7 @@ def raw_cluster_cmd_result(self, *args):
def do_rados(self, remote, cmd):
testdir = teuthology.get_testdir(self.ctx)
pre = [
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'rados',
@@ -412,7 +412,7 @@ def osd_admin_socket(self, osdnum, command, check_status=True):
assert remote is not None
args=[
'sudo',
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'ceph',
@@ -903,7 +903,7 @@ def blackhole_kill_osd(self, osd):
time.sleep(2)
self.ctx.daemons.get_daemon('osd', osd).stop()
- def revive_osd(self, osd, timeout=75):
+ def revive_osd(self, osd, timeout=300):
if self.config.get('powercycle'):
(remote,) = self.ctx.cluster.only('osd.{o}'.format(o=osd)).remotes.iterkeys()
self.log('kill_osd on osd.{o} doing powercycle of {s}'.format(o=osd, s=remote.name))
@@ -916,7 +916,13 @@ def revive_osd(self, osd, timeout=75):
ceph_task.make_admin_daemon_dir(self.ctx, remote)
self.ctx.daemons.get_daemon('osd', osd).reset()
self.ctx.daemons.get_daemon('osd', osd).restart()
- self.wait_run_admin_socket(osd, timeout=timeout)
+ # wait for dump_ops_in_flight; this command doesn't appear
+ # until after the signal handler is installed and it is safe
+ # to stop the osd again without making valgrind leak checks
+ # unhappy. see #5924.
+ self.wait_run_admin_socket(osd,
+ args=['dump_ops_in_flight'],
+ timeout=timeout)
def mark_down_osd(self, osd):
self.raw_cluster_cmd('osd', 'down', str(osd))
diff --git a/teuthology/task/chef.py b/tasks/chef.py
similarity index 92%
rename from teuthology/task/chef.py
rename to tasks/chef.py
index e32bb4b18..47e5e280b 100644
--- a/teuthology/task/chef.py
+++ b/tasks/chef.py
@@ -1,7 +1,7 @@
import logging
-from ..orchestra import run
-from .. import misc
+from teuthology.orchestra import run
+from teuthology import misc
log = logging.getLogger(__name__)
diff --git a/teuthology/task/cifs-mount.py b/tasks/cifs_mount.py
similarity index 97%
rename from teuthology/task/cifs-mount.py
rename to tasks/cifs_mount.py
index ecd61eb44..2ab929bab 100644
--- a/teuthology/task/cifs-mount.py
+++ b/tasks/cifs_mount.py
@@ -3,7 +3,7 @@
import os
from teuthology import misc as teuthology
-from ..orchestra import run
+from teuthology.orchestra import run
log = logging.getLogger(__name__)
@@ -55,7 +55,7 @@ def task(ctx, config):
clients = list(teuthology.get_clients(ctx=ctx, roles=config.keys()))
- from teuthology.task.samba import get_sambas
+ from .samba import get_sambas
samba_roles = ['samba.{id_}'.format(id_=id_) for id_ in teuthology.all_roles_of_type(ctx.cluster, 'samba')]
sambas = list(get_sambas(ctx=ctx, roles=samba_roles))
(ip, port) = sambas[0][1].ssh.get_transport().getpeername()
diff --git a/teuthology/task/cram.py b/tasks/cram.py
similarity index 98%
rename from teuthology/task/cram.py
rename to tasks/cram.py
index 4829b8edd..d8870593a 100644
--- a/teuthology/task/cram.py
+++ b/tasks/cram.py
@@ -3,7 +3,7 @@
from teuthology import misc as teuthology
from teuthology.parallel import parallel
-from ..orchestra import run
+from teuthology.orchestra import run
log = logging.getLogger(__name__)
@@ -113,7 +113,7 @@ def _run_tests(ctx, role):
run.Raw('CEPH_REF={ref}'.format(ref=ceph_ref)),
run.Raw('CEPH_ID="{id}"'.format(id=id_)),
run.Raw('PYTHONPATH="$PYTHONPATH:{tdir}/binary/usr/local/lib/python2.7/dist-packages:{tdir}/binary/usr/local/lib/python2.6/dist-packages"'.format(tdir=testdir)),
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'{tdir}/virtualenv/bin/cram'.format(tdir=testdir),
diff --git a/teuthology/task/die_on_err.py b/tasks/die_on_err.py
similarity index 98%
rename from teuthology/task/die_on_err.py
rename to tasks/die_on_err.py
index 959f4b6b9..0ce922d3d 100644
--- a/teuthology/task/die_on_err.py
+++ b/tasks/die_on_err.py
@@ -1,7 +1,7 @@
import contextlib
import logging
import time
-from ..orchestra import run
+from teuthology.orchestra import run
import ceph_manager
from teuthology import misc as teuthology
diff --git a/teuthology/task/divergent_priors.py b/tasks/divergent_priors.py
similarity index 98%
rename from teuthology/task/divergent_priors.py
rename to tasks/divergent_priors.py
index 18aca5b57..8e9f355ea 100644
--- a/teuthology/task/divergent_priors.py
+++ b/tasks/divergent_priors.py
@@ -3,7 +3,7 @@
import ceph_manager
from teuthology import misc as teuthology
-from teuthology.task_util.rados import rados
+from util.rados import rados
log = logging.getLogger(__name__)
diff --git a/teuthology/task/dump_stuck.py b/tasks/dump_stuck.py
similarity index 100%
rename from teuthology/task/dump_stuck.py
rename to tasks/dump_stuck.py
diff --git a/teuthology/task/filestore_idempotent.py b/tasks/filestore_idempotent.py
similarity index 93%
rename from teuthology/task/filestore_idempotent.py
rename to tasks/filestore_idempotent.py
index fea790a76..c1560fbbf 100644
--- a/teuthology/task/filestore_idempotent.py
+++ b/tasks/filestore_idempotent.py
@@ -1,5 +1,5 @@
import logging
-from ..orchestra import run
+from teuthology.orchestra import run
import random
from teuthology import misc as teuthology
@@ -42,10 +42,10 @@ def task(ctx, config):
'cd', dir,
run.Raw('&&'),
'wget','-q', '-Orun_seed_to.sh',
- 'http://ceph.com/git/?p=ceph.git;a=blob_plain;f=src/test/filestore/run_seed_to.sh;hb=HEAD',
+ 'http://ceph.com/git/?p=ceph.git;a=blob_plain;f=src/test/filestore/run_seed_to.sh;hb=dumpling',
run.Raw('&&'),
'wget','-q', '-Orun_seed_to_range.sh',
- 'http://ceph.com/git/?p=ceph.git;a=blob_plain;f=src/test/filestore/run_seed_to_range.sh;hb=HEAD',
+ 'http://ceph.com/git/?p=ceph.git;a=blob_plain;f=src/test/filestore/run_seed_to_range.sh;hb=dumpling',
run.Raw('&&'),
'chmod', '+x', 'run_seed_to.sh', 'run_seed_to_range.sh',
]);
@@ -59,7 +59,7 @@ def task(ctx, config):
],
wait=False,
check_status=False)
- result = proc.exitstatus.get();
+ result = proc.wait();
if result != 0:
remote.run(
diff --git a/teuthology/task/kclient.py b/tasks/kclient.py
similarity index 95%
rename from teuthology/task/kclient.py
rename to tasks/kclient.py
index 6fec64618..dbde4a7d7 100644
--- a/teuthology/task/kclient.py
+++ b/tasks/kclient.py
@@ -3,6 +3,7 @@
import os
from teuthology import misc as teuthology
+from util.kclient import write_secret_file
log = logging.getLogger(__name__)
@@ -55,7 +56,7 @@ def task(ctx, config):
keyring = '/etc/ceph/ceph.client.{id}.keyring'.format(id=id_)
secret = '{tdir}/data/client.{id}.secret'.format(tdir=testdir, id=id_)
- teuthology.write_secret_file(ctx, remote, 'client.{id}'.format(id=id_),
+ write_secret_file(ctx, remote, 'client.{id}'.format(id=id_),
keyring, secret)
remote.run(
@@ -69,7 +70,7 @@ def task(ctx, config):
remote.run(
args=[
'sudo',
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'/sbin/mount.ceph',
diff --git a/teuthology/task/locktest.py b/tasks/locktest.py
similarity index 97%
rename from teuthology/task/locktest.py
rename to tasks/locktest.py
index 06c845125..46ae6d4ba 100755
--- a/teuthology/task/locktest.py
+++ b/tasks/locktest.py
@@ -1,6 +1,6 @@
import logging
-from ..orchestra import run
+from teuthology.orchestra import run
from teuthology import misc as teuthology
log = logging.getLogger(__name__)
@@ -91,8 +91,8 @@ def task(ctx, config):
wait=False
)
- hostresult = hostproc.exitstatus.get()
- clientresult = clientproc.exitstatus.get()
+ hostresult = hostproc.wait()
+ clientresult = clientproc.wait()
if (hostresult != 0) or (clientresult != 0):
raise Exception("Did not pass locking test!")
log.info('finished locktest executable with results {r} and {s}'. \
diff --git a/teuthology/task/lost_unfound.py b/tasks/lost_unfound.py
similarity index 99%
rename from teuthology/task/lost_unfound.py
rename to tasks/lost_unfound.py
index d7c0fc3c1..87356b7bc 100644
--- a/teuthology/task/lost_unfound.py
+++ b/tasks/lost_unfound.py
@@ -1,7 +1,7 @@
import logging
import ceph_manager
from teuthology import misc as teuthology
-from teuthology.task_util.rados import rados
+from util.rados import rados
log = logging.getLogger(__name__)
diff --git a/teuthology/task/manypools.py b/tasks/manypools.py
similarity index 98%
rename from teuthology/task/manypools.py
rename to tasks/manypools.py
index cf9d5b54d..2d1caf34e 100644
--- a/teuthology/task/manypools.py
+++ b/tasks/manypools.py
@@ -1,5 +1,5 @@
from teuthology import misc as teuthology
-from ..orchestra import run
+from teuthology.orchestra import run
import logging
log = logging.getLogger(__name__)
diff --git a/teuthology/task/mds_thrash.py b/tasks/mds_thrash.py
similarity index 100%
rename from teuthology/task/mds_thrash.py
rename to tasks/mds_thrash.py
diff --git a/teuthology/task/metadata.yaml b/tasks/metadata.yaml
similarity index 100%
rename from teuthology/task/metadata.yaml
rename to tasks/metadata.yaml
diff --git a/teuthology/task/mon_clock_skew_check.py b/tasks/mon_clock_skew_check.py
similarity index 100%
rename from teuthology/task/mon_clock_skew_check.py
rename to tasks/mon_clock_skew_check.py
diff --git a/teuthology/task/mon_recovery.py b/tasks/mon_recovery.py
similarity index 100%
rename from teuthology/task/mon_recovery.py
rename to tasks/mon_recovery.py
diff --git a/teuthology/task/mon_thrash.py b/tasks/mon_thrash.py
similarity index 100%
rename from teuthology/task/mon_thrash.py
rename to tasks/mon_thrash.py
diff --git a/teuthology/task/multibench.py b/tasks/multibench.py
similarity index 100%
rename from teuthology/task/multibench.py
rename to tasks/multibench.py
diff --git a/teuthology/task/object_source_down.py b/tasks/object_source_down.py
similarity index 98%
rename from teuthology/task/object_source_down.py
rename to tasks/object_source_down.py
index 544b88640..ab2cea139 100644
--- a/teuthology/task/object_source_down.py
+++ b/tasks/object_source_down.py
@@ -1,7 +1,7 @@
import logging
import ceph_manager
from teuthology import misc as teuthology
-from teuthology.task_util.rados import rados
+from util.rados import rados
log = logging.getLogger(__name__)
diff --git a/teuthology/task/omapbench.py b/tasks/omapbench.py
similarity index 94%
rename from teuthology/task/omapbench.py
rename to tasks/omapbench.py
index 4b46a632d..93a10b7b7 100644
--- a/teuthology/task/omapbench.py
+++ b/tasks/omapbench.py
@@ -1,7 +1,7 @@
import contextlib
import logging
-from ..orchestra import run
+from teuthology.orchestra import run
from teuthology import misc as teuthology
log = logging.getLogger(__name__)
@@ -53,7 +53,7 @@ def task(ctx, config):
proc = remote.run(
args=[
"/bin/sh", "-c",
- " ".join(['{tdir}/adjust-ulimits',
+ " ".join(['adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage',
'omapbench',
@@ -65,7 +65,7 @@ def task(ctx, config):
'--valsize', str(config.get('valsize',1000)),
'--inc', str(config.get('increment',10)),
'--omaptype', str(config.get('omaptype','uniform'))
- ]).format(tdir=testdir),
+ ]),
],
logger=log.getChild('omapbench.{id}'.format(id=id_)),
stdin=run.PIPE,
diff --git a/teuthology/task/osd_backfill.py b/tasks/osd_backfill.py
similarity index 94%
rename from teuthology/task/osd_backfill.py
rename to tasks/osd_backfill.py
index 28433026c..a91e9d696 100644
--- a/teuthology/task/osd_backfill.py
+++ b/tasks/osd_backfill.py
@@ -11,7 +11,7 @@ def rados_start(ctx, remote, cmd):
log.info("rados %s" % ' '.join(cmd))
testdir = teuthology.get_testdir(ctx)
pre = [
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'rados',
@@ -33,10 +33,10 @@ def task(ctx, config):
'thrashosds task only accepts a dict for configuration'
first_mon = teuthology.get_first_mon(ctx, config)
(mon,) = ctx.cluster.only(first_mon).remotes.iterkeys()
-
+
num_osds = teuthology.num_instances_of_type(ctx.cluster, 'osd')
log.info('num_osds is %s' % num_osds)
- assert num_osds == 3
+ assert num_osds == 3
manager = ceph_manager.CephManager(
mon,
@@ -54,7 +54,7 @@ def task(ctx, config):
# write some data
p = rados_start(ctx, mon, ['-p', 'rbd', 'bench', '15', 'write', '-b', '4096',
'--no-cleanup'])
- err = p.exitstatus.get();
+ err = p.wait();
log.info('err is %d' % err)
# mark osd.0 out to trigger a rebalance/backfill
@@ -82,7 +82,7 @@ def task(ctx, config):
manager.revive_osd(1)
# wait for our writes to complete + succeed
- err = p.exitstatus.get()
+ err = p.wait()
log.info('err is %d' % err)
# cluster must recover
diff --git a/teuthology/task/osd_failsafe_enospc.py b/tasks/osd_failsafe_enospc.py
similarity index 91%
rename from teuthology/task/osd_failsafe_enospc.py
rename to tasks/osd_failsafe_enospc.py
index 92e5af90c..0019b9d3e 100644
--- a/teuthology/task/osd_failsafe_enospc.py
+++ b/tasks/osd_failsafe_enospc.py
@@ -3,8 +3,8 @@
import time
import ceph_manager
-from ..orchestra import run
-from teuthology.task_util.rados import rados
+from teuthology.orchestra import run
+from util.rados import rados
from teuthology import misc as teuthology
log = logging.getLogger(__name__)
@@ -60,7 +60,7 @@ def task(ctx, config):
proc = mon.run(
args=[
- '{tdir}/daemon-helper'.format(tdir=teuthology.get_testdir(ctx)),
+ 'daemon-helper',
'kill',
'ceph', '-w'
],
@@ -73,7 +73,7 @@ def task(ctx, config):
time.sleep(sleep_time)
proc.stdin.close() # causes daemon-helper send SIGKILL to ceph -w
- proc.exitstatus.get()
+ proc.wait()
lines = proc.stdout.getvalue().split('\n')
@@ -87,7 +87,7 @@ def task(ctx, config):
proc = mon.run(
args=[
- '{tdir}/daemon-helper'.format(tdir=teuthology.get_testdir(ctx)),
+ 'daemon-helper',
'kill',
'ceph', '-w'
],
@@ -100,7 +100,7 @@ def task(ctx, config):
time.sleep(sleep_time)
proc.stdin.close() # causes daemon-helper send SIGKILL to ceph -w
- proc.exitstatus.get()
+ proc.wait()
lines = proc.stdout.getvalue().split('\n')
@@ -128,7 +128,7 @@ def task(ctx, config):
proc = mon.run(
args=[
- '{tdir}/daemon-helper'.format(tdir=teuthology.get_testdir(ctx)),
+ 'daemon-helper',
'kill',
'ceph', '-w'
],
@@ -139,7 +139,7 @@ def task(ctx, config):
time.sleep(sleep_time)
proc.stdin.close() # causes daemon-helper send SIGKILL to ceph -w
- proc.exitstatus.get()
+ proc.wait()
lines = proc.stdout.getvalue().split('\n')
@@ -156,7 +156,7 @@ def task(ctx, config):
proc = mon.run(
args=[
- '{tdir}/daemon-helper'.format(tdir=teuthology.get_testdir(ctx)),
+ 'daemon-helper',
'kill',
'ceph', '-w'
],
@@ -169,7 +169,7 @@ def task(ctx, config):
time.sleep(sleep_time)
proc.stdin.close() # causes daemon-helper send SIGKILL to ceph -w
- proc.exitstatus.get()
+ proc.wait()
lines = proc.stdout.getvalue().split('\n')
@@ -186,7 +186,7 @@ def task(ctx, config):
proc = mon.run(
args=[
- '{tdir}/daemon-helper'.format(tdir=teuthology.get_testdir(ctx)),
+ 'daemon-helper',
'kill',
'ceph', '-w'
],
@@ -197,7 +197,7 @@ def task(ctx, config):
time.sleep(sleep_time)
proc.stdin.close() # causes daemon-helper send SIGKILL to ceph -w
- proc.exitstatus.get()
+ proc.wait()
lines = proc.stdout.getvalue().split('\n')
diff --git a/teuthology/task/osd_recovery.py b/tasks/osd_recovery.py
similarity index 96%
rename from teuthology/task/osd_recovery.py
rename to tasks/osd_recovery.py
index d813a6782..b192c18cd 100644
--- a/teuthology/task/osd_recovery.py
+++ b/tasks/osd_recovery.py
@@ -10,7 +10,7 @@
def rados_start(testdir, remote, cmd):
log.info("rados %s" % ' '.join(cmd))
pre = [
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'rados',
@@ -33,10 +33,10 @@ def task(ctx, config):
testdir = teuthology.get_testdir(ctx)
first_mon = teuthology.get_first_mon(ctx, config)
(mon,) = ctx.cluster.only(first_mon).remotes.iterkeys()
-
+
num_osds = teuthology.num_instances_of_type(ctx.cluster, 'osd')
log.info('num_osds is %s' % num_osds)
- assert num_osds == 3
+ assert num_osds == 3
manager = ceph_manager.CephManager(
mon,
@@ -76,7 +76,7 @@ def task(ctx, config):
manager.revive_osd(1)
# wait for our writes to complete + succeed
- err = p.exitstatus.get()
+ err = p.wait()
log.info('err is %d' % err)
# cluster must repeer
@@ -86,7 +86,7 @@ def task(ctx, config):
# write some more (make sure osd.2 really is divergent)
p = rados_start(testdir, mon, ['-p', 'rbd', 'bench', '15', 'write', '-b', '4096'])
- p.exitstatus.get();
+ p.wait();
# revive divergent osd
manager.revive_osd(2)
@@ -153,13 +153,13 @@ def test_incomplete_pgs(ctx, config):
p = rados_start(testdir, mon,
['-p', 'rbd', 'bench', '60', 'write', '-b', '1',
'--no-cleanup'])
- p.exitstatus.get()
+ p.wait()
# few objects in metadata pool (with pg log, normal recovery)
for f in range(1, 20):
p = rados_start(testdir, mon, ['-p', 'metadata', 'put',
'foo.%d' % f, '/etc/passwd'])
- p.exitstatus.get()
+ p.wait()
# move it back
manager.raw_cluster_cmd('osd', 'in', '0', '1')
diff --git a/teuthology/task/peer.py b/tasks/peer.py
similarity index 98%
rename from teuthology/task/peer.py
rename to tasks/peer.py
index 3fb8b4b6f..f6b410d82 100644
--- a/teuthology/task/peer.py
+++ b/tasks/peer.py
@@ -3,7 +3,7 @@
import ceph_manager
from teuthology import misc as teuthology
-from teuthology.task_util.rados import rados
+from util.rados import rados
log = logging.getLogger(__name__)
diff --git a/teuthology/task/peering_speed_test.py b/tasks/peering_speed_test.py
similarity index 100%
rename from teuthology/task/peering_speed_test.py
rename to tasks/peering_speed_test.py
diff --git a/teuthology/task/qemu.py b/tasks/qemu.py
similarity index 97%
rename from teuthology/task/qemu.py
rename to tasks/qemu.py
index f69e851ae..b0bc23f64 100644
--- a/teuthology/task/qemu.py
+++ b/tasks/qemu.py
@@ -6,8 +6,8 @@
from teuthology import misc as teuthology
from teuthology import contextutil
-from teuthology.task import rbd
-from ..orchestra import run
+from tasks import rbd
+from teuthology.orchestra import run
log = logging.getLogger(__name__)
@@ -162,12 +162,12 @@ def run_qemu(ctx, config):
base_file = '{tdir}/qemu/base.{client}.qcow2'.format(tdir=testdir, client=client)
args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
- '{tdir}/daemon-helper'.format(tdir=testdir),
+ 'daemon-helper',
'term',
- 'kvm', '-enable-kvm', '-nographic',
+ 'qemu-system-x86_64', '-enable-kvm', '-nographic',
'-m', str(client_config.get('memory', DEFAULT_MEM)),
# base OS device
'-drive',
@@ -194,7 +194,7 @@ def run_qemu(ctx, config):
for i in xrange(client_config.get('num_rbd', DEFAULT_NUM_RBD)):
args.extend([
'-drive',
- 'file=rbd:rbd/{img}:id={id},format=rbd,if=virtio,cache={cachemode}'.format(
+ 'file=rbd:rbd/{img}:id={id},format=raw,if=virtio,cache={cachemode}'.format(
img='{client}.{num}'.format(client=client, num=i),
id=client[len('client.'):],
cachemode=cachemode,
diff --git a/teuthology/task/rados.py b/tasks/rados.py
similarity index 98%
rename from teuthology/task/rados.py
rename to tasks/rados.py
index 7bef3e02c..43a7c54de 100644
--- a/teuthology/task/rados.py
+++ b/tasks/rados.py
@@ -4,7 +4,7 @@
from ceph_manager import CephManager
from teuthology import misc as teuthology
-from ..orchestra import run
+from teuthology.orchestra import run
log = logging.getLogger(__name__)
@@ -57,7 +57,7 @@ def task(ctx, config):
op_weights = config.get('op_weights', {})
testdir = teuthology.get_testdir(ctx)
args = [
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'ceph_test_rados',
diff --git a/teuthology/task/radosbench.py b/tasks/radosbench.py
similarity index 86%
rename from teuthology/task/radosbench.py
rename to tasks/radosbench.py
index 420fa101f..f7dd30035 100644
--- a/teuthology/task/radosbench.py
+++ b/tasks/radosbench.py
@@ -1,7 +1,7 @@
import contextlib
import logging
-from ..orchestra import run
+from teuthology.orchestra import run
from teuthology import misc as teuthology
log = logging.getLogger(__name__)
@@ -45,13 +45,13 @@ def task(ctx, config):
proc = remote.run(
args=[
"/bin/sh", "-c",
- " ".join(['{tdir}/adjust-ulimits',
+ " ".join(['adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage',
'rados',
'--name', role,
'mkpool', str(config.get('pool', 'data'))
- ]).format(tdir=testdir),
+ ]),
],
logger=log.getChild('radosbench.{id}'.format(id=id_)),
stdin=run.PIPE,
@@ -62,14 +62,14 @@ def task(ctx, config):
proc = remote.run(
args=[
"/bin/sh", "-c",
- " ".join(['{tdir}/adjust-ulimits',
+ " ".join(['adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage',
'rados',
'--name', role,
- '-p' , str(config.get('pool', 'data')),
+ '-p', str(config.get('pool', 'data')),
'bench', str(config.get('time', 360)), 'write',
- ]).format(tdir=testdir),
+ ]),
],
logger=log.getChild('radosbench.{id}'.format(id=id_)),
stdin=run.PIPE,
@@ -87,13 +87,13 @@ def task(ctx, config):
proc = remote.run(
args=[
"/bin/sh", "-c",
- " ".join(['{tdir}/adjust-ulimits',
+ " ".join(['adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage',
'rados',
'--name', role,
'rmpool', str(config.get('pool', 'data'))
- ]).format(tdir=testdir),
+ ]),
],
logger=log.getChild('radosbench.{id}'.format(id=id_)),
stdin=run.PIPE,
diff --git a/teuthology/task/radosgw-admin.py b/tasks/radosgw_admin.py
similarity index 99%
rename from teuthology/task/radosgw-admin.py
rename to tasks/radosgw_admin.py
index 8f7e97bf5..6e5f52ccf 100644
--- a/teuthology/task/radosgw-admin.py
+++ b/tasks/radosgw_admin.py
@@ -15,11 +15,11 @@
import boto.s3.connection
import boto.s3.acl
-import teuthology.task_util.rgw as rgw_utils
+import util.rgw as rgw_utils
from teuthology import misc as teuthology
from teuthology import contextutil
-from teuthology.task_util.rgw import rgwadmin
+from util.rgw import rgwadmin
log = logging.getLogger(__name__)
diff --git a/teuthology/task/radosgw-admin-rest.py b/tasks/radosgw_admin_rest.py
similarity index 99%
rename from teuthology/task/radosgw-admin-rest.py
rename to tasks/radosgw_admin_rest.py
index 4c57a00fe..25b04a37d 100644
--- a/teuthology/task/radosgw-admin-rest.py
+++ b/tasks/radosgw_admin_rest.py
@@ -31,7 +31,7 @@ def rgwadmin(ctx, client, cmd):
log.info('radosgw-admin: %s' % cmd)
testdir = teuthology.get_testdir(ctx)
pre = [
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'radosgw-admin',
diff --git a/teuthology/task/radosgw-agent.py b/tasks/radosgw_agent.py
similarity index 95%
rename from teuthology/task/radosgw-agent.py
rename to tasks/radosgw_agent.py
index a6661b480..9dd2eebcf 100644
--- a/teuthology/task/radosgw-agent.py
+++ b/tasks/radosgw_agent.py
@@ -2,9 +2,9 @@
import logging
import argparse
-from ..orchestra import run
+from teuthology.orchestra import run
from teuthology import misc as teuthology
-import teuthology.task_util.rgw as rgw_utils
+import util.rgw as rgw_utils
log = logging.getLogger(__name__)
@@ -39,7 +39,7 @@ def run_radosgw_agent(ctx, config):
remote.run(
args=[
'cd', testdir, run.Raw('&&'),
- 'git', 'clone',
+ 'git', 'clone',
'-b', branch,
'https://github.com/ceph/radosgw-agent.git',
'radosgw-agent.{client}'.format(client=client),
@@ -74,7 +74,7 @@ def run_radosgw_agent(ctx, config):
port = cconf.get('port', 8000)
daemon_name = '{host}.{port}.syncdaemon'.format(host=remote.name, port=port)
in_args=[
- '{tdir}/daemon-helper'.format(tdir=testdir), 'kill',
+ 'daemon-helper', 'kill',
'{tdir}/radosgw-agent.{client}/radosgw-agent'.format(tdir=testdir,
client=client),
'-v',
@@ -96,7 +96,7 @@ def run_radosgw_agent(ctx, config):
# the test server and full/incremental flags are mutually exclusive
if sync_scope is None:
in_args.append('--test-server-host')
- in_args.append('0.0.0.0')
+ in_args.append('0.0.0.0')
in_args.append('--test-server-port')
in_args.append(str(port))
log.debug('Starting a sync test server on {client}'.format(client=client))
@@ -124,15 +124,15 @@ def task(ctx, config):
to 0.0.0.0. Port defaults to 8000. This must be run on clients
that have the correct zone root pools and rgw zone set in
ceph.conf, or the task cannot read the region information from the
- cluster.
+ cluster.
By default, this task will start an HTTP server that will trigger full
- or incremental syncs based on requests made to it.
+ or incremental syncs based on requests made to it.
Alternatively, a single full sync can be triggered by
specifying 'sync-scope: full' or a loop of incremental syncs can be triggered
by specifying 'sync-scope: incremental' (the loop will sleep
'--incremental-sync-delay' seconds between each sync, default is 20 seconds).
-
+
An example::
tasks:
@@ -183,7 +183,7 @@ def task(ctx, config):
for client, proc in procs:
log.info("shutting down sync agent on %s", client)
proc.stdin.close()
- proc.exitstatus.get()
+ proc.wait()
finally:
for client, proc in procs:
ctx.cluster.only(client).run(
diff --git a/teuthology/task/rbd.py b/tasks/rbd.py
similarity index 97%
rename from teuthology/task/rbd.py
rename to tasks/rbd.py
index d107c6f47..b791a2a17 100644
--- a/teuthology/task/rbd.py
+++ b/tasks/rbd.py
@@ -3,7 +3,7 @@
import os
from cStringIO import StringIO
-from ..orchestra import run
+from teuthology.orchestra import run
from teuthology import misc as teuthology
from teuthology import contextutil
from teuthology.parallel import parallel
@@ -54,7 +54,7 @@ def create_image(ctx, config):
log.info('Creating image {name} with size {size}'.format(name=name,
size=size))
args = [
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage'.format(tdir=testdir),
'{tdir}/archive/coverage'.format(tdir=testdir),
'rbd',
@@ -79,7 +79,7 @@ def create_image(ctx, config):
(remote,) = ctx.cluster.only(role).remotes.keys()
remote.run(
args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'rbd',
@@ -166,7 +166,7 @@ def dev_create(ctx, config):
remote.run(
args=[
'sudo',
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'rbd',
@@ -193,7 +193,7 @@ def dev_create(ctx, config):
args=[
'LD_LIBRARY_PATH={tdir}/binary/usr/local/lib'.format(tdir=testdir),
'sudo',
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'rbd',
@@ -418,7 +418,7 @@ def run_xfstests_one_client(ctx, role, properties):
# readlink -f in order to get their canonical
# pathname (so it matches what the kernel remembers).
args = [
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'/usr/bin/sudo',
@@ -496,10 +496,10 @@ def xfstests(ctx, config):
properties = {}
test_image = properties.get('test_image', 'test_image.{role}'.format(role=role))
- test_size = properties.get('test_size', 1200)
+ test_size = properties.get('test_size', 2000) # 2G
test_fmt = properties.get('test_format', 1)
scratch_image = properties.get('scratch_image', 'scratch_image.{role}'.format(role=role))
- scratch_size = properties.get('scratch_size', 1200)
+ scratch_size = properties.get('scratch_size', 10000) # 10G
scratch_fmt = properties.get('scratch_format', 1)
images_config[role] = dict(
diff --git a/teuthology/task/rbd_fsx.py b/tasks/rbd_fsx.py
similarity index 96%
rename from teuthology/task/rbd_fsx.py
rename to tasks/rbd_fsx.py
index d841c2ecd..97d285087 100644
--- a/teuthology/task/rbd_fsx.py
+++ b/tasks/rbd_fsx.py
@@ -42,7 +42,7 @@ def _run_one_client(ctx, config, role):
(remote,) = ctx.cluster.only(role).remotes.iterkeys()
remote.run(
args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'ceph_test_librbd_fsx',
diff --git a/teuthology/task/recovery_bench.py b/tasks/recovery_bench.py
similarity index 96%
rename from teuthology/task/recovery_bench.py
rename to tasks/recovery_bench.py
index 9026716bc..569bba84c 100644
--- a/teuthology/task/recovery_bench.py
+++ b/tasks/recovery_bench.py
@@ -104,7 +104,7 @@ def do_bench(self):
# create the objects
osd_remote.run(
args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'smalliobench'.format(tdir=testdir),
@@ -120,7 +120,7 @@ def do_bench(self):
log.info('non-recovery (baseline)')
p = osd_remote.run(
args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'smalliobench',
@@ -142,7 +142,7 @@ def do_bench(self):
log.info('recovery active')
p = osd_remote.run(
args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'smalliobench',
diff --git a/teuthology/task/repair_test.py b/tasks/repair_test.py
similarity index 100%
rename from teuthology/task/repair_test.py
rename to tasks/repair_test.py
diff --git a/teuthology/task/rest-api.py b/tasks/rest_api.py
similarity index 95%
rename from teuthology/task/rest-api.py
rename to tasks/rest_api.py
index 252d050bb..4c2eeb3a3 100644
--- a/teuthology/task/rest-api.py
+++ b/tasks/rest_api.py
@@ -3,15 +3,15 @@
from teuthology import misc as teuthology
from teuthology import contextutil
-from ..orchestra import run
-from teuthology.task.ceph import CephState
+from teuthology.orchestra import run
+from tasks.ceph import DaemonGroup
log = logging.getLogger(__name__)
@contextlib.contextmanager
def run_rest_api_daemon(ctx, api_clients):
if not hasattr(ctx, 'daemons'):
- ctx.daemons = CephState()
+ ctx.daemons = DaemonGroup()
remotes = ctx.cluster.only(teuthology.is_type('client')).remotes
testdir = teuthology.get_testdir(ctx)
coverage_dir = '{tdir}/archive/coverage'.format(tdir=testdir)
@@ -21,7 +21,7 @@ def run_rest_api_daemon(ctx, api_clients):
id_ = whole_id_[len('clients'):]
run_cmd = [
'sudo',
- '{tdir}/daemon-helper'.format(tdir=testdir),
+ 'daemon-helper',
'kill',
'ceph-rest-api',
'-n',
@@ -98,7 +98,7 @@ def task(ctx, config):
rems.run(
args=[
'sudo',
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
coverage_dir,
'ceph-authtool',
diff --git a/teuthology/task/restart.py b/tasks/restart.py
similarity index 97%
rename from teuthology/task/restart.py
rename to tasks/restart.py
index c06b76d28..636522c4b 100644
--- a/teuthology/task/restart.py
+++ b/tasks/restart.py
@@ -4,7 +4,7 @@
from teuthology import misc as teuthology
from teuthology.orchestra import run as tor
-from ..orchestra import run
+from teuthology.orchestra import run
log = logging.getLogger(__name__)
def restart_daemon(ctx, config, role, id_, *args):
@@ -112,7 +112,7 @@ def task(ctx, config):
env_arg = '{var}={val}'.format(var=var, val=quoted_val)
args.append(run.Raw(env_arg))
args.extend([
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'{srcdir}/{c}'.format(
@@ -144,7 +144,7 @@ def task(ctx, config):
proc.stdin.writelines(['restarted\n'])
proc.stdin.flush()
try:
- proc.exitstatus.get()
+ proc.wait()
except tor.CommandFailedError:
raise Exception('restart task got non-zero exit status from script: {s}'.format(s=c))
finally:
diff --git a/teuthology/task/rgw.py b/tasks/rgw.py
similarity index 93%
rename from teuthology/task/rgw.py
rename to tasks/rgw.py
index 47d589d61..cd53989b5 100644
--- a/teuthology/task/rgw.py
+++ b/tasks/rgw.py
@@ -5,11 +5,12 @@
from cStringIO import StringIO
-from ..orchestra import run
+from teuthology.orchestra import run
from teuthology import misc as teuthology
from teuthology import contextutil
-from teuthology.task_util.rgw import rgwadmin
-from teuthology.task_util.rados import rados
+from util.rgw import rgwadmin
+from util.rados import rados
+import argparse
log = logging.getLogger(__name__)
@@ -67,15 +68,28 @@ def ship_config(ctx, config, role_endpoints):
testdir = teuthology.get_testdir(ctx)
log.info('Shipping apache config and rgw.fcgi...')
src = os.path.join(os.path.dirname(__file__), 'apache.conf.template')
- for client in config.iterkeys():
+ for client, conf in config.iteritems():
+ if not conf:
+ conf = {}
(remote,) = ctx.cluster.only(client).remotes.keys()
system_type = teuthology.get_system_type(remote)
+ idle_timeout = conf.get('idle_timeout', ctx.rgw.default_idle_timeout)
if system_type == 'deb':
mod_path = '/usr/lib/apache2/modules'
print_continue = 'on'
+ user = 'www-data'
+ group = 'www-data'
+ apache24_modconfig = '''
+ IncludeOptional /etc/apache2/mods-available/mpm_event.conf
+ IncludeOptional /etc/apache2/mods-available/mpm_event.load
+'''
else:
mod_path = '/usr/lib64/httpd/modules'
print_continue = 'off'
+ user = 'apache'
+ group = 'apache'
+ apache24_modconfig = \
+ 'IncludeOptional /etc/httpd/conf.modules.d/00-mpm.conf'
host, port = role_endpoints[client]
with file(src, 'rb') as f:
conf = f.read().format(
@@ -85,6 +99,10 @@ def ship_config(ctx, config, role_endpoints):
host=host,
port=port,
client=client,
+ idle_timeout=idle_timeout,
+ user=user,
+ group=group,
+ apache24_modconfig=apache24_modconfig,
)
teuthology.write_file(
remote=remote,
@@ -145,10 +163,10 @@ def start_rgw(ctx, config):
log.info('client {client} is id {id}'.format(client=client, id=id_))
run_cmd=[
'sudo',
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
- '{tdir}/daemon-helper'.format(tdir=testdir),
+ 'daemon-helper',
'term',
]
run_cmd_tail=[
@@ -176,12 +194,11 @@ def start_rgw(ctx, config):
run.Raw('2>&1'),
]
- run_cmd.extend(
- teuthology.get_valgrind_args(
- testdir,
- client,
- client_config.get('valgrind')
- )
+ run_cmd = teuthology.get_valgrind_args(
+ testdir,
+ client,
+ run_cmd,
+ client_config.get('valgrind')
)
run_cmd.extend(run_cmd_tail)
@@ -223,8 +240,8 @@ def start_apache(ctx, config):
apache_name = '/usr/sbin/httpd'
proc = remote.run(
args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
- '{tdir}/daemon-helper'.format(tdir=testdir),
+ 'adjust-ulimits',
+ 'daemon-helper',
'kill',
apache_name,
'-X',
@@ -331,7 +348,7 @@ def fill_in_endpoints(region_info, role_zones, role_endpoints):
region, zone, zone_info, _ = role_zones[role]
host, port = role_endpoints[role]
endpoint = 'http://{host}:{port}/'.format(host=host, port=port)
- # check if the region specified under client actually exists
+ # check if the region specified under client actually exists
# in region_info (it should, if properly configured).
# If not, throw a reasonable error
if region not in region_info:
@@ -537,8 +554,9 @@ def task(ctx, config):
rgw region: bar
rgw zone: bar-secondary
rgw region root pool: .rgw.rroot.bar
- rgw zone root pool: .rgw.zroot.bar-secondary
+ rgw zone root pool: .rgw.zroot.bar-secondary
- rgw:
+ default_idle_timeout: 30
regions:
foo:
api name: api_name # default: region name
@@ -582,6 +600,13 @@ def task(ctx, config):
role_endpoints = assign_ports(ctx, config)
+ ctx.rgw = argparse.Namespace()
+
+ ctx.rgw.default_idle_timeout = 30
+ if 'default_idle_timeout' in config:
+ ctx.rgw.default_idle_timeout = int(config['default_idle_timeout'])
+ del config['default_idle_timeout']
+
with contextutil.nested(
lambda: create_dirs(ctx=ctx, config=config),
lambda: configure_regions_and_zones(
diff --git a/teuthology/task/rgw-logsocket.py b/tasks/rgw_logsocket.py
similarity index 100%
rename from teuthology/task/rgw-logsocket.py
rename to tasks/rgw_logsocket.py
diff --git a/teuthology/task/s3readwrite.py b/tasks/s3readwrite.py
similarity index 97%
rename from teuthology/task/s3readwrite.py
rename to tasks/s3readwrite.py
index b2ad6f9a0..0c12bec18 100644
--- a/teuthology/task/s3readwrite.py
+++ b/tasks/s3readwrite.py
@@ -9,8 +9,8 @@
from teuthology import misc as teuthology
from teuthology import contextutil
-from ..orchestra import run
-from ..orchestra.connection import split_user
+from teuthology.orchestra import run
+from teuthology.orchestra.connection import split_user
log = logging.getLogger(__name__)
@@ -72,7 +72,7 @@ def create_users(ctx, config):
users = {'s3': 'foo'}
cached_client_user_names = dict()
for client in config['clients']:
- cached_client_user_names[client] = dict()
+ cached_client_user_names[client] = dict()
s3tests_conf = config['s3tests_conf'][client]
s3tests_conf.setdefault('readwrite', {})
s3tests_conf['readwrite'].setdefault('bucket', 'rwtest-' + client + '-{random}-')
@@ -86,13 +86,13 @@ def create_users(ctx, config):
rwconf['files'].setdefault('stddev', 500)
for section, user in users.iteritems():
_config_user(s3tests_conf, section, '{user}.{client}'.format(user=user, client=client))
- log.debug('creating user {user} on {client}'.format(user=s3tests_conf[section]['user_id'],
+ log.debug('creating user {user} on {client}'.format(user=s3tests_conf[section]['user_id'],
client=client))
- # stash the 'delete_user' flag along with user name for easier cleanup
+ # stash the 'delete_user' flag along with user name for easier cleanup
delete_this_user = True
if 'delete_user' in s3tests_conf['s3']:
- delete_this_user = s3tests_conf['s3']['delete_user']
+ delete_this_user = s3tests_conf['s3']['delete_user']
log.debug('delete_user set to {flag} for {client}'.format(flag=delete_this_user,client=client))
cached_client_user_names[client][section+user] = (s3tests_conf[section]['user_id'], delete_this_user)
@@ -103,7 +103,7 @@ def create_users(ctx, config):
else:
ctx.cluster.only(client).run(
args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'radosgw-admin',
@@ -126,7 +126,7 @@ def create_users(ctx, config):
if delete_this_user:
ctx.cluster.only(client).run(
args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'radosgw-admin',
diff --git a/teuthology/task/s3roundtrip.py b/tasks/s3roundtrip.py
similarity index 97%
rename from teuthology/task/s3roundtrip.py
rename to tasks/s3roundtrip.py
index 100d5ef38..207f88354 100644
--- a/teuthology/task/s3roundtrip.py
+++ b/tasks/s3roundtrip.py
@@ -9,8 +9,8 @@
from teuthology import misc as teuthology
from teuthology import contextutil
-from ..orchestra import run
-from ..orchestra.connection import split_user
+from teuthology.orchestra import run
+from teuthology.orchestra.connection import split_user
log = logging.getLogger(__name__)
@@ -71,7 +71,7 @@ def create_users(ctx, config):
_config_user(s3tests_conf, section, '{user}.{client}'.format(user=user, client=client))
ctx.cluster.only(client).run(
args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'radosgw-admin',
@@ -92,7 +92,7 @@ def create_users(ctx, config):
uid = '{user}.{client}'.format(user=user, client=client)
ctx.cluster.only(client).run(
args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'radosgw-admin',
diff --git a/teuthology/task/s3tests.py b/tasks/s3tests.py
similarity index 83%
rename from teuthology/task/s3tests.py
rename to tasks/s3tests.py
index 4d2c40912..519dbbb01 100644
--- a/teuthology/task/s3tests.py
+++ b/tasks/s3tests.py
@@ -9,8 +9,8 @@
from teuthology import misc as teuthology
from teuthology import contextutil
-from ..orchestra import run
-from ..orchestra.connection import split_user
+from teuthology.orchestra import run
+from teuthology.orchestra.connection import split_user
log = logging.getLogger(__name__)
@@ -78,7 +78,7 @@ def create_users(ctx, config):
_config_user(s3tests_conf, section, '{user}.{client}'.format(user=user, client=client))
ctx.cluster.only(client).run(
args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'radosgw-admin',
@@ -99,7 +99,7 @@ def create_users(ctx, config):
uid = '{user}.{client}'.format(user=user, client=client)
ctx.cluster.only(client).run(
args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'radosgw-admin',
@@ -146,7 +146,34 @@ def configure(ctx, config):
path='{tdir}/archive/s3-tests.{client}.conf'.format(tdir=testdir, client=client),
data=conf_fp.getvalue(),
)
- yield
+
+ log.info('Configuring boto...')
+ boto_src = os.path.join(os.path.dirname(__file__), 'boto.cfg.template')
+ for client, properties in config['clients'].iteritems():
+ with file(boto_src, 'rb') as f:
+ (remote,) = ctx.cluster.only(client).remotes.keys()
+ conf = f.read().format(
+ idle_timeout=config.get('idle_timeout', 30)
+ )
+ teuthology.write_file(
+ remote=remote,
+ path='{tdir}/boto.cfg'.format(tdir=testdir),
+ data=conf,
+ )
+
+ try:
+ yield
+
+ finally:
+ log.info('Cleaning up boto...')
+ for client, properties in config['clients'].iteritems():
+ (remote,) = ctx.cluster.only(client).remotes.keys()
+ remote.run(
+ args=[
+ 'rm',
+ '{tdir}/boto.cfg'.format(tdir=testdir),
+ ],
+ )
@contextlib.contextmanager
def run_tests(ctx, config):
@@ -154,13 +181,14 @@ def run_tests(ctx, config):
testdir = teuthology.get_testdir(ctx)
for client, client_config in config.iteritems():
args = [
- 'S3TEST_CONF={tdir}/archive/s3-tests.{client}.conf'.format(tdir=testdir, client=client),
- '{tdir}/s3-tests/virtualenv/bin/nosetests'.format(tdir=testdir),
- '-w',
- '{tdir}/s3-tests'.format(tdir=testdir),
- '-v',
- '-a', '!fails_on_rgw',
- ]
+ 'S3TEST_CONF={tdir}/archive/s3-tests.{client}.conf'.format(tdir=testdir, client=client),
+ 'BOTO_CONFIG={tdir}/boto.cfg'.format(tdir=testdir),
+ '{tdir}/s3-tests/virtualenv/bin/nosetests'.format(tdir=testdir),
+ '-w',
+ '{tdir}/s3-tests'.format(tdir=testdir),
+ '-v',
+ '-a', '!fails_on_rgw',
+ ]
if client_config is not None and 'extra_args' in client_config:
args.extend(client_config['extra_args'])
@@ -188,7 +216,7 @@ def task(ctx, config):
- rgw: [client.0]
- s3tests: [client.0]
- To run against a server on client.1::
+ To run against a server on client.1 and increase the boto timeout to 10m::
tasks:
- ceph:
@@ -196,6 +224,7 @@ def task(ctx, config):
- s3tests:
client.0:
rgw_server: client.1
+ idle_timeout: 600
To pass extra arguments to nose (e.g. to run a certain test)::
diff --git a/teuthology/task/samba.py b/tasks/samba.py
similarity index 97%
rename from teuthology/task/samba.py
rename to tasks/samba.py
index d136dcd44..9f15bd821 100644
--- a/teuthology/task/samba.py
+++ b/tasks/samba.py
@@ -3,7 +3,7 @@
import sys
from teuthology import misc as teuthology
-from ..orchestra import run
+from teuthology.orchestra import run
log = logging.getLogger(__name__)
@@ -80,9 +80,9 @@ def task(ctx, config):
testdir = teuthology.get_testdir(ctx)
- from teuthology.task.ceph import CephState
+ from tasks.ceph import DaemonGroup
if not hasattr(ctx, 'daemons'):
- ctx.daemons = CephState()
+ ctx.daemons = DaemonGroup()
for id_, remote in samba_servers:
@@ -148,7 +148,7 @@ def task(ctx, config):
smbd_cmd = [
'sudo',
- '{tdir}/daemon-helper'.format(tdir=testdir),
+ 'daemon-helper',
'kill',
'nostdin',
'/usr/local/samba/sbin/smbd',
diff --git a/teuthology/task/scrub.py b/tasks/scrub.py
similarity index 100%
rename from teuthology/task/scrub.py
rename to tasks/scrub.py
diff --git a/teuthology/task/scrub_test.py b/tasks/scrub_test.py
similarity index 100%
rename from teuthology/task/scrub_test.py
rename to tasks/scrub_test.py
diff --git a/teuthology/task/thrashosds.py b/tasks/thrashosds.py
similarity index 96%
rename from teuthology/task/thrashosds.py
rename to tasks/thrashosds.py
index 1702dbdfd..c14884c78 100644
--- a/teuthology/task/thrashosds.py
+++ b/tasks/thrashosds.py
@@ -19,7 +19,7 @@ def task(ctx, config):
The config is optional, and is a dict containing some or all of:
- min_in: (default 2) the minimum number of OSDs to keep in the
+ min_in: (default 3) the minimum number of OSDs to keep in the
cluster
min_out: (default 0) the minimum number of OSDs to keep out of the
@@ -57,7 +57,7 @@ def task(ctx, config):
to become clean after each cluster change. If this doesn't
happen within the timeout, an exception will be raised.
- revive_timeout: (75) number of seconds to wait for an osd asok to
+ revive_timeout: (150) number of seconds to wait for an osd asok to
appear after attempting to revive the osd
chance_pgnum_grow: (0) chance to increase a pool's size
@@ -109,7 +109,7 @@ def task(ctx, config):
for t, key in ctx.config['targets'].iteritems():
host = t.split('@')[-1]
shortname = host.split('.')[0]
- from ..orchestra import remote as oremote
+ from teuthology.orchestra import remote as oremote
console = oremote.getRemoteConsole(
name=host,
ipmiuser=ctx.teuthology_config['ipmi_user'],
diff --git a/teuthology/task/userdata_setup.yaml b/tasks/userdata_setup.yaml
similarity index 100%
rename from teuthology/task/userdata_setup.yaml
rename to tasks/userdata_setup.yaml
diff --git a/teuthology/task/userdata_teardown.yaml b/tasks/userdata_teardown.yaml
similarity index 100%
rename from teuthology/task/userdata_teardown.yaml
rename to tasks/userdata_teardown.yaml
diff --git a/tasks/util/__init__.py b/tasks/util/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tasks/util/kclient.py b/tasks/util/kclient.py
new file mode 100644
index 000000000..c6a259fc7
--- /dev/null
+++ b/tasks/util/kclient.py
@@ -0,0 +1,22 @@
+from teuthology.misc import get_testdir
+from teuthology.orchestra import run
+
+
+def write_secret_file(ctx, remote, role, keyring, filename):
+ """
+ Stash the kerying in the filename specified.
+ """
+ testdir = get_testdir(ctx)
+ remote.run(
+ args=[
+ 'adjust-ulimits',
+ 'ceph-coverage',
+ '{tdir}/archive/coverage'.format(tdir=testdir),
+ 'ceph-authtool',
+ '--name={role}'.format(role=role),
+ '--print-key',
+ keyring,
+ run.Raw('>'),
+ filename,
+ ],
+ )
diff --git a/teuthology/task_util/rados.py b/tasks/util/rados.py
similarity index 91%
rename from teuthology/task_util/rados.py
rename to tasks/util/rados.py
index a9386c75b..1ce4cefd7 100644
--- a/teuthology/task_util/rados.py
+++ b/tasks/util/rados.py
@@ -8,7 +8,7 @@ def rados(ctx, remote, cmd, wait=True, check_status=False):
testdir = teuthology.get_testdir(ctx)
log.info("rados %s" % ' '.join(cmd))
pre = [
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'rados',
diff --git a/teuthology/task_util/rgw.py b/tasks/util/rgw.py
similarity index 97%
rename from teuthology/task_util/rgw.py
rename to tasks/util/rgw.py
index 91458e5cb..b8cf2cfd0 100644
--- a/teuthology/task_util/rgw.py
+++ b/tasks/util/rgw.py
@@ -4,7 +4,7 @@
import requests
from urlparse import urlparse
-from ..orchestra.connection import split_user
+from teuthology.orchestra.connection import split_user
from teuthology import misc as teuthology
log = logging.getLogger(__name__)
@@ -13,7 +13,7 @@ def rgwadmin(ctx, client, cmd, stdin=StringIO(), check_status=False):
log.info('rgwadmin: {client} : {cmd}'.format(client=client,cmd=cmd))
testdir = teuthology.get_testdir(ctx)
pre = [
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage'.format(tdir=testdir),
'{tdir}/archive/coverage'.format(tdir=testdir),
'radosgw-admin'.format(tdir=testdir),
diff --git a/teuthology/task/watch_notify_stress.py b/tasks/watch_notify_stress.py
similarity index 94%
rename from teuthology/task/watch_notify_stress.py
rename to tasks/watch_notify_stress.py
index 7a21ad5fb..5896a34c7 100644
--- a/teuthology/task/watch_notify_stress.py
+++ b/tasks/watch_notify_stress.py
@@ -2,7 +2,7 @@
import logging
import proc_thrasher
-from ..orchestra import run
+from teuthology.orchestra import run
from teuthology import misc as teuthology
log = logging.getLogger(__name__)
@@ -44,7 +44,7 @@ def task(ctx, config):
args =['CEPH_CLIENT_ID={id_}'.format(id_=id_),
'CEPH_ARGS="{flags}"'.format(flags=config.get('flags', '')),
- '{tdir}/daemon-helper'.format(tdir=testdir), 'kill',
+ 'daemon-helper', 'kill',
'multi_stress_watch foo foo'
]
diff --git a/teuthology/task/workunit.py b/tasks/workunit.py
similarity index 98%
rename from teuthology/task/workunit.py
rename to tasks/workunit.py
index 04ebb2aa3..4224f5478 100644
--- a/teuthology/task/workunit.py
+++ b/tasks/workunit.py
@@ -4,7 +4,7 @@
from teuthology import misc as teuthology
from teuthology.parallel import parallel
-from ..orchestra import run
+from teuthology.orchestra import run
log = logging.getLogger(__name__)
@@ -140,7 +140,7 @@ def _make_scratch_dir(ctx, role, subdir):
id_ = role[len(PREFIX):]
log.debug("getting remote for {id} role {role_}".format(id=id_, role_=role))
(remote,) = ctx.cluster.only(role).remotes.iterkeys()
- dir_owner = remote.shortname.split('@', 1)[0]
+ dir_owner = remote.user
mnt = os.path.join(teuthology.get_testdir(ctx), 'mnt.{id}'.format(id=id_))
# if neither kclient nor ceph-fuse are required for a workunit,
# mnt may not exist. Stat and create the directory if it doesn't.
@@ -288,7 +288,7 @@ def _run_tests(ctx, refspec, role, tests, env, subdir=None):
env_arg = '{var}={val}'.format(var=var, val=quoted_val)
args.append(run.Raw(env_arg))
args.extend([
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
+ 'adjust-ulimits',
'ceph-coverage',
'{tdir}/archive/coverage'.format(tdir=testdir),
'{srcdir}/{workunit}'.format(
diff --git a/teuthology/ceph.conf.template b/teuthology/ceph.conf.template
deleted file mode 100644
index d57292d14..000000000
--- a/teuthology/ceph.conf.template
+++ /dev/null
@@ -1,46 +0,0 @@
-[global]
- chdir = ""
- pid file = $name.pid
- auth supported = cephx
-
- filestore xattr use omap = true
-
- mon clock drift allowed = .250
-
- osd crush chooseleaf type = 0
- auth debug = true
-
- ms die on old message = true
-
-[osd]
- osd journal size = 100
-
- osd scrub load threshold = 5.0
- osd scrub max interval = 600
-
- osd recover clone overlap = true
- osd recovery max chunk = 1048576
-
- osd debug op order = true
- osd debug verify stray on activate = true
-
- osd open classes on start = true
-
-[mon]
- debug ms = 1
- debug mon = 20
- debug paxos = 20
- mon data avail warn = 10
-
-[mds]
- lockdep = 1
- mds debug scatterstat = true
- mds verify scatter = true
- mds debug frag = true
-
-[client]
- rgw cache enabled = true
- rgw enable ops log = true
- rgw enable usage log = true
- log file = /var/log/ceph/ceph-$name.$pid.log
- admin socket = /var/run/ceph/ceph-$name.$pid.asok
diff --git a/teuthology/contextutil.py b/teuthology/contextutil.py
deleted file mode 100644
index 690d07f95..000000000
--- a/teuthology/contextutil.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import contextlib
-import sys
-import logging
-
-log = logging.getLogger(__name__)
-
-@contextlib.contextmanager
-def nested(*managers):
- """
- Like contextlib.nested but takes callables returning context
- managers, to avoid the major reason why contextlib.nested was
- deprecated.
-
- This version also logs any exceptions early, much like run_tasks,
- to ease debugging. TODO combine nested and run_tasks.
- """
- exits = []
- vars = []
- exc = (None, None, None)
- try:
- for mgr_fn in managers:
- mgr = mgr_fn()
- exit = mgr.__exit__
- enter = mgr.__enter__
- vars.append(enter())
- exits.append(exit)
- yield vars
- except:
- log.exception('Saw exception from nested tasks')
- exc = sys.exc_info()
- finally:
- while exits:
- exit = exits.pop()
- try:
- if exit(*exc):
- exc = (None, None, None)
- except:
- exc = sys.exc_info()
- if exc != (None, None, None):
- # Don't rely on sys.exc_info() still containing
- # the right information. Another exception may
- # have been raised and caught by an exit method
- raise exc[0], exc[1], exc[2]
diff --git a/teuthology/coverage.py b/teuthology/coverage.py
deleted file mode 100644
index 8a31b439a..000000000
--- a/teuthology/coverage.py
+++ /dev/null
@@ -1,244 +0,0 @@
-import argparse
-from contextlib import closing
-import logging
-import os
-import shutil
-import subprocess
-import MySQLdb
-import yaml
-
-from teuthology import misc as teuthology
-
-log = logging.getLogger(__name__)
-
-"""
-The coverage database can be created in mysql with:
-
-CREATE TABLE `coverage` (
- `run_id` bigint(20) NOT NULL AUTO_INCREMENT,
- `rev` char(40) NOT NULL,
- `test` varchar(255) NOT NULL,
- `suite` varchar(255) NOT NULL,
- `lines` int(10) unsigned NOT NULL,
- `line_cov` float unsigned NOT NULL,
- `functions` int(10) unsigned NOT NULL,
- `function_cov` float unsigned NOT NULL,
- `branches` int(10) unsigned NOT NULL,
- `branch_cov` float unsigned NOT NULL,
- `run_date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
- PRIMARY KEY (`run_id`)
-) ENGINE=InnoDB DEFAULT CHARSET=utf8
-
-"""
-
-def connect_to_db(ctx):
- db = MySQLdb.connect(
- host=ctx.teuthology_config['coverage_db_host'],
- user=ctx.teuthology_config['coverage_db_user'],
- db=ctx.teuthology_config['coverage_db_name'],
- passwd=ctx.teuthology_config['coverage_db_password'],
- )
- db.autocommit(False)
- return db
-
-def store_coverage(ctx, test_coverage, rev, suite):
- with closing(connect_to_db(ctx)) as db:
- rows = []
- for test, coverage in test_coverage.iteritems():
- flattened_cov = [item for sublist in coverage for item in sublist]
- rows.append([rev, test, suite] + flattened_cov)
- log.debug('inserting rows into db: %s', str(rows))
- try:
- cursor = db.cursor()
- cursor.executemany(
- 'INSERT INTO `coverage`'
- ' (`rev`, `test`, `suite`, `lines`, `line_cov`, `functions`,'
- ' `function_cov`, `branches`, `branch_cov`)'
- ' VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s)',
- rows)
- except:
- log.exception('error updating database')
- db.rollback()
- raise
- else:
- db.commit()
- log.info('added coverage to database')
- finally:
- cursor.close()
-
-def read_coverage(output):
- log.debug('reading coverage from output: %s', output)
- coverage = [None, None, None]
- prefixes = [' lines......: ', ' functions..: ', ' branches...: ']
- for line in reversed(output.splitlines()):
- for i, prefix in enumerate(prefixes):
- if line.startswith(prefix):
- if '%' in line:
- cov_num = int(line[line.find('(') + 1:line.find(' of')])
- cov_percent = float(line[len(prefix):line.find('%')])
- coverage[i] = (cov_num, cov_percent)
- else:
- # may have no data for e.g. branches on the initial run
- coverage[i] = (None, None)
- break
- if None not in coverage:
- break
- return coverage
-
-def analyze():
- parser = argparse.ArgumentParser(description="""
-Analyze the coverage of a suite of test runs, generating html output with lcov.
-""")
- parser.add_argument(
- '-o', '--lcov-output',
- help='the directory in which to store results',
- required=True,
- )
- parser.add_argument(
- '--html-output',
- help='the directory in which to store html output',
- )
- parser.add_argument(
- '--cov-tools-dir',
- help='the location of coverage scripts (cov-init and cov-analyze)',
- default='../../coverage',
- )
- parser.add_argument(
- '--skip-init',
- help='skip initialization (useful if a run stopped partway through)',
- action='store_true',
- default=False,
- )
- parser.add_argument(
- '-v', '--verbose',
- help='be more verbose',
- action='store_true',
- default=False,
- )
- parser.add_argument(
- 'test_dir',
- help='the location of the test results',
- )
- args = parser.parse_args()
-
- loglevel = logging.INFO
- if args.verbose:
- loglevel = logging.DEBUG
-
- logging.basicConfig(
- level=loglevel,
- )
-
- teuthology.read_config(args)
-
- handler = logging.FileHandler(
- filename=os.path.join(args.test_dir, 'coverage.log'),
- )
- formatter = logging.Formatter(
- fmt='%(asctime)s.%(msecs)03d %(levelname)s:%(message)s',
- datefmt='%Y-%m-%dT%H:%M:%S',
- )
- handler.setFormatter(formatter)
- logging.getLogger().addHandler(handler)
-
- try:
- _analyze(args)
- except:
- log.exception('error generating coverage')
- raise
-
-def _analyze(args):
- tests = [
- f for f in sorted(os.listdir(args.test_dir))
- if not f.startswith('.')
- and os.path.isdir(os.path.join(args.test_dir, f))
- and os.path.exists(os.path.join(args.test_dir, f, 'summary.yaml'))
- and os.path.exists(os.path.join(args.test_dir, f, 'ceph-sha1'))]
-
- test_summaries = {}
- for test in tests:
- summary = {}
- with file(os.path.join(args.test_dir, test, 'summary.yaml')) as f:
- g = yaml.safe_load_all(f)
- for new in g:
- summary.update(new)
-
- if summary['flavor'] != 'gcov':
- log.debug('Skipping %s, since it does not include coverage', test)
- continue
- test_summaries[test] = summary
-
- assert len(test_summaries) > 0
-
- suite = os.path.basename(args.test_dir)
-
- # only run cov-init once.
- # this only works if all tests were run against the same version.
- if not args.skip_init:
- log.info('initializing coverage data...')
- subprocess.check_call(
- args=[
- os.path.join(args.cov_tools_dir, 'cov-init.sh'),
- os.path.join(args.test_dir, tests[0]),
- args.lcov_output,
- os.path.join(
- args.teuthology_config['ceph_build_output_dir'],
- '{suite}.tgz'.format(suite=suite),
- ),
- ])
- shutil.copy(
- os.path.join(args.lcov_output, 'base.lcov'),
- os.path.join(args.lcov_output, 'total.lcov')
- )
-
- test_coverage = {}
- for test, summary in test_summaries.iteritems():
- lcov_file = '{name}.lcov'.format(name=test)
-
- log.info('analyzing coverage for %s', test)
- proc = subprocess.Popen(
- args=[
- os.path.join(args.cov_tools_dir, 'cov-analyze.sh'),
- '-t', os.path.join(args.test_dir, test),
- '-d', args.lcov_output,
- '-o', test,
- ],
- stdout=subprocess.PIPE,
- )
- output, _ = proc.communicate()
- desc = summary.get('description', test)
- test_coverage[desc] = read_coverage(output)
-
- log.info('adding %s data to total', test)
- proc = subprocess.Popen(
- args=[
- 'lcov',
- '-a', os.path.join(args.lcov_output, lcov_file),
- '-a', os.path.join(args.lcov_output, 'total.lcov'),
- '-o', os.path.join(args.lcov_output, 'total_tmp.lcov'),
- ],
- stdout=subprocess.PIPE,
- )
- output, _ = proc.communicate()
-
- os.rename(
- os.path.join(args.lcov_output, 'total_tmp.lcov'),
- os.path.join(args.lcov_output, 'total.lcov')
- )
-
- coverage = read_coverage(output)
- test_coverage['total for {suite}'.format(suite=suite)] = coverage
- log.debug('total coverage is %s', str(coverage))
-
- if args.html_output:
- subprocess.check_call(
- args=[
- 'genhtml',
- '-s',
- '-o', os.path.join(args.html_output, 'total'),
- '-t', 'Total for {suite}'.format(suite=suite),
- '--',
- os.path.join(args.lcov_output, 'total.lcov'),
- ])
-
- store_coverage(args, test_coverage, summary['ceph-sha1'], suite)
diff --git a/teuthology/lock.py b/teuthology/lock.py
deleted file mode 100644
index b54a9bf96..000000000
--- a/teuthology/lock.py
+++ /dev/null
@@ -1,643 +0,0 @@
-import argparse
-import json
-import logging
-import subprocess
-import urllib
-import yaml
-import re
-import collections
-import tempfile
-import os
-import time
-
-from teuthology import lockstatus as ls
-from teuthology import misc as teuthology
-
-log = logging.getLogger(__name__)
-
-def lock_many(ctx, num, machinetype, user=None, description=None):
- if user is None:
- user = teuthology.get_user()
- success, content, status = ls.send_request('POST', ls._lock_url(ctx),
- urllib.urlencode(dict(
- user=user,
- num=num,
- machinetype=machinetype,
- desc=description,
- )))
- if success:
- machines = json.loads(content)
- log.debug('locked {machines}'.format(machines=', '.join(machines.keys())))
- if ctx.machine_type == 'vps':
- for machine in machines:
- create_if_vm(ctx, machine)
- return machines
- if status == 503:
- log.error('Insufficient nodes available to lock %d nodes.', num)
- else:
- log.error('Could not lock %d nodes, reason: unknown.', num)
- return []
-
-def lock(ctx, name, user=None, description=None):
- if user is None:
- user = teuthology.get_user()
- success, _, _ = ls.send_request('POST', ls._lock_url(ctx) + '/' + name,
- urllib.urlencode(dict(user=user, desc=description)))
- if success:
- log.debug('locked %s as %s', name, user)
- else:
- log.error('failed to lock %s', name)
- return success
-
-def unlock(ctx, name, user=None):
- if user is None:
- user = teuthology.get_user()
- success, _ , _ = ls.send_request('DELETE', ls._lock_url(ctx) + '/' + name + '?' + \
- urllib.urlencode(dict(user=user)))
- if success:
- log.debug('unlocked %s', name)
- if not destroy_if_vm(ctx, name):
- log.error('downburst destroy failed for %s',name)
- else:
- log.error('failed to unlock %s', name)
- return success
-
-def list_locks(ctx):
- success, content, _ = ls.send_request('GET', ls._lock_url(ctx))
- if success:
- return json.loads(content)
- return None
-
-def update_lock(ctx, name, description=None, status=None, sshpubkey=None):
- status_info = ls.get_status(ctx, name)
- phys_host = status_info['vpshost']
- if phys_host:
- keyscan_out = ''
- while not keyscan_out:
- time.sleep(10)
- keyscan_out, _ = keyscan_check(ctx, [name])
- updated = {}
- if description is not None:
- updated['desc'] = description
- if status is not None:
- updated['status'] = status
- if sshpubkey is not None:
- updated['sshpubkey'] = sshpubkey
-
- if updated:
- success, _, _ = ls.send_request('PUT', ls._lock_url(ctx) + '/' + name,
- body=urllib.urlencode(updated),
- headers={'Content-type': 'application/x-www-form-urlencoded'})
- return success
- return True
-
-def _positive_int(string):
- value = int(string)
- if value < 1:
- raise argparse.ArgumentTypeError(
- '{string} is not positive'.format(string=string))
- return value
-
-def canonicalize_hostname(s):
- if re.match('ubuntu@.*\.front\.sepia\.ceph\.com', s) is None:
- s = 'ubuntu@' + s + '.front.sepia.ceph.com'
- return s
-
-def main():
- parser = argparse.ArgumentParser(description="""
-Lock, unlock, or query lock status of machines.
-""")
- parser.add_argument(
- '-v', '--verbose',
- action='store_true',
- default=False,
- help='be more verbose',
- )
- group = parser.add_mutually_exclusive_group(required=True)
- group.add_argument(
- '--list',
- action='store_true',
- default=False,
- help='Show lock info for machines owned by you, or only machines specified. Can be restricted by --owner, --status, and --locked.',
- )
- group.add_argument(
- '--list-targets',
- action='store_true',
- default=False,
- help='Show lock info for all machines, or only machines specified, in targets: yaml format. Can be restricted by --owner, --status, and --locked.',
- )
- group.add_argument(
- '--lock',
- action='store_true',
- default=False,
- help='lock particular machines',
- )
- group.add_argument(
- '--unlock',
- action='store_true',
- default=False,
- help='unlock particular machines',
- )
- group.add_argument(
- '--lock-many',
- dest='num_to_lock',
- type=_positive_int,
- help='lock this many machines',
- )
- group.add_argument(
- '--update',
- action='store_true',
- default=False,
- help='update the description or status of some machines',
- )
- group.add_argument(
- '--summary',
- action='store_true',
- default=False,
- help='summarize locked-machine counts by owner',
- )
- parser.add_argument(
- '-a', '--all',
- action='store_true',
- default=False,
- help='list all machines, not just those owned by you',
- )
- parser.add_argument(
- '--owner',
- default=None,
- help='owner of the lock(s) (must match to unlock a machine)',
- )
- parser.add_argument(
- '-f',
- action='store_true',
- default=False,
- help='don\'t exit after the first error, continue locking or unlocking other machines',
- )
- parser.add_argument(
- '--desc',
- default=None,
- help='lock description',
- )
- parser.add_argument(
- '--desc-pattern',
- default=None,
- help='lock description',
- )
- parser.add_argument(
- '--machine-type',
- default=None,
- help='Type of machine to lock',
- )
- parser.add_argument(
- '--status',
- default=None,
- choices=['up', 'down'],
- help='whether a machine is usable for testing',
- )
- parser.add_argument(
- '--locked',
- default=None,
- choices=['true', 'false'],
- help='whether a machine is locked',
- )
- parser.add_argument(
- '--brief',
- action='store_true',
- default=False,
- help='Shorten information reported from --list',
- )
- parser.add_argument(
- '-t', '--targets',
- dest='targets',
- default=None,
- help='input yaml containing targets',
- )
- parser.add_argument(
- 'machines',
- metavar='MACHINE',
- default=[],
- nargs='*',
- help='machines to operate on',
- )
- parser.add_argument(
- '--os-type',
- default='ubuntu',
- help='virtual machine type',
- )
-
- ctx = parser.parse_args()
-
- loglevel = logging.INFO
- if ctx.verbose:
- loglevel = logging.DEBUG
-
- logging.basicConfig(
- level=loglevel,
- )
-
- teuthology.read_config(ctx)
-
- ret = 0
- user = ctx.owner
- machines = [canonicalize_hostname(m) for m in ctx.machines]
- machines_to_update = []
-
- if ctx.targets:
- try:
- with file(ctx.targets) as f:
- g = yaml.safe_load_all(f)
- for new in g:
- if 'targets' in new:
- for t in new['targets'].iterkeys():
- machines.append(t)
- except IOError, e:
- raise argparse.ArgumentTypeError(str(e))
-
- if ctx.f:
- assert ctx.lock or ctx.unlock, \
- '-f is only supported by --lock and --unlock'
- if machines:
- assert ctx.lock or ctx.unlock or ctx.list or ctx.list_targets \
- or ctx.update, \
- 'machines cannot be specified with that operation'
- else:
- assert ctx.num_to_lock or ctx.list or ctx.list_targets or ctx.summary,\
- 'machines must be specified for that operation'
- if ctx.all:
- assert ctx.list or ctx.list_targets, \
- '--all can only be used with --list and --list-targets'
- assert ctx.owner is None, \
- '--all and --owner are mutually exclusive'
- assert not machines, \
- '--all and listing specific machines are incompatible'
- if ctx.num_to_lock:
- assert ctx.machine_type, \
- 'must specify machine type to lock'
-
- if ctx.brief:
- assert ctx.list, '--brief only applies to --list'
-
- if ctx.list or ctx.list_targets:
- assert ctx.desc is None, '--desc does nothing with --list'
-
- if machines:
- statuses = []
- for machine in machines:
- status = ls.get_status(ctx, machine)
- if status:
- statuses.append(status)
- else:
- log.error("Lockserver doesn't know about machine: %s" %
- machine)
- else:
- statuses = list_locks(ctx)
- vmachines = []
-
- for vmachine in statuses:
- if vmachine['vpshost']:
- if vmachine['locked']:
- vmachines.append(vmachine['name'])
- if vmachines:
- # Avoid ssh-keyscans for everybody when listing all machines
- # Listing specific machines will update the keys.
- if machines:
- scan_for_locks(ctx, vmachines)
- statuses = [ls.get_status(ctx, machine) for machine in machines]
- else:
- statuses = list_locks(ctx)
- if statuses:
- if ctx.machine_type:
- statuses = [status for status in statuses \
- if status['type'] == ctx.machine_type]
- if not machines and ctx.owner is None and not ctx.all:
- ctx.owner = teuthology.get_user()
- if ctx.owner is not None:
- statuses = [status for status in statuses \
- if status['locked_by'] == ctx.owner]
- if ctx.status is not None:
- statuses = [status for status in statuses \
- if status['up'] == (ctx.status == 'up')]
- if ctx.locked is not None:
- statuses = [status for status in statuses \
- if status['locked'] == (ctx.locked == 'true')]
- if ctx.desc is not None:
- statuses = [status for status in statuses \
- if status['description'] == ctx.desc]
- if ctx.desc_pattern is not None:
- statuses = [status for status in statuses \
- if status['description'] is not None and \
- status['description'].find(ctx.desc_pattern) >= 0]
- if ctx.list:
- if ctx.brief:
- for s in statuses:
- locked = "un" if s['locked'] == 0 else " "
- mo = re.match('\w+@(\w+?)\..*', s['name'])
- host = mo.group(1) if mo else s['name']
- print '{host} {locked}locked {owner} "{desc}"'.format(
- locked = locked, host = host,
- owner=s['locked_by'], desc=s['description'])
- else:
- print json.dumps(statuses, indent=4)
- else:
- frag = { 'targets': {} }
- for f in statuses:
- frag['targets'][f['name']] = f['sshpubkey']
- print yaml.safe_dump(frag, default_flow_style=False)
- else:
- log.error('error retrieving lock statuses')
- ret = 1
-
- elif ctx.summary:
- do_summary(ctx)
- return 0
-
- elif ctx.lock:
- for machine in machines:
- if not lock(ctx, machine, user):
- ret = 1
- if not ctx.f:
- return ret
- else:
- machines_to_update.append(machine)
- create_if_vm(ctx, machine)
- elif ctx.unlock:
- for machine in machines:
- if not unlock(ctx, machine, user):
- ret = 1
- if not ctx.f:
- return ret
- else:
- machines_to_update.append(machine)
- destroy_if_vm(ctx, machine)
- elif ctx.num_to_lock:
- result = lock_many(ctx, ctx.num_to_lock, ctx.machine_type, user)
- if not result:
- ret = 1
- else:
- machines_to_update = result.keys()
- if ctx.machine_type == 'vps':
- shortnames = ' '.join([name.split('@')[1].split('.')[0] for name in result.keys()])
- print "Successfully Locked:\n%s\n" % shortnames
- print "Unable to display keys at this time (virtual machines are booting)."
- print "Please run teuthology-lock --list-targets %s once these machines come up." % shortnames
- else:
- print yaml.safe_dump(dict(targets=result), default_flow_style=False)
- elif ctx.update:
- assert ctx.desc is not None or ctx.status is not None, \
- 'you must specify description or status to update'
- assert ctx.owner is None, 'only description and status may be updated'
- machines_to_update = machines
-
- if ctx.desc is not None or ctx.status is not None:
- for machine in machines_to_update:
- update_lock(ctx, machine, ctx.desc, ctx.status)
-
- return ret
-
-def update_hostkeys():
- parser = argparse.ArgumentParser(description="""
-Update any hostkeys that have changed. You can list specific machines
-to run on, or use -a to check all of them automatically.
-""")
- parser.add_argument(
- '-t', '--targets',
- default=None,
- help='input yaml containing targets to check',
- )
- parser.add_argument(
- 'machines',
- metavar='MACHINES',
- default=[],
- nargs='*',
- help='hosts to check for updated keys',
- )
- parser.add_argument(
- '-v', '--verbose',
- action='store_true',
- default=False,
- help='be more verbose',
- )
- parser.add_argument(
- '-a', '--all',
- action='store_true',
- default=False,
- help='update hostkeys of all machines in the db',
- )
-
- ctx = parser.parse_args()
-
- loglevel = logging.INFO
- if ctx.verbose:
- loglevel = logging.DEBUG
-
- logging.basicConfig(
- level=loglevel,
- )
-
- teuthology.read_config(ctx)
-
- assert ctx.all or ctx.targets or ctx.machines, 'You must specify machines to update'
- if ctx.all:
- assert not ctx.targets and not ctx.machines, \
- 'You can\'t specify machines with the --all option'
- machines = [canonicalize_hostname(m) for m in ctx.machines]
-
- if ctx.targets:
- try:
- with file(ctx.targets) as f:
- g = yaml.safe_load_all(f)
- for new in g:
- if 'targets' in new:
- for t in new['targets'].iterkeys():
- machines.append(t)
- except IOError, e:
- raise argparse.ArgumentTypeError(str(e))
-
- return scan_for_locks(ctx, machines)
-
-def keyscan_check(ctx, machines):
- locks = list_locks(ctx)
- current_locks = {}
- for lock in locks:
- current_locks[lock['name']] = lock
-
- if hasattr(ctx, 'all'):
- if ctx.all:
- machines = current_locks.keys()
-
- for i, machine in enumerate(machines):
- if '@' in machine:
- _, machines[i] = machine.rsplit('@')
- args = ['ssh-keyscan']
- args.extend(machines)
- p = subprocess.Popen(
- args=args,
- stdout=subprocess.PIPE,
- )
- out, _ = p.communicate()
- #assert p.returncode == 0, 'ssh-keyscan failed'
- return (out, current_locks)
-
-def update_keys(ctx, out, current_locks):
- ret = 0
- for key_entry in out.splitlines():
- hostname, pubkey = key_entry.split(' ', 1)
- # TODO: separate out user
- full_name = 'ubuntu@{host}'.format(host=hostname)
- log.info('Checking %s', full_name)
- assert full_name in current_locks, 'host is not in the database!'
- if current_locks[full_name]['sshpubkey'] != pubkey:
- log.info('New key found. Updating...')
- if not update_lock(ctx, full_name, sshpubkey=pubkey):
- log.error('failed to update %s!', full_name)
- ret = 1
- return ret
-
-def scan_for_locks(ctx, machines):
- out, current_locks = keyscan_check(ctx, machines)
- return update_keys(ctx, out, current_locks)
-
-def do_summary(ctx):
- lockd = collections.defaultdict(lambda: [0,0,'unknown'])
- for l in list_locks(ctx):
- if ctx.machine_type and l['type'] != ctx.machine_type:
- continue
- who = l['locked_by'] if l['locked'] == 1 else '(free)', l['type']
- lockd[who][0] += 1
- lockd[who][1] += l['up'] # up is 1 or 0
- lockd[who][2] = l['type']
-
- locks = sorted([p for p in lockd.iteritems()], key=lambda sort: (sort[1][2],sort[1][0]))
- total_count, total_up = 0, 0
- print "TYPE COUNT UP OWNER"
-
- for (owner, (count, upcount, machinetype)) in locks:
- #if machinetype == spectype:
- print "{machinetype:8s} {count:3d} {up:3d} {owner}".format(count = count,
- up = upcount, owner = owner[0], machinetype=machinetype)
- total_count += count
- total_up += upcount
-
- print " --- ---"
- print "{cnt:12d} {up:3d}".format(cnt = total_count, up = total_up)
-
-def decanonicalize_hostname(s):
- if re.match('ubuntu@.*\.front\.sepia\.ceph\.com', s):
- s = s[len('ubuntu@'): -len('.front.sepia.ceph.com')]
- return s
-
-def _get_downburst_exec():
- """
- First check for downburst in the user's path.
- Then check in ~/src, ~ubuntu/src, and ~teuthology/src.
- Return '' if no executable downburst is found.
- """
- path = os.environ.get('PATH', None)
- if path:
- for p in os.environ.get('PATH','').split(os.pathsep):
- pth = os.path.join(p, 'downburst')
- if os.access(pth, os.X_OK):
- return pth
- import pwd
- little_old_me = pwd.getpwuid(os.getuid()).pw_name
- for user in [little_old_me, 'ubuntu', 'teuthology']:
- pth = "/home/%s/src/downburst/virtualenv/bin/downburst" % user
- if os.access(pth, os.X_OK):
- return pth
- return ''
-
-#
-# Use downburst to create a virtual machine
-#
-def create_if_vm(ctx, machine_name):
- status_info = ls.get_status(ctx, machine_name)
- phys_host = status_info['vpshost']
- if not phys_host:
- return False
- from teuthology.misc import get_distro
- os_type = get_distro(ctx)
- default_os_version = dict(
- ubuntu="12.04",
- fedora="18",
- centos="6.4",
- opensuse="12.2",
- sles="11-sp2",
- rhel="6.3",
- debian='6.0'
- )
- createMe = decanonicalize_hostname(machine_name)
- with tempfile.NamedTemporaryFile() as tmp:
- try:
- lcnfg = ctx.config['downburst']
- except (KeyError, AttributeError):
- lcnfg = {}
-
- distro = lcnfg.get('distro', os_type.lower())
- try:
- distroversion = ctx.config.get('os_version', default_os_version[distro])
- except AttributeError:
- distroversion = default_os_version[distro]
-
- file_info = {}
- file_info['disk-size'] = lcnfg.get('disk-size', '30G')
- file_info['ram'] = lcnfg.get('ram', '1.9G')
- file_info['cpus'] = lcnfg.get('cpus', 1)
- file_info['networks'] = lcnfg.get('networks',
- [{'source' : 'front', 'mac' : status_info['mac']}])
- file_info['distro'] = distro
- file_info['distroversion'] = distroversion
- file_info['additional-disks'] = lcnfg.get(
- 'additional-disks', 3)
- file_info['additional-disks-size'] = lcnfg.get(
- 'additional-disks-size', '200G')
- file_info['arch'] = lcnfg.get('arch', 'x86_64')
- file_out = {'downburst': file_info}
- yaml.safe_dump(file_out, tmp)
- metadata = "--meta-data=%s" % tmp.name
- dbrst = _get_downburst_exec()
- if not dbrst:
- log.info("Error: no downburst executable found")
- return False
- p = subprocess.Popen([dbrst, '-c', phys_host,
- 'create', metadata, createMe],
- stdout=subprocess.PIPE,stderr=subprocess.PIPE,)
- owt,err = p.communicate()
- if err:
- log.info("Downburst completed on %s: %s" %
- (machine_name,err))
- else:
- log.info("%s created: %s" % (machine_name,owt))
- #If the guest already exists first destroy then re-create:
- if 'exists' in err:
- log.info("Guest files exist. Re-creating guest: %s" %
- (machine_name))
- destroy_if_vm(ctx, machine_name)
- create_if_vm(ctx, machine_name)
- return True
-#
-# Use downburst to destroy a virtual machine
-#
-def destroy_if_vm(ctx, machine_name):
- """
- Return False only on vm downburst failures.
- """
- status_info = ls.get_status(ctx, machine_name)
- phys_host = status_info['vpshost']
- if not phys_host:
- return True
- destroyMe = decanonicalize_hostname(machine_name)
- dbrst = _get_downburst_exec()
- if not dbrst:
- log.info("Error: no downburst executable found")
- return False
- p = subprocess.Popen([dbrst, '-c', phys_host,
- 'destroy', destroyMe],
- stdout=subprocess.PIPE,stderr=subprocess.PIPE,)
- owt,err = p.communicate()
- if err:
- log.info("Error occurred while deleting %s" % destroyMe)
- return False
- else:
- log.info("%s destroyed: %s" % (machine_name,owt))
- return True
-
diff --git a/teuthology/locker/api.py b/teuthology/locker/api.py
deleted file mode 100644
index 2203fd5e3..000000000
--- a/teuthology/locker/api.py
+++ /dev/null
@@ -1,196 +0,0 @@
-import json
-import web
-import subprocess
-
-from config import DB
-
-def load_machine(name):
- results = list(DB.select('machine', what='*',
- where='name = $name',
- vars=dict(name=name)))
- if not results:
- raise web.NotFound()
- return results[0]
-
-def get_sshkey(name):
- if '@' in name:
- _, name = name.rsplit('@')
- args = ['ssh-keyscan']
- args.append(name)
- p = subprocess.Popen(
- args=args,
- stdout=subprocess.PIPE,
- )
- out, _ = p.communicate()
- pubkey = None
- for key_entry in out.splitlines():
- hostname, pubkey = key_entry.split(' ', 1)
- if not pubkey:
- status = 1
- else:
- status = 0
- return (pubkey), status
-
-def update_sshkey(name, key, type):
- if type == 'vps':
- return
- res = DB.update('machine', where='name = $name AND locked = false',
- vars=dict(name=name),
- sshpubkey=key,)
- assert res == 1, 'Failed to update key of machine {name}'.format(name=name)
- print 'Updated key on ', name
-
-class MachineLock:
- def GET(self, name):
- row = load_machine(name)
- row.locked_since = row.locked_since.isoformat()
- web.header('Content-type', 'text/json')
- return json.dumps(row)
-
- def DELETE(self, name):
- user = web.input('user')['user']
- machine = load_machine(name)
- if not machine.locked:
- raise web.BadRequest()
- if machine.locked_by != user:
- raise web.Forbidden()
-
- res = DB.update('machine',
- where='locked = true AND name = $name AND locked_by = $user',
- vars=dict(name=name, user=user),
- locked=False, locked_by=None, description=None)
- assert res == 1, 'Failed to unlock machine {name}'.format(name=name)
- print user, 'unlocked', name
-
- def POST(self, name):
- user = web.input('user')['user']
- desc = web.input(desc=None)['desc']
- machine = load_machine(name)
- if machine.locked:
- raise web.Forbidden()
-
- if machine.type == 'vps':
- curkey = machine.sshpubkey
- else:
- curkey, getstatus = get_sshkey(name)
- if getstatus != 0:
- curkey = machine.sshpubkey
- if machine.sshpubkey != curkey:
- newkey = curkey
- else:
- newkey = machine.sshpubkey
- res = DB.update('machine', where='name = $name AND locked = false',
- vars=dict(name=name),
- locked=True,
- description=desc,
- sshpubkey=newkey,
- locked_by=user,
- locked_since=web.db.SQLLiteral('NOW()'))
- assert res == 1, 'Failed to lock machine {name}'.format(name=name)
- print user, 'locked single machine', name, 'desc', desc
-
- def PUT(self, name):
- desc = web.input(desc=None)['desc']
- status = web.input(status=None)['status']
- sshpubkey = web.input(sshpubkey=None)['sshpubkey']
-
- updated = {}
- if desc is not None:
- updated['description'] = desc
- if status is not None:
- updated['up'] = (status == 'up')
- if sshpubkey is not None:
- updated['sshpubkey'] = sshpubkey
-
- if not updated:
- raise web.BadRequest()
- DB.update('machine', where='name = $name',
- vars=dict(name=name), **updated)
- print 'updated', name, 'with', updated, 'desc', desc
-
-class Lock:
- def GET(self):
- rows = list(DB.select('machine', what='*'))
- if not rows:
- raise web.NotFound()
- for row in rows:
- row.locked_since = row.locked_since.isoformat()
- web.header('Content-type', 'text/json')
- return json.dumps(rows)
-
- def POST(self):
- user = web.input('user')['user']
- desc = web.input(desc=None)['desc']
- num = int(web.input('num')['num'])
- machinetype = dict(machinetype=(web.input(machinetype='plana')['machinetype']))
-
- if num < 1:
- raise web.BadRequest()
-
- tries = 0
- check_existing = True
- while True:
- try:
- # transaction will be rolled back if an exception is raised
- with DB.transaction():
- if desc is not None and check_existing:
- # if a description is provided, treat it as a
- # key for locking in case the same run locked
- # machines in the db successfully before, but
- # the web server reported failure to it
- # because the request took too long. Only try
- # this once per request.
- check_existing = False
- results = list(DB.select('machine',
- machinetype, desc, user,
- what='name, sshpubkey',
- where='locked = true AND up = true AND type = $machinetype AND description = $desc AND locked_by = $user',
- limit=num))
- if len(results) == num:
- name_keys = {}
- for row in results:
- name_keys[row.name] = row.sshpubkey
- print 'reusing machines', name_keys.keys()
- break
-
- results = list(DB.select('machine', machinetype,
- what='name, sshpubkey, type',
- where='locked = false AND up = true AND type = $machinetype',
- limit=num))
- if len(results) < num:
- raise web.HTTPError(status='503 Service Unavailable')
- name_keys = {}
- for row in results:
- if row.type == 'vps':
- curkey = row.sshpubkey
- else:
- curkey, getstatus = get_sshkey(row.name)
- if getstatus != 0:
- curkey = row.sshpubkey
- if row.sshpubkey != curkey:
- newkey = curkey
- update_sshkey(row.name, curkey, row.type)
- else:
- newkey = row.sshpubkey
- name_keys[row.name] = newkey
- where_cond = web.db.sqlors('name = ', name_keys.keys()) \
- + ' AND locked = false AND up = true'
- num_locked = DB.update('machine',
- where=where_cond,
- locked=True,
- locked_by=user,
- description=desc,
- locked_since=web.db.SQLLiteral('NOW()'))
- assert num_locked == num, 'Failed to lock machines'
- except:
- tries += 1
- if tries < 10:
- continue
- raise
- else:
- break
-
- print user, 'locked', name_keys.keys(), 'desc', desc
-
- web.header('Content-type', 'text/json')
- return json.dumps(name_keys)
diff --git a/teuthology/locker/config.py b/teuthology/locker/config.py
deleted file mode 100644
index 090e8a0b0..000000000
--- a/teuthology/locker/config.py
+++ /dev/null
@@ -1,25 +0,0 @@
-"""
-This file contains database configuration.
-
-The schema can be created with::
-
- CREATE TABLE machine (
- name varchar(255),
- type enum('burnupi','plana','vps') NOT NULL DEFAULT 'plana',
- up boolean NOT NULL,
- locked boolean NOT NULL,
- locked_since timestamp NOT NULL DEFAULT '0000-00-00T00:00:00',
- locked_by varchar(32),
- description text,
- sshpubkey text NOT NULL,
- PRIMARY KEY (name),
- INDEX (locked),
- INDEX (up));
-
-If using MySQL, be sure to use an engine that supports
-transactions, like InnoDB.
-"""
-import web
-
-# Change these values to the connection info for your database.
-DB = web.database(dbn='dbms', db='db', user='user', pw='password', host='host')
diff --git a/teuthology/locker/locker.py b/teuthology/locker/locker.py
deleted file mode 100755
index 7de222d11..000000000
--- a/teuthology/locker/locker.py
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/usr/bin/env python
-
-import os
-import sys
-import web
-
-abspath = os.path.dirname(__file__)
-if abspath not in sys.path:
- sys.path.append(abspath)
-
-from api import Lock, MachineLock
-
-urls = (
- '/lock', 'Lock',
- '/lock/(.*)', 'MachineLock',
- )
-
-app = web.application(urls, globals())
-application = app.wsgifunc()
diff --git a/teuthology/lockstatus.py b/teuthology/lockstatus.py
deleted file mode 100644
index 5c25479ef..000000000
--- a/teuthology/lockstatus.py
+++ /dev/null
@@ -1,26 +0,0 @@
-import json
-import httplib2
-import logging
-
-log = logging.getLogger(__name__)
-
-def _lock_url(ctx):
- try:
- return ctx.teuthology_config['lock_server']
- except (AttributeError, KeyError):
- return "http://teuthology.front.sepia.ceph.com/locker/lock"
-
-def send_request(method, url, body=None, headers=None):
- http = httplib2.Http()
- resp, content = http.request(url, method=method, body=body, headers=headers)
- if resp.status == 200:
- return (True, content, resp.status)
- log.info("%s request to '%s' with body '%s' failed with response code %d",
- method, url, body, resp.status)
- return (False, None, resp.status)
-
-def get_status(ctx, name):
- success, content, _ = send_request('GET', _lock_url(ctx) + '/' + name)
- if success:
- return json.loads(content)
- return None
diff --git a/teuthology/misc.py b/teuthology/misc.py
deleted file mode 100644
index 1a0eee7e4..000000000
--- a/teuthology/misc.py
+++ /dev/null
@@ -1,913 +0,0 @@
-from cStringIO import StringIO
-
-import os
-import logging
-import configobj
-import getpass
-import socket
-import sys
-import tarfile
-import time
-import urllib2
-import urlparse
-import yaml
-import json
-
-from teuthology import safepath
-from teuthology import lockstatus
-from .orchestra import run
-
-log = logging.getLogger(__name__)
-
-import datetime
-stamp = datetime.datetime.now().strftime("%y%m%d%H%M")
-global_jobid = None
-checked_jobid = False
-is_vm = lambda x: x.startswith('vpm') or x.startswith('ubuntu@vpm')
-
-is_arm = lambda x: x.startswith('tala') or x.startswith('ubuntu@tala') or x.startswith('saya') or x.startswith('ubuntu@saya')
-
-def get_testdir(ctx):
- if 'test_path' in ctx.teuthology_config:
- return ctx.teuthology_config['test_path']
-
- basedir = ctx.teuthology_config.get('base_test_dir', '/home/ubuntu/cephtest')
-
- global global_jobid
- global checked_jobid
-
- # check if a jobid exists in the machine status for all our targets
- # and if its the same jobid, use that as the subdir for the test
- if not checked_jobid and ctx.config.get('check-locks') != False:
- jobids = {}
- for machine in ctx.config['targets'].iterkeys():
- status = lockstatus.get_status(ctx, machine)
- if status is None or 'description' not in status or status['description'] is None:
- continue
- jid = status['description'].split('/')[-1]
- if jid is None or jid == 'None':
- continue
- jobids[jid] = 1
- if len(jobids) > 1:
- break
- if len(jobids) == 1:
- # same job id on all machines, use that as the test subdir
- (jobid,) = jobids.iterkeys()
- if jobid is not None:
- global_jobid = jobid
- log.debug('setting my jobid to {jid}'.format(jid=global_jobid))
- checked_jobid = True
-
- # the subdir is chosen using the priority:
- # 1. jobid chosen by the teuthology beanstalk queue
- # 2. run name specified by teuthology schedule
- # 3. user@timestamp
- if global_jobid is not None:
- log.debug('with jobid basedir: {b}'.format(b=global_jobid))
- return '{basedir}/{jobid}'.format(
- basedir=basedir,
- jobid=global_jobid,
- )
- elif hasattr(ctx, 'name') and ctx.name:
- log.debug('with name basedir: {b}'.format(b=basedir))
- # we need a short string to keep the path short
- import re
- m = re.match(r"(.*)-(.*)-(.*)-(.*)_(.*)-(.*)-(.*)-(.*)-(.*)", ctx.name)
- (u, y, m, d, hms, s, c, k, f) = m.groups()
- short = u[0:2] + y[2:4] + m[0:2] + d[0:2] + hms[0:2] + hms[3:5] + s[0] + c[0] + k[0] + f[0]
- return '{basedir}/{rundir}'.format(
- basedir=basedir,
- rundir=short,
- )
- else:
- log.debug('basedir: {b}'.format(b=basedir))
- return '{basedir}/{user}{stamp}'.format(
- basedir=basedir,
- user=get_user()[0:2],
- stamp=stamp)
-
-def get_testdir_base(ctx):
- if 'test_path' in ctx.teuthology_config:
- return ctx.teuthology_config['test_path']
- return ctx.teuthology_config.get('base_test_dir', '/home/ubuntu/cephtest')
-
-def get_ceph_binary_url(package=None,
- branch=None, tag=None, sha1=None, dist=None,
- flavor=None, format=None, arch=None):
- BASE = 'http://gitbuilder.ceph.com/{package}-{format}-{dist}-{arch}-{flavor}/'.format(
- package=package,
- flavor=flavor,
- arch=arch,
- format=format,
- dist=dist
- )
-
- if sha1 is not None:
- assert branch is None, "cannot set both sha1 and branch"
- assert tag is None, "cannot set both sha1 and tag"
- else:
- # gitbuilder uses remote-style ref names for branches, mangled to
- # have underscores instead of slashes; e.g. origin_master
- if tag is not None:
- ref = tag
- assert branch is None, "cannot set both branch and tag"
- else:
- if branch is None:
- branch = 'master'
- ref = branch
-
- sha1_url = urlparse.urljoin(BASE, 'ref/{ref}/sha1'.format(ref=ref))
- log.debug('Translating ref to sha1 using url %s', sha1_url)
-
- try:
- sha1_fp = urllib2.urlopen(sha1_url)
- sha1 = sha1_fp.read().rstrip('\n')
- sha1_fp.close()
- except urllib2.HTTPError as e:
- log.error('Failed to get url %s', sha1_url)
- raise e
-
- log.debug('Using %s %s sha1 %s', package, format, sha1)
- bindir_url = urlparse.urljoin(BASE, 'sha1/{sha1}/'.format(sha1=sha1))
- return (sha1, bindir_url)
-
-def feed_many_stdins(fp, processes):
- while True:
- data = fp.read(8192)
- if not data:
- break
- for proc in processes:
- proc.stdin.write(data)
-
-def feed_many_stdins_and_close(fp, processes):
- feed_many_stdins(fp, processes)
- for proc in processes:
- proc.stdin.close()
-
-def get_mons(roles, ips):
- mons = {}
- mon_ports = {}
- mon_id = 0
- for idx, roles in enumerate(roles):
- for role in roles:
- if not role.startswith('mon.'):
- continue
- if ips[idx] not in mon_ports:
- mon_ports[ips[idx]] = 6789
- else:
- mon_ports[ips[idx]] += 1
- addr = '{ip}:{port}'.format(
- ip=ips[idx],
- port=mon_ports[ips[idx]],
- )
- mon_id += 1
- mons[role] = addr
- assert mons
- return mons
-
-def generate_caps(type_):
- defaults = dict(
- osd=dict(
- mon='allow *',
- osd='allow *',
- ),
- mds=dict(
- mon='allow *',
- osd='allow *',
- mds='allow',
- ),
- client=dict(
- mon='allow rw',
- osd='allow rwx',
- mds='allow',
- ),
- )
- for subsystem, capability in defaults[type_].items():
- yield '--cap'
- yield subsystem
- yield capability
-
-def skeleton_config(ctx, roles, ips):
- """
- Returns a ConfigObj that's prefilled with a skeleton config.
-
- Use conf[section][key]=value or conf.merge to change it.
-
- Use conf.write to write it out, override .filename first if you want.
- """
- path = os.path.join(os.path.dirname(__file__), 'ceph.conf.template')
- t = open(path, 'r')
- skconf = t.read().format(testdir=get_testdir(ctx))
- conf = configobj.ConfigObj(StringIO(skconf), file_error=True)
- mons = get_mons(roles=roles, ips=ips)
- for role, addr in mons.iteritems():
- conf.setdefault(role, {})
- conf[role]['mon addr'] = addr
- # set up standby mds's
- for roles_subset in roles:
- for role in roles_subset:
- if role.startswith('mds.'):
- conf.setdefault(role, {})
- if role.find('-s-') != -1:
- standby_mds = role[role.find('-s-')+3:]
- conf[role]['mds standby for name'] = standby_mds
- return conf
-
-def roles_of_type(roles_for_host, type_):
- prefix = '{type}.'.format(type=type_)
- for name in roles_for_host:
- if not name.startswith(prefix):
- continue
- id_ = name[len(prefix):]
- yield id_
-
-def all_roles(cluster):
- for _, roles_for_host in cluster.remotes.iteritems():
- for name in roles_for_host:
- yield name
-
-def all_roles_of_type(cluster, type_):
- prefix = '{type}.'.format(type=type_)
- for _, roles_for_host in cluster.remotes.iteritems():
- for name in roles_for_host:
- if not name.startswith(prefix):
- continue
- id_ = name[len(prefix):]
- yield id_
-
-def is_type(type_):
- """
- Returns a matcher function for whether role is of type given.
- """
- prefix = '{type}.'.format(type=type_)
- def _is_type(role):
- return role.startswith(prefix)
- return _is_type
-
-def num_instances_of_type(cluster, type_):
- remotes_and_roles = cluster.remotes.items()
- roles = [roles for (remote, roles) in remotes_and_roles]
- prefix = '{type}.'.format(type=type_)
- num = sum(sum(1 for role in hostroles if role.startswith(prefix)) for hostroles in roles)
- return num
-
-def create_simple_monmap(ctx, remote, conf):
- """
- Writes a simple monmap based on current ceph.conf into /monmap.
-
- Assumes ceph_conf is up to date.
-
- Assumes mon sections are named "mon.*", with the dot.
- """
- def gen_addresses():
- for section, data in conf.iteritems():
- PREFIX = 'mon.'
- if not section.startswith(PREFIX):
- continue
- name = section[len(PREFIX):]
- addr = data['mon addr']
- yield (name, addr)
-
- addresses = list(gen_addresses())
- assert addresses, "There are no monitors in config!"
- log.debug('Ceph mon addresses: %s', addresses)
-
- testdir = get_testdir(ctx)
- args = [
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
- 'ceph-coverage',
- '{tdir}/archive/coverage'.format(tdir=testdir),
- 'monmaptool',
- '--create',
- '--clobber',
- ]
- for (name, addr) in addresses:
- args.extend(('--add', name, addr))
- args.extend([
- '--print',
- '{tdir}/monmap'.format(tdir=testdir),
- ])
- remote.run(
- args=args,
- )
-
-def write_file(remote, path, data):
- remote.run(
- args=[
- 'python',
- '-c',
- 'import shutil, sys; shutil.copyfileobj(sys.stdin, file(sys.argv[1], "wb"))',
- path,
- ],
- stdin=data,
- )
-
-def sudo_write_file(remote, path, data, perms=None):
- permargs = []
- if perms:
- permargs=[run.Raw('&&'), 'sudo', 'chmod', perms, path]
- remote.run(
- args=[
- 'sudo',
- 'python',
- '-c',
- 'import shutil, sys; shutil.copyfileobj(sys.stdin, file(sys.argv[1], "wb"))',
- path,
- ] + permargs,
- stdin=data,
- )
-
-def move_file(remote, from_path, to_path, sudo=False):
-
- # need to stat the file first, to make sure we
- # maintain the same permissions
- args = []
- if sudo:
- args.append('sudo')
- args.extend([
- 'stat',
- '-c',
- '\"%a\"',
- to_path
- ])
- proc = remote.run(
- args=args,
- stdout=StringIO(),
- )
- perms = proc.stdout.getvalue().rstrip().strip('\"')
-
- args = []
- if sudo:
- args.append('sudo')
- args.extend([
- 'mv',
- '--',
- from_path,
- to_path,
- ])
- proc = remote.run(
- args=args,
- stdout=StringIO(),
- )
-
- # reset the file back to the original permissions
- args = []
- if sudo:
- args.append('sudo')
- args.extend([
- 'chmod',
- perms,
- to_path,
- ])
- proc = remote.run(
- args=args,
- stdout=StringIO(),
- )
-
-def delete_file(remote, path, sudo=False, force=False):
- args = []
- if sudo:
- args.append('sudo')
- args.extend(['rm'])
- if force:
- args.extend(['-f'])
- args.extend([
- '--',
- path,
- ])
- proc = remote.run(
- args=args,
- stdout=StringIO(),
- )
-
-def remove_lines_from_file(remote, path, line_is_valid_test, string_to_test_for):
- # read in the specified file
- in_data = get_file(remote, path, False)
- out_data = ""
-
- first_line = True
- # use the 'line_is_valid_test' function to remove unwanted lines
- for line in in_data.split('\n'):
- if line_is_valid_test(line, string_to_test_for):
- if not first_line:
- out_data += '\n'
- else:
- first_line = False
-
- out_data += '{line}'.format(line=line)
-
- else:
- log.info('removing line: {bad_line}'.format(bad_line=line))
-
- # get a temp file path on the remote host to write to,
- # we don't want to blow away the remote file and then have the
- # network drop out
- temp_file_path = remote_mktemp(remote)
-
- # write out the data to a temp file
- write_file(remote, temp_file_path, out_data)
-
- # then do a 'mv' to the actual file location
- move_file(remote, temp_file_path, path)
-
-def append_lines_to_file(remote, path, lines, sudo=False):
- temp_file_path = remote_mktemp(remote)
-
- data = get_file(remote, path, sudo)
-
- # add the additional data and write it back out, using a temp file
- # in case of connectivity of loss, and then mv it to the
- # actual desired location
- data += lines
- temp_file_path
- write_file(remote, temp_file_path, data)
-
- # then do a 'mv' to the actual file location
- move_file(remote, temp_file_path, path)
-
-def remote_mktemp(remote, sudo=False):
- args = []
- if sudo:
- args.append('sudo')
- args.extend([
- 'python',
- '-c',
- 'import os; import tempfile; (fd,fname) = tempfile.mkstemp(); os.close(fd); print fname.rstrip()'
- ])
- proc = remote.run(
- args=args,
- stdout=StringIO(),
- )
- data = proc.stdout.getvalue()
- return data
-
-def create_file(remote, path, data="", permissions=str(644), sudo=False):
- """
- Create a file on the remote host.
- """
- args = []
- if sudo:
- args.append('sudo')
- args.extend([
- 'touch',
- path,
- run.Raw('&&'),
- 'chmod',
- permissions,
- '--',
- path
- ])
- proc = remote.run(
- args=args,
- stdout=StringIO(),
- )
- # now write out the data if any was passed in
- if "" != data:
- append_lines_to_file(remote, path, data, sudo)
-
-def get_file(remote, path, sudo=False):
- """
- Read a file from remote host into memory.
- """
- args = []
- if sudo:
- args.append('sudo')
- args.extend([
- 'cat',
- '--',
- path,
- ])
- proc = remote.run(
- args=args,
- stdout=StringIO(),
- )
- data = proc.stdout.getvalue()
- return data
-
-def pull_directory(remote, remotedir, localdir):
- """
- Copy a remote directory to a local directory.
- """
- log.debug('Transferring archived files from %s:%s to %s',
- remote.shortname, remotedir, localdir)
- if not os.path.exists(localdir):
- os.mkdir(localdir)
- proc = remote.run(
- args=[
- 'sudo',
- 'tar',
- 'c',
- '-f', '-',
- '-C', remotedir,
- '--',
- '.',
- ],
- stdout=run.PIPE,
- wait=False,
- )
- tar = tarfile.open(mode='r|', fileobj=proc.stdout)
- while True:
- ti = tar.next()
- if ti is None:
- break
-
- if ti.isdir():
- # ignore silently; easier to just create leading dirs below
- pass
- elif ti.isfile():
- sub = safepath.munge(ti.name)
- safepath.makedirs(root=localdir, path=os.path.dirname(sub))
- tar.makefile(ti, targetpath=os.path.join(localdir, sub))
- else:
- if ti.isdev():
- type_ = 'device'
- elif ti.issym():
- type_ = 'symlink'
- elif ti.islnk():
- type_ = 'hard link'
- else:
- type_ = 'unknown'
- log.info('Ignoring tar entry: %r type %r', ti.name, type_)
- continue
- proc.exitstatus.get()
-
-def pull_directory_tarball(remote, remotedir, localfile):
- """
- Copy a remote directory to a local tarball.
- """
- log.debug('Transferring archived files from %s:%s to %s',
- remote.shortname, remotedir, localfile)
- out = open(localfile, 'w')
- proc = remote.run(
- args=[
- 'sudo',
- 'tar',
- 'cz',
- '-f', '-',
- '-C', remotedir,
- '--',
- '.',
- ],
- stdout=out,
- wait=False,
- )
- proc.exitstatus.get()
-
-# returns map of devices to device id links:
-# /dev/sdb: /dev/disk/by-id/wwn-0xf00bad
-def get_wwn_id_map(remote, devs):
- stdout = None
- try:
- r = remote.run(
- args=[
- 'ls',
- '-l',
- '/dev/disk/by-id/wwn-*',
- ],
- stdout=StringIO(),
- )
- stdout = r.stdout.getvalue()
- except:
- log.error('Failed to get wwn devices! Using /dev/sd* devices...')
- return dict((d,d) for d in devs)
-
- devmap = {}
-
- # lines will be:
- # lrwxrwxrwx 1 root root 9 Jan 22 14:58 /dev/disk/by-id/wwn-0x50014ee002ddecaf -> ../../sdb
- for line in stdout.splitlines():
- comps = line.split(' ')
- # comps[-1] should be:
- # ../../sdb
- rdev = comps[-1]
- # translate to /dev/sdb
- dev='/dev/{d}'.format(d=rdev.split('/')[-1])
-
- # comps[-3] should be:
- # /dev/disk/by-id/wwn-0x50014ee002ddecaf
- iddev = comps[-3]
-
- if dev in devs:
- devmap[dev] = iddev
-
- return devmap
-
-def get_scratch_devices(remote):
- """
- Read the scratch disk list from remote host
- """
- devs = []
- try:
- file_data = get_file(remote, "/scratch_devs")
- devs = file_data.split()
- except:
- r = remote.run(
- args=['ls', run.Raw('/dev/[sv]d?')],
- stdout=StringIO()
- )
- devs = r.stdout.getvalue().strip().split('\n')
-
- #Remove root device (vm guests) from the disk list
- for dev in devs:
- if 'vda' in dev:
- devs.remove(dev)
- log.warn("Removing root device: %s from device list" % dev)
-
- log.debug('devs={d}'.format(d=devs))
-
- retval = []
- for dev in devs:
- try:
- remote.run(
- args=[
- # node exists
- 'stat',
- dev,
- run.Raw('&&'),
- # readable
- 'sudo', 'dd', 'if=%s' % dev, 'of=/dev/null', 'count=1',
- run.Raw('&&'),
- # not mounted
- run.Raw('!'),
- 'mount',
- run.Raw('|'),
- 'grep', '-q', dev,
- ]
- )
- retval.append(dev)
- except:
- pass
- return retval
-
-def wait_until_healthy(ctx, remote):
- """Wait until a Ceph cluster is healthy."""
- testdir = get_testdir(ctx)
- while True:
- r = remote.run(
- args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
- 'ceph-coverage',
- '{tdir}/archive/coverage'.format(tdir=testdir),
- 'ceph',
- 'health',
- ],
- stdout=StringIO(),
- logger=log.getChild('health'),
- )
- out = r.stdout.getvalue()
- log.debug('Ceph health: %s', out.rstrip('\n'))
- if out.split(None, 1)[0] == 'HEALTH_OK':
- break
- time.sleep(1)
-
-def wait_until_osds_up(ctx, cluster, remote):
- """Wait until all Ceph OSDs are booted."""
- num_osds = num_instances_of_type(cluster, 'osd')
- testdir = get_testdir(ctx)
- while True:
- r = remote.run(
- args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
- 'ceph-coverage',
- '{tdir}/archive/coverage'.format(tdir=testdir),
- 'ceph',
- 'osd', 'dump', '--format=json'
- ],
- stdout=StringIO(),
- logger=log.getChild('health'),
- )
- out = r.stdout.getvalue()
- j = json.loads('\n'.join(out.split('\n')[1:]))
- up = len(j['osds'])
- log.debug('%d of %d OSDs are up' % (up, num_osds))
- if up == num_osds:
- break
- time.sleep(1)
-
-def wait_until_fuse_mounted(remote, fuse, mountpoint):
- while True:
- proc = remote.run(
- args=[
- 'stat',
- '--file-system',
- '--printf=%T\n',
- '--',
- mountpoint,
- ],
- stdout=StringIO(),
- )
- fstype = proc.stdout.getvalue().rstrip('\n')
- if fstype == 'fuseblk':
- break
- log.debug('ceph-fuse not yet mounted, got fs type {fstype!r}'.format(fstype=fstype))
-
- # it shouldn't have exited yet; exposes some trivial problems
- assert not fuse.exitstatus.ready()
-
- time.sleep(5)
- log.info('ceph-fuse is mounted on %s', mountpoint)
-
-def reconnect(ctx, timeout, remotes=None):
- """
- Connect to all the machines in ctx.cluster.
-
- Presumably, some of them won't be up. Handle this
- by waiting for them, unless the wait time exceeds
- the specified timeout.
-
- ctx needs to contain the cluster of machines you
- wish it to try and connect to, as well as a config
- holding the ssh keys for each of them. As long as it
- contains this data, you can construct a context
- that is a subset of your full cluster.
- """
- log.info('Re-opening connections...')
- starttime = time.time()
-
- if remotes:
- need_reconnect = remotes
- else:
- need_reconnect = ctx.cluster.remotes.keys()
-
- for r in need_reconnect:
- r.ssh.close()
-
- while need_reconnect:
- for remote in need_reconnect:
- try:
- log.info('trying to connect to %s', remote.name)
- key = ctx.config['targets'][remote.name]
- from .orchestra import connection
- remote.ssh = connection.connect(
- user_at_host=remote.name,
- host_key=key,
- keep_alive=True,
- )
- except Exception:
- if time.time() - starttime > timeout:
- raise
- else:
- need_reconnect.remove(remote)
-
- log.debug('waited {elapsed}'.format(elapsed=str(time.time() - starttime)))
- time.sleep(1)
-
-def write_secret_file(ctx, remote, role, keyring, filename):
- testdir = get_testdir(ctx)
- remote.run(
- args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
- 'ceph-coverage',
- '{tdir}/archive/coverage'.format(tdir=testdir),
- 'ceph-authtool',
- '--name={role}'.format(role=role),
- '--print-key',
- keyring,
- run.Raw('>'),
- filename,
- ],
- )
-
-def get_clients(ctx, roles):
- for role in roles:
- assert isinstance(role, basestring)
- PREFIX = 'client.'
- assert role.startswith(PREFIX)
- id_ = role[len(PREFIX):]
- (remote,) = ctx.cluster.only(role).remotes.iterkeys()
- yield (id_, remote)
-
-def get_user():
- return getpass.getuser() + '@' + socket.gethostname()
-
-
-def read_config(ctx):
- ctx.teuthology_config = {}
- filename = os.path.join(os.environ['HOME'], '.teuthology.yaml')
-
- if not os.path.exists(filename):
- log.debug("%s not found", filename)
- return
-
- with file(filename) as f:
- g = yaml.safe_load_all(f)
- for new in g:
- ctx.teuthology_config.update(new)
-
-def get_mon_names(ctx):
- mons = []
- for remote, roles in ctx.cluster.remotes.items():
- for role in roles:
- if not role.startswith('mon.'):
- continue
- mons.append(role)
- return mons
-
-# return the "first" mon (alphanumerically, for lack of anything better)
-def get_first_mon(ctx, config):
- firstmon = sorted(get_mon_names(ctx))[0]
- assert firstmon
- return firstmon
-
-def replace_all_with_clients(cluster, config):
- """
- Converts a dict containing a key all to one
- mapping all clients to the value of config['all']
- """
- assert isinstance(config, dict), 'config must be a dict'
- if 'all' not in config:
- return config
- norm_config = {}
- assert len(config) == 1, \
- "config cannot have 'all' and specific clients listed"
- for client in all_roles_of_type(cluster, 'client'):
- norm_config['client.{id}'.format(id=client)] = config['all']
- return norm_config
-
-def deep_merge(a, b):
- if a is None:
- return b
- if b is None:
- return a
- if isinstance(a, list):
- assert isinstance(b, list)
- a.extend(b)
- return a
- if isinstance(a, dict):
- assert isinstance(b, dict)
- for (k, v) in b.iteritems():
- if k in a:
- a[k] = deep_merge(a[k], v)
- else:
- a[k] = v
- return a
- return b
-
-def get_valgrind_args(testdir, name, v):
- if v is None:
- return []
- if not isinstance(v, list):
- v = [v]
- val_path = '/var/log/ceph/valgrind'.format(tdir=testdir)
- if '--tool=memcheck' in v or '--tool=helgrind' in v:
- extra_args = [
- '{tdir}/chdir-coredump'.format(tdir=testdir),
- 'valgrind',
- '--suppressions={tdir}/valgrind.supp'.format(tdir=testdir),
- '--xml=yes',
- '--xml-file={vdir}/{n}.log'.format(vdir=val_path, n=name)
- ]
- else:
- extra_args = [
- '{tdir}/chdir-coredump'.format(tdir=testdir),
- 'valgrind',
- '--suppressions={tdir}/valgrind.supp'.format(tdir=testdir),
- '--log-file={vdir}/{n}.log'.format(vdir=val_path, n=name)
- ]
- extra_args.extend(v)
- log.debug('running %s under valgrind with args %s', name, extra_args)
- return extra_args
-
-def stop_daemons_of_type(ctx, type_):
- log.info('Shutting down %s daemons...' % type_)
- exc_info = (None, None, None)
- for daemon in ctx.daemons.iter_daemons_of_role(type_):
- try:
- daemon.stop()
- except (run.CommandFailedError,
- run.CommandCrashedError,
- run.ConnectionLostError):
- exc_info = sys.exc_info()
- log.exception('Saw exception from %s.%s', daemon.role, daemon.id_)
- if exc_info != (None, None, None):
- raise exc_info[0], exc_info[1], exc_info[2]
-
-def get_system_type(remote):
- """
- Return this system type (deb or rpm)
- """
- r = remote.run(
- args=[
- 'sudo','lsb_release', '-is',
- ],
- stdout=StringIO(),
- )
- system_value = r.stdout.getvalue().strip()
- log.debug("System to be installed: %s" % system_value)
- if system_value in ['Ubuntu','Debian']:
- return "deb"
- if system_value in ['CentOS','Fedora','RedHatEnterpriseServer']:
- return "rpm"
- return system_value
-
-def get_distro(ctx):
- try:
- os_type = ctx.config.get('os_type', ctx.os_type)
- except AttributeError:
- os_type = 'ubuntu'
- try:
- return ctx.config['downburst'].get('distro', os_type)
- except KeyError:
- return os_type
- except AttributeError:
- return ctx.os_type
diff --git a/teuthology/nuke.py b/teuthology/nuke.py
deleted file mode 100644
index 82389f99d..000000000
--- a/teuthology/nuke.py
+++ /dev/null
@@ -1,476 +0,0 @@
-import argparse
-import yaml
-
-def parse_args():
- from teuthology.run import config_file
- from teuthology.run import MergeConfig
-
- parser = argparse.ArgumentParser(description='Reset test machines')
- parser.add_argument(
- '-v', '--verbose',
- action='store_true', default=None,
- help='be more verbose'
- )
- parser.add_argument(
- '-t', '--targets',
- nargs='+',
- type=config_file,
- action=MergeConfig,
- default={},
- dest='config',
- help='yaml config containing machines to nuke',
- )
- parser.add_argument(
- '-a', '--archive',
- metavar='DIR',
- help='archive path for a job to kill and nuke',
- )
- parser.add_argument(
- '--owner',
- help='job owner',
- )
- parser.add_argument(
- '-p','--pid',
- type=int,
- default=False,
- help='pid of the process to be killed',
- )
- parser.add_argument(
- '-r', '--reboot-all',
- action='store_true',
- default=False,
- help='reboot all machines',
- )
- parser.add_argument(
- '-s', '--synch-clocks',
- action='store_true',
- default=False,
- help='synchronize clocks on all machines',
- )
- parser.add_argument(
- '-u', '--unlock',
- action='store_true',
- default=False,
- help='Unlock each successfully nuked machine, and output targets that'
- 'could not be nuked.'
- )
- parser.add_argument(
- '-n', '--name',
- metavar='NAME',
- help='Name of run to cleanup'
- )
- parser.add_argument(
- '-i', '--noipmi',
- action='store_true', default=False,
- help='Skip ipmi checking'
- )
- args = parser.parse_args()
- return args
-
-def shutdown_daemons(ctx, log):
- from .orchestra import run
- nodes = {}
- for remote in ctx.cluster.remotes.iterkeys():
- proc = remote.run(
- args=[
- 'if', 'grep', '-q', 'ceph-fuse', '/etc/mtab', run.Raw(';'),
- 'then',
- 'grep', 'ceph-fuse', '/etc/mtab', run.Raw('|'),
- 'grep', '-o', " /.* fuse", run.Raw('|'),
- 'grep', '-o', "/.* ", run.Raw('|'),
- 'xargs', 'sudo', 'fusermount', '-u', run.Raw(';'),
- 'fi',
- run.Raw(';'),
- 'sudo',
- 'killall',
- '--quiet',
- 'ceph-mon',
- 'ceph-osd',
- 'ceph-mds',
- 'ceph-fuse',
- 'ceph-disk',
- 'radosgw',
- 'ceph_test_rados',
- 'rados',
- 'apache2',
- run.Raw('||'),
- 'true', # ignore errors from ceph binaries not being found
- ],
- wait=False,
- )
- nodes[remote.name] = proc
-
- for name, proc in nodes.iteritems():
- log.info('Waiting for %s to finish shutdowns...', name)
- proc.exitstatus.get()
-
-def find_kernel_mounts(ctx, log):
- from .orchestra import run
- nodes = {}
- log.info('Looking for kernel mounts to handle...')
- for remote in ctx.cluster.remotes.iterkeys():
- proc = remote.run(
- args=[
- 'grep', '-q', ' ceph ' , '/etc/mtab',
- run.Raw('||'),
- 'grep', '-q', '^/dev/rbd' , '/etc/mtab',
- ],
- wait=False,
- )
- nodes[remote] = proc
- kernel_mounts = list()
- for remote, proc in nodes.iteritems():
- try:
- proc.exitstatus.get()
- log.debug('kernel mount exists on %s', remote.name)
- kernel_mounts.append(remote)
- except run.CommandFailedError: # no mounts!
- log.debug('no kernel mount on %s', remote.name)
-
- return kernel_mounts
-
-def remove_kernel_mounts(ctx, kernel_mounts, log):
- """
- properly we should be able to just do a forced unmount,
- but that doesn't seem to be working, so you should reboot instead
- """
- from .orchestra import run
- nodes = {}
- for remote in kernel_mounts:
- log.info('clearing kernel mount from %s', remote.name)
- proc = remote.run(
- args=[
- 'grep', 'ceph', '/etc/mtab', run.Raw('|'),
- 'grep', '-o', "on /.* type", run.Raw('|'),
- 'grep', '-o', "/.* ", run.Raw('|'),
- 'xargs', '-r',
- 'sudo', 'umount', '-f', run.Raw(';'),
- 'fi'
- ],
- wait=False
- )
- nodes[remote] = proc
-
- for remote, proc in nodes:
- proc.exitstatus.get()
-
-def remove_osd_mounts(ctx, log):
- """
- unmount any osd data mounts (scratch disks)
- """
- from .orchestra import run
- ctx.cluster.run(
- args=[
- 'grep',
- '/var/lib/ceph/osd/',
- '/etc/mtab',
- run.Raw('|'),
- 'awk', '{print $2}', run.Raw('|'),
- 'xargs', '-r',
- 'sudo', 'umount', run.Raw(';'),
- 'true'
- ],
- )
-
-def remove_osd_tmpfs(ctx, log):
- """
- unmount tmpfs mounts
- """
- from .orchestra import run
- ctx.cluster.run(
- args=[
- 'egrep', 'tmpfs\s+/mnt', '/etc/mtab', run.Raw('|'),
- 'awk', '{print $2}', run.Raw('|'),
- 'xargs', '-r',
- 'sudo', 'umount', run.Raw(';'),
- 'true'
- ],
- )
-
-def reboot(ctx, remotes, log):
- import time
- nodes = {}
- for remote in remotes:
- log.info('rebooting %s', remote.name)
- proc = remote.run( # note use of -n to force a no-sync reboot
- args=['sudo', 'reboot', '-f', '-n'],
- wait=False
- )
- nodes[remote] = proc
- # we just ignore these procs because reboot -f doesn't actually
- # send anything back to the ssh client!
- #for remote, proc in nodes.iteritems():
- #proc.exitstatus.get()
- from teuthology.misc import reconnect
- if remotes:
- log.info('waiting for nodes to reboot')
- time.sleep(5) #if we try and reconnect too quickly, it succeeds!
- reconnect(ctx, 480) #allow 8 minutes for the reboots
-
-def reset_syslog_dir(ctx, log):
- from .orchestra import run
- nodes = {}
- for remote in ctx.cluster.remotes.iterkeys():
- proc = remote.run(
- args=[
- 'if', 'test', '-e', '/etc/rsyslog.d/80-cephtest.conf',
- run.Raw(';'),
- 'then',
- 'sudo', 'rm', '-f', '--', '/etc/rsyslog.d/80-cephtest.conf',
- run.Raw('&&'),
- 'sudo', 'service', 'rsyslog', 'restart',
- run.Raw(';'),
- 'fi',
- run.Raw(';'),
- ],
- wait=False,
- )
- nodes[remote.name] = proc
-
- for name, proc in nodes.iteritems():
- log.info('Waiting for %s to restart syslog...', name)
- proc.exitstatus.get()
-
-def dpkg_configure(ctx, log):
- from .orchestra import run
- nodes = {}
- for remote in ctx.cluster.remotes.iterkeys():
- proc = remote.run(
- args=[
- 'sudo', 'dpkg', '--configure', '-a',
- run.Raw('&&'),
- 'sudo', 'apt-get', '-f', 'install',
- run.Raw('||'),
- ':',
- ],
- wait=False,
- )
- nodes[remote.name] = proc
-
- for name, proc in nodes.iteritems():
- log.info('Waiting for %s to dpkg --configure -a and apt-get -f install...', name)
- proc.exitstatus.get()
-
-def remove_installed_packages(ctx, log):
- from teuthology.task import install as install_task
-
- dpkg_configure(ctx, log)
- config = {'project': 'ceph'}
- install_task.remove_packages(ctx, config,
- {"deb": install_task.deb_packages['ceph'],
- "rpm": install_task.rpm_packages['ceph']})
- install_task.remove_sources(ctx, config)
- install_task.purge_data(ctx)
-
-def remove_testing_tree(ctx, log):
- from teuthology.misc import get_testdir_base
- from .orchestra import run
- nodes = {}
- for remote in ctx.cluster.remotes.iterkeys():
- proc = remote.run(
- args=[
- 'sudo', 'rm', '-rf', get_testdir_base(ctx),
- # just for old time's sake
- run.Raw('&&'),
- 'sudo', 'rm', '-rf', '/tmp/cephtest',
- run.Raw('&&'),
- 'sudo', 'rm', '-rf', '/home/ubuntu/cephtest',
- run.Raw('&&'),
- 'sudo', 'rm', '-rf', '/etc/ceph',
- ],
- wait=False,
- )
- nodes[remote.name] = proc
-
- for name, proc in nodes.iteritems():
- log.info('Waiting for %s to clear filesystem...', name)
- proc.exitstatus.get()
-
-def synch_clocks(remotes, log):
- from .orchestra import run
- nodes = {}
- for remote in remotes:
- proc = remote.run(
- args=[
- 'sudo', 'service', 'ntp', 'stop',
- run.Raw('&&'),
- 'sudo', 'ntpdate-debian',
- run.Raw('&&'),
- 'sudo', 'hwclock', '--systohc', '--utc',
- run.Raw('&&'),
- 'sudo', 'service', 'ntp', 'start',
- run.Raw('||'),
- 'true', # ignore errors; we may be racing with ntpd startup
- ],
- wait=False,
- )
- nodes[remote.name] = proc
- for name, proc in nodes.iteritems():
- log.info('Waiting for clock to synchronize on %s...', name)
- proc.exitstatus.get()
-
-def main():
- from gevent import monkey; monkey.patch_all(dns=False)
- from .orchestra import monkey; monkey.patch_all()
- from teuthology.run import config_file
-
- import logging
-
- log = logging.getLogger(__name__)
-
- ctx = parse_args()
-
- loglevel = logging.INFO
- if ctx.verbose:
- loglevel = logging.DEBUG
-
- logging.basicConfig(
- level=loglevel,
- )
-
- if ctx.archive:
- ctx.config = config_file(ctx.archive + '/config.yaml')
- if not ctx.pid:
- ctx.pid = int(open(ctx.archive + '/pid').read().rstrip('\n'))
- if not ctx.owner:
- ctx.owner = open(ctx.archive + '/owner').read().rstrip('\n')
-
- from teuthology.misc import read_config
- read_config(ctx)
-
- log.info('\n '.join(['targets:', ] + yaml.safe_dump(ctx.config['targets'], default_flow_style=False).splitlines()))
-
- if ctx.owner is None:
- from teuthology.misc import get_user
- ctx.owner = get_user()
-
- if ctx.pid:
- if ctx.archive:
- import os
- log.info('Killing teuthology process at pid %d', ctx.pid)
- os.system('grep -q %s /proc/%d/cmdline && sudo kill %d' % (
- ctx.archive,
- ctx.pid,
- ctx.pid))
- else:
- import subprocess
- subprocess.check_call(["kill", "-9", str(ctx.pid)]);
-
- nuke(ctx, log, ctx.unlock, ctx.synch_clocks, ctx.reboot_all, ctx.noipmi)
-
-def nuke(ctx, log, should_unlock, sync_clocks=True, reboot_all=True,
- noipmi=False):
- from teuthology.parallel import parallel
- total_unnuked = {}
- with parallel() as p:
- for target, hostkey in ctx.config['targets'].iteritems():
- p.spawn(
- nuke_one,
- ctx,
- {target: hostkey},
- log,
- should_unlock,
- sync_clocks,
- reboot_all,
- ctx.config.get('check-locks', True),
- noipmi,
- )
- for unnuked in p:
- if unnuked:
- total_unnuked.update(unnuked)
- if total_unnuked:
- log.error('Could not nuke the following targets:\n' + '\n '.join(['targets:', ] + yaml.safe_dump(total_unnuked, default_flow_style=False).splitlines()))
-
-def nuke_one(ctx, targets, log, should_unlock, synch_clocks, reboot_all,
- check_locks, noipmi):
- from teuthology.lock import unlock
- ret = None
- ctx = argparse.Namespace(
- config=dict(targets=targets),
- owner=ctx.owner,
- check_locks=check_locks,
- synch_clocks=synch_clocks,
- reboot_all=reboot_all,
- teuthology_config=ctx.teuthology_config,
- name=ctx.name,
- noipmi=noipmi,
- )
- try:
- nuke_helper(ctx, log)
- except:
- log.exception('Could not nuke all targets in %s', targets)
- # not re-raising the so that parallel calls aren't killed
- ret = targets
- else:
- if should_unlock:
- for target in targets.keys():
- unlock(ctx, target, ctx.owner)
- return ret
-
-def nuke_helper(ctx, log):
- # ensure node is up with ipmi
- from teuthology.orchestra import remote
-
- (target,) = ctx.config['targets'].keys()
- host = target.split('@')[-1]
- shortname = host.split('.')[0]
- if 'vpm' in shortname:
- return
- log.debug('shortname: %s' % shortname)
- log.debug('{ctx}'.format(ctx=ctx))
- if not ctx.noipmi and 'ipmi_user' in ctx.teuthology_config:
- console = remote.getRemoteConsole(name=host,
- ipmiuser=ctx.teuthology_config['ipmi_user'],
- ipmipass=ctx.teuthology_config['ipmi_password'],
- ipmidomain=ctx.teuthology_config['ipmi_domain'])
- cname = '{host}.{domain}'.format(host=shortname, domain=ctx.teuthology_config['ipmi_domain'])
- log.info('checking console status of %s' % cname)
- if not console.check_status():
- # not powered on or can't get IPMI status. Try to power on
- console.power_on()
- # try to get status again, waiting for login prompt this time
- log.info('checking console status of %s' % cname)
- if not console.check_status(100):
- log.error('Failed to get console status for %s, disabling console...' % cname)
- log.info('console ready on %s' % cname)
- else:
- log.info('console ready on %s' % cname)
-
- from teuthology.task.internal import check_lock, connect
- if ctx.check_locks:
- check_lock(ctx, None)
- connect(ctx, None)
-
- log.info('Unmount ceph-fuse and killing daemons...')
- shutdown_daemons(ctx, log)
- log.info('All daemons killed.')
-
- need_reboot = find_kernel_mounts(ctx, log)
-
- # no need to unmount anything if we're rebooting
- if ctx.reboot_all:
- need_reboot = ctx.cluster.remotes.keys()
- else:
- log.info('Unmount any osd data directories...')
- remove_osd_mounts(ctx, log)
- log.info('Unmount any osd tmpfs dirs...')
- remove_osd_tmpfs(ctx, log)
- #log.info('Dealing with any kernel mounts...')
- #remove_kernel_mounts(ctx, need_reboot, log)
-
- if need_reboot:
- reboot(ctx, need_reboot, log)
- log.info('All kernel mounts gone.')
-
- log.info('Synchronizing clocks...')
- if ctx.synch_clocks:
- need_reboot = ctx.cluster.remotes.keys()
- synch_clocks(need_reboot, log)
-
- log.info('Reseting syslog output locations...')
- reset_syslog_dir(ctx, log)
- log.info('Clearing filesystem of test data...')
- remove_testing_tree(ctx, log)
- log.info('Filesystem Cleared.')
- remove_installed_packages(ctx, log)
- log.info('Installed packages removed.')
diff --git a/teuthology/orchestra/cluster.py b/teuthology/orchestra/cluster.py
deleted file mode 100644
index df97d7a52..000000000
--- a/teuthology/orchestra/cluster.py
+++ /dev/null
@@ -1,105 +0,0 @@
-class Cluster(object):
- """
- Manage SSH connections to a cluster of machines.
- """
-
- def __init__(self, remotes=None):
- """
- Initialize
- """
- self.remotes = {}
- if remotes is not None:
- for remote, roles in remotes:
- self.add(remote, roles)
-
- def __repr__(self):
- remotes = [(k, v) for k,v in self.remotes.items()]
- remotes.sort(key=lambda tup: tup[0].name)
- remotes = '{' + ', '.join('{remote!r}: {roles!r}'.format(remote=k, roles=v) for k,v in remotes) + '}'
- return '{classname}(remotes={remotes})'.format(
- classname=self.__class__.__name__,
- remotes=remotes,
- )
-
- def __str__(self):
- remotes = list(self.remotes.items())
- remotes.sort(key=lambda tup: tup[0].name)
- remotes = ((k, ','.join(v)) for k,v in remotes)
- remotes = ('{k}[{v}]'.format(k=k, v=v) for k,v in remotes)
- return ' '.join(remotes)
-
- def add(self, remote, roles):
- if remote in self.remotes:
- raise RuntimeError(
- 'Remote {new!r} already found in remotes: {old!r}'.format(
- new=remote,
- old=self.remotes[remote],
- ),
- )
- self.remotes[remote] = list(roles)
-
- def run(self, **kwargs):
- """
- Run a command on all the nodes in this cluster.
-
- Goes through nodes in alphabetical order.
-
- If you don't specify wait=False, this will be sequentially.
-
- Returns a list of `RemoteProcess`.
- """
- remotes = sorted(self.remotes.iterkeys(), key=lambda rem: rem.name)
- return [remote.run(**kwargs) for remote in remotes]
-
- def only(self, *roles):
- """
- Return a cluster with only the remotes that have all of given roles.
-
- For roles given as strings, they are matched against the roles
- on a remote, and the remote passes the check only if all the
- roles listed are present.
-
- Argument can be callable, and will act as a match on roles of
- the remote. The matcher will be evaluated one role at a time,
- but a match on any role is good enough. Note that this is
- subtly diffent from the behavior of string roles, but is
- logical if you consider a callable to be similar to passing a
- non-string object with an `__eq__` method.
-
- For example::
-
- web = mycluster.only(lambda role: role.startswith('web-'))
- """
- c = self.__class__()
- want = frozenset(r for r in roles if not callable(r))
- matchers = [r for r in roles if callable(r)]
-
- for remote, has_roles in self.remotes.iteritems():
- # strings given as roles must all match
- if frozenset(has_roles) & want != want:
- # not a match
- continue
-
- # every matcher given must match at least one role
- if not all(
- any(matcher(role) for role in has_roles)
- for matcher in matchers
- ):
- continue
-
- c.add(remote, has_roles)
-
- return c
-
- def exclude(self, *roles):
- """
- Return a cluster *without* remotes that have all of given roles.
-
- This is the opposite of `only`.
- """
- matches = self.only(*roles)
- c = self.__class__()
- for remote, has_roles in self.remotes.iteritems():
- if remote not in matches.remotes:
- c.add(remote, has_roles)
- return c
diff --git a/teuthology/orchestra/connection.py b/teuthology/orchestra/connection.py
deleted file mode 100644
index 2473c19b1..000000000
--- a/teuthology/orchestra/connection.py
+++ /dev/null
@@ -1,49 +0,0 @@
-import base64
-import paramiko
-
-def split_user(user_at_host):
- try:
- user, host = user_at_host.rsplit('@', 1)
- except ValueError:
- user, host = None, user_at_host
- assert user != '', \
- "Bad input to split_user: {user_at_host!r}".format(user_at_host=user_at_host)
- return user, host
-
-def create_key(keytype, key):
- if keytype == 'ssh-rsa':
- return paramiko.rsakey.RSAKey(data=base64.decodestring(key))
- elif keytype == 'ssh-dss':
- return paramiko.dsskey.DSSKey(data=base64.decodestring(key))
- else:
- raise ValueError('keytype must be ssh-rsa or ssh-dsa')
-
-def connect(user_at_host, host_key=None, keep_alive=False,
- _SSHClient=None, _create_key=None):
- user, host = split_user(user_at_host)
- if _SSHClient is None:
- _SSHClient = paramiko.SSHClient
- ssh = _SSHClient()
- if host_key is None:
- ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
- if _create_key is None:
- _create_key = create_key
-
- if host_key is None:
- ssh.load_system_host_keys()
- else:
- keytype, key = host_key.split(' ', 1)
- ssh.get_host_keys().add(
- hostname=host,
- keytype=keytype,
- key=_create_key(keytype, key)
- )
-
- # just let the exceptions bubble up to caller
- ssh.connect(
- hostname=host,
- username=user,
- timeout=60,
- )
- ssh.get_transport().set_keepalive(keep_alive)
- return ssh
diff --git a/teuthology/orchestra/monkey.py b/teuthology/orchestra/monkey.py
deleted file mode 100644
index 33c692ad8..000000000
--- a/teuthology/orchestra/monkey.py
+++ /dev/null
@@ -1,47 +0,0 @@
-import logging
-
-log = logging.getLogger(__name__)
-
-def patch_001_paramiko_deprecation():
- """
- Silence an an unhelpful DeprecationWarning triggered by Paramiko.
-
- Not strictly a monkeypatch.
- """
- import warnings
- warnings.filterwarnings(
- category=DeprecationWarning,
- message='This application uses RandomPool,',
- action='ignore',
- )
-
-
-def patch_100_paramiko_log():
- """
- Silence some noise paramiko likes to log.
-
- Not strictly a monkeypatch.
- """
- logging.getLogger('paramiko.transport').setLevel(logging.WARNING)
-
-
-def patch_100_logger_getChild():
- """
- Imitate Python 2.7 feature Logger.getChild.
- """
- import logging
- if not hasattr(logging.Logger, 'getChild'):
- def getChild(self, name):
- return logging.getLogger('.'.join([self.name, name]))
- logging.Logger.getChild = getChild
-
-
-def patch_all():
- """
- Run all the patch_* functions in this module.
- """
- monkeys = [(k,v) for (k,v) in globals().iteritems() if k.startswith('patch_') and k != 'patch_all']
- monkeys.sort()
- for k,v in monkeys:
- log.debug('Patching %s', k)
- v()
diff --git a/teuthology/orchestra/remote.py b/teuthology/orchestra/remote.py
deleted file mode 100644
index 24baee27a..000000000
--- a/teuthology/orchestra/remote.py
+++ /dev/null
@@ -1,259 +0,0 @@
-from . import run
-from teuthology import misc
-import time
-
-class Remote(object):
- """
- A connection to a remote host.
-
- This is a higher-level wrapper around Paramiko's `SSHClient`.
- """
-
- # for unit tests to hook into
- _runner = staticmethod(run.run)
-
- def __init__(self, name, ssh, shortname=None, console=None):
- self.name = name
- self._shortname = shortname
- self.ssh = ssh
- self.console = console
-
- @property
- def shortname(self):
- name = self._shortname
- if name is None:
- name = self.name
- return name
-
- @property
- def system_type(self):
- return misc.get_system_type(self)
-
- def __str__(self):
- return self.shortname
-
- def __repr__(self):
- return '{classname}(name={name!r})'.format(
- classname=self.__class__.__name__,
- name=self.name,
- )
-
- def run(self, **kwargs):
- """
- This calls `orchestra.run.run` with our SSH client.
-
- TODO refactor to move run.run here?
- """
- r = self._runner(client=self.ssh, **kwargs)
- r.remote = self
- return r
-
-import pexpect
-import re
-import logging
-import libvirt
-from teuthology import lockstatus as ls
-
-log = logging.getLogger(__name__)
-
-def getShortName(name):
- hn = name.split('@')[-1]
- p = re.compile('([^.]+)\.?.*')
- return p.match(hn).groups()[0]
-
-class PhysicalConsole():
-
- def __init__(self, name, ipmiuser, ipmipass, ipmidomain, logfile=None, timeout=20):
- self.name = name
- self.shortname = getShortName(name)
- self.timeout = timeout
- self.logfile = None
- self.ipmiuser = ipmiuser
- self.ipmipass = ipmipass
- self.ipmidomain = ipmidomain
-
- def _exec(self, cmd):
- if not self.ipmiuser or not self.ipmipass or not self.ipmidomain:
- log.error('Must set ipmi_user, ipmi_password, and ipmi_domain in .teuthology.yaml')
- log.debug('pexpect command: ipmitool -H {s}.{dn} -I lanplus -U {ipmiuser} -P {ipmipass} {cmd}'.format(
- cmd=cmd,
- s=self.shortname,
- dn=self.ipmidomain,
- ipmiuser=self.ipmiuser,
- ipmipass=self.ipmipass))
-
- child = pexpect.spawn ('ipmitool -H {s}.{dn} -I lanplus -U {ipmiuser} -P {ipmipass} {cmd}'.format(
- cmd=cmd,
- s=self.shortname,
- dn=self.ipmidomain,
- ipmiuser=self.ipmiuser,
- ipmipass=self.ipmipass))
- if self.logfile:
- child.logfile = self.logfile
- return child
-
- def _exit_session(self, child, timeout=None):
- child.send('~.')
- t = timeout
- if not t:
- t = self.timeout
- r = child.expect(['terminated ipmitool', pexpect.TIMEOUT, pexpect.EOF], timeout=t)
- if r != 0:
- self._exec('sol deactivate')
-
- def _wait_for_login(self, timeout=None, attempts=6):
- log.debug('Waiting for login prompt on {s}'.format(s=self.shortname))
- # wait for login prompt to indicate boot completed
- t = timeout
- if not t:
- t = self.timeout
- for i in range(0, attempts):
- start = time.time()
- while time.time() - start < t:
- child = self._exec('sol activate')
- child.send('\n')
- log.debug('expect: {s} login'.format(s=self.shortname))
- r = child.expect(['{s} login: '.format(s=self.shortname), pexpect.TIMEOUT, pexpect.EOF], timeout=(t - (time.time() - start)))
- log.debug('expect before: {b}'.format(b=child.before))
- log.debug('expect after: {a}'.format(a=child.after))
-
- self._exit_session(child)
- if r == 0:
- return
- def check_power(self, state, timeout=None):
- # check power
- total_timeout = timeout
- if not total_timeout:
- total_timeout = self.timeout
- t = 1
- total = t
- ta = time.time()
- while total < total_timeout:
- c = self._exec('power status')
- r = c.expect(['Chassis Power is {s}'.format(s=state), pexpect.EOF, pexpect.TIMEOUT], timeout=t)
- tb = time.time()
- if r == 0:
- return True
- elif r == 1:
- # keep trying if EOF is reached, first sleep for remaining
- # timeout interval
- if tb - ta < t:
- time.sleep(t - (tb - ta))
- # go around again if EOF or TIMEOUT
- ta = tb
- t *= 2
- total += t
- return False
-
- # returns True if console is at login prompt
- def check_status(self, timeout=None):
- try :
- # check for login prompt at console
- self._wait_for_login(timeout)
- return True
- except Exception as e:
- log.info('Failed to get ipmi console status for {s}: {e}'.format(s=self.shortname, e=e))
- return False
-
- def power_cycle(self):
- log.info('Power cycling {s}'.format(s=self.shortname))
- child = self._exec('power cycle')
- child.expect('Chassis Power Control: Cycle', timeout=self.timeout)
- self._wait_for_login()
- log.info('Power cycle for {s} completed'.format(s=self.shortname))
-
- def hard_reset(self):
- log.info('Performing hard reset of {s}'.format(s=self.shortname))
- start = time.time()
- while time.time() - start < self.timeout:
- child = self._exec('power reset')
- r = child.expect(['Chassis Power Control: Reset', pexpect.EOF], timeout=self.timeout)
- if r == 0:
- break
- self._wait_for_login()
- log.info('Hard reset for {s} completed'.format(s=self.shortname))
-
- def power_on(self):
- log.info('Power on {s}'.format(s=self.shortname))
- start = time.time()
- while time.time() - start < self.timeout:
- child = self._exec('power on')
- r = child.expect(['Chassis Power Control: Up/On', pexpect.EOF], timeout=self.timeout)
- if r == 0:
- break
- if not self.check_power('on'):
- log.error('Failed to power on {s}'.format(s=self.shortname))
- log.info('Power on for {s} completed'.format(s=self.shortname))
-
- def power_off(self):
- log.info('Power off {s}'.format(s=self.shortname))
- start = time.time()
- while time.time() - start < self.timeout:
- child = self._exec('power off')
- r = child.expect(['Chassis Power Control: Down/Off', pexpect.EOF], timeout=self.timeout)
- if r == 0:
- break
- if not self.check_power('off', 60):
- log.error('Failed to power off {s}'.format(s=self.shortname))
- log.info('Power off for {s} completed'.format(s=self.shortname))
-
- def power_off_for_interval(self, interval=30):
- log.info('Power off {s} for {i} seconds'.format(s=self.shortname, i=interval))
- child = self._exec('power off')
- child.expect('Chassis Power Control: Down/Off', timeout=self.timeout)
-
- time.sleep(interval)
-
- child = self._exec('power on')
- child.expect('Chassis Power Control: Up/On', timeout=self.timeout)
- self._wait_for_login()
- log.info('Power off for {i} seconds completed'.format(s=self.shortname, i=interval))
-
-class VirtualConsole():
-
- def __init__(self, name, ipmiuser, ipmipass, ipmidomain, logfile=None, timeout=20):
- self.shortname = getShortName(name)
- status_info = ls.get_status('', self.shortname)
- try:
- phys_host = status_info['vpshost']
- except TypeError:
- return
- self.connection = libvirt.open(phys_host)
- for i in self.connection.listDomainsID():
- d = con.lookupByID(i)
- if d.name() == self.shortname:
- self.vm_domain = d
- break
- return
-
- def check_power(self, state, timeout=None):
- return self.vm_domain.info[0] in [libvirt.VIR_DOMAIN_RUNNING, libvirt.VIR_DOMAIN_BLOCKED,
- libvirt.VIR_DOMAIN_PAUSED]
-
- def check_status(self, timeout=None):
- return self.vm_domain.info()[0] == libvirt.VIR_DOMAIN_RUNNING
-
- def power_cycle(self):
- self.vm_domain.info().destroy()
- self.vm_domain.info().create()
-
- def hard_reset(self):
- self.vm_domain.info().destroy()
-
- def power_on(self):
- self.vm_domain.info().create()
-
- def power_off(self):
- self.vm_domain.info().destroy()
-
- def power_off_for_interval(self, interval=30):
- log.info('Power off {s} for {i} seconds'.format(s=self.shortname, i=interval))
- self.vm_domain.info().destroy()
- time.sleep(interval)
- self.vm_domain.info().create()
- log.info('Power off for {i} seconds completed'.format(s=self.shortname, i=interval))
-
-def getRemoteConsole(name, ipmiuser, ipmipass, ipmidomain, logfile=None, timeout=20):
- if misc.is_vm(name):
- return VirtualConsole(name, ipmiuser, ipmipass, ipmidomain, logfile, timeout)
- return PhysicalConsole(name, ipmiuser, ipmipass, ipmidomain, logfile, timeout)
diff --git a/teuthology/orchestra/run.py b/teuthology/orchestra/run.py
deleted file mode 100644
index a3edc0ea5..000000000
--- a/teuthology/orchestra/run.py
+++ /dev/null
@@ -1,282 +0,0 @@
-from cStringIO import StringIO
-
-import gevent
-import gevent.event
-import pipes
-import logging
-import shutil
-
-log = logging.getLogger(__name__)
-
-class RemoteProcess(object):
- __slots__ = [
- 'command', 'stdin', 'stdout', 'stderr', 'exitstatus', 'exited',
- # for orchestra.remote.Remote to place a backreference
- 'remote',
- ]
- def __init__(self, command, stdin, stdout, stderr, exitstatus, exited):
- self.command = command
- self.stdin = stdin
- self.stdout = stdout
- self.stderr = stderr
- self.exitstatus = exitstatus
- self.exited = exited
-
-class Raw(object):
- def __init__(self, value):
- self.value = value
-
- def __repr__(self):
- return '{cls}({value!r})'.format(
- cls=self.__class__.__name__,
- value=self.value,
- )
-
-def quote(args):
- def _quote(args):
- for a in args:
- if isinstance(a, Raw):
- yield a.value
- else:
- yield pipes.quote(a)
- return ' '.join(_quote(args))
-
-def execute(client, args):
- """
- Execute a command remotely.
-
- Caller needs to handle stdin etc.
-
- :param client: SSHConnection to run the command with
- :param args: command to run
- :type args: list of string
-
- Returns a RemoteProcess, where exitstatus is a callable that will
- block until the exit status is available.
- """
- cmd = quote(args)
- (host,port) = client.get_transport().getpeername()
- log.debug('Running [{h}]: {cmd!r}'.format(h=host, cmd=cmd))
- (in_, out, err) = client.exec_command(cmd)
-
- def get_exitstatus():
- status = out.channel.recv_exit_status()
- # -1 on connection loss *and* signals; map to more pythonic None
- if status == -1:
- status = None
- return status
-
- def exitstatus_ready():
- return out.channel.exit_status_ready()
-
- r = RemoteProcess(
- command=cmd,
- stdin=in_,
- stdout=out,
- stderr=err,
- # this is a callable that will block until the status is
- # available
- exitstatus=get_exitstatus,
- exited=exitstatus_ready,
- )
- return r
-
-def copy_to_log(f, logger, host, loglevel=logging.INFO):
- # i can't seem to get fudge to fake an iterable, so using this old
- # api for now
- for line in f.xreadlines():
- line = line.rstrip()
- logger.log(loglevel, '[' + host + ']: ' + line)
-
-def copy_and_close(src, fdst):
- if src is not None:
- if isinstance(src, basestring):
- src = StringIO(src)
- shutil.copyfileobj(src, fdst)
- fdst.close()
-
-def copy_file_to(f, dst, host):
- if hasattr(dst, 'log'):
- # looks like a Logger to me; not using isinstance to make life
- # easier for unit tests
- handler = copy_to_log
- return handler(f, dst, host)
- else:
- handler = shutil.copyfileobj
- return handler(f, dst)
-
-
-class CommandFailedError(Exception):
- def __init__(self, command, exitstatus, node=None):
- self.command = command
- self.exitstatus = exitstatus
- self.node = node
-
- def __str__(self):
- return "Command failed on {node} with status {status}: {command!r}".format(
- node=self.node,
- status=self.exitstatus,
- command=self.command,
- )
-
-
-class CommandCrashedError(Exception):
- def __init__(self, command):
- self.command = command
-
- def __str__(self):
- return "Command crashed: {command!r}".format(
- command=self.command,
- )
-
-
-class ConnectionLostError(Exception):
- def __init__(self, command):
- self.command = command
-
- def __str__(self):
- return "SSH connection was lost: {command!r}".format(
- command=self.command,
- )
-
-def spawn_asyncresult(fn, *args, **kwargs):
- """
- Spawn a Greenlet and pass it's results to an AsyncResult.
-
- This function is useful to shuffle data from a Greenlet to
- AsyncResult, which then again is useful because any Greenlets that
- raise exceptions will cause tracebacks to be shown on stderr by
- gevent, even when ``.link_exception`` has been called. Using an
- AsyncResult avoids this.
- """
- r = gevent.event.AsyncResult()
- def wrapper():
- try:
- value = fn(*args, **kwargs)
- except Exception as e:
- r.set_exception(e)
- else:
- r.set(value)
- gevent.spawn(wrapper)
-
- return r
-
-class Sentinel(object):
- def __init__(self, name):
- self.name = name
-
- def __str__(self):
- return self.name
-
-PIPE = Sentinel('PIPE')
-
-class KludgeFile(object):
- """
- Wrap Paramiko's ChannelFile in a way that lets ``f.close()``
- actually cause an EOF for the remote command.
- """
- def __init__(self, wrapped):
- self._wrapped = wrapped
-
- def __getattr__(self, name):
- return getattr(self._wrapped, name)
-
- def close(self):
- self._wrapped.close()
- self._wrapped.channel.shutdown_write()
-
-def run(
- client, args,
- stdin=None, stdout=None, stderr=None,
- logger=None,
- check_status=True,
- wait=True,
- ):
- """
- Run a command remotely.
-
- :param client: SSHConnection to run the command with
- :param args: command to run
- :type args: list of string
- :param stdin: Standard input to send; either a string, a file-like object, None, or `PIPE`. `PIPE` means caller is responsible for closing stdin, or command may never exit.
- :param stdout: What to do with standard output. Either a file-like object, a `logging.Logger`, `PIPE`, or `None` for copying to default log. `PIPE` means caller is responsible for reading, or command may never exit.
- :param stderr: What to do with standard error. See `stdout`.
- :param logger: If logging, write stdout/stderr to "out" and "err" children of this logger. Defaults to logger named after this module.
- :param check_status: Whether to raise CalledProcessError on non-zero exit status, and . Defaults to True. All signals and connection loss are made to look like SIGHUP.
- :param wait: Whether to wait for process to exit. If False, returned ``r.exitstatus`` s a `gevent.event.AsyncResult`, and the actual status is available via ``.get()``.
- """
- r = execute(client, args)
-
- r.stdin = KludgeFile(wrapped=r.stdin)
-
- g_in = None
- if stdin is not PIPE:
- g_in = gevent.spawn(copy_and_close, stdin, r.stdin)
- r.stdin = None
- else:
- assert not wait, "Using PIPE for stdin without wait=False would deadlock."
-
- if logger is None:
- logger = log
- (host,port) = client.get_transport().getpeername()
- g_err = None
- if stderr is not PIPE:
- if stderr is None:
- stderr = logger.getChild('err')
- g_err = gevent.spawn(copy_file_to, r.stderr, stderr, host)
- r.stderr = stderr
- else:
- assert not wait, "Using PIPE for stderr without wait=False would deadlock."
-
- g_out = None
- if stdout is not PIPE:
- if stdout is None:
- stdout = logger.getChild('out')
- g_out = gevent.spawn(copy_file_to, r.stdout, stdout, host)
- r.stdout = stdout
- else:
- assert not wait, "Using PIPE for stdout without wait=False would deadlock."
-
- def _check_status(status):
- if g_err is not None:
- g_err.get()
- if g_out is not None:
- g_out.get()
- if g_in is not None:
- g_in.get()
-
- status = status()
- if check_status:
- if status is None:
- # command either died due to a signal, or the connection
- # was lost
- transport = client.get_transport()
- if not transport.is_active():
- # look like we lost the connection
- raise ConnectionLostError(command=r.command)
-
- # connection seems healthy still, assuming it was a
- # signal; sadly SSH does not tell us which signal
- raise CommandCrashedError(command=r.command)
- if status != 0:
- (host,port) = client.get_transport().getpeername()
- raise CommandFailedError(command=r.command, exitstatus=status, node=host)
- return status
-
- if wait:
- r.exitstatus = _check_status(r.exitstatus)
- else:
- r.exitstatus = spawn_asyncresult(_check_status, r.exitstatus)
-
- return r
-
-
-def wait(processes):
- """
- Wait for all given processes to exit.
-
- Raise if any one of them fails.
- """
- for proc in processes:
- assert isinstance(proc.exitstatus, gevent.event.AsyncResult)
- proc.exitstatus.get()
diff --git a/teuthology/orchestra/test/test_cluster.py b/teuthology/orchestra/test/test_cluster.py
deleted file mode 100644
index 0616fc2d9..000000000
--- a/teuthology/orchestra/test/test_cluster.py
+++ /dev/null
@@ -1,207 +0,0 @@
-from nose.tools import eq_ as eq
-
-import fudge
-import nose
-
-from .. import cluster, remote
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_init_empty():
- c = cluster.Cluster()
- eq(c.remotes, {})
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_init():
- r1 = fudge.Fake('Remote')
- r2 = fudge.Fake('Remote')
- c = cluster.Cluster(
- remotes=[
- (r1, ['foo', 'bar']),
- (r2, ['baz']),
- ],
- )
- r3 = fudge.Fake('Remote')
- c.add(r3, ['xyzzy', 'thud', 'foo'])
- eq(c.remotes, {
- r1: ['foo', 'bar'],
- r2: ['baz'],
- r3: ['xyzzy', 'thud', 'foo'],
- })
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_repr():
- r1 = remote.Remote('r1', ssh=fudge.Fake('SSH'))
- r2 = remote.Remote('r2', ssh=fudge.Fake('SSH'))
- c = cluster.Cluster(
- remotes=[
- (r1, ['foo', 'bar']),
- (r2, ['baz']),
- ],
- )
- eq(repr(c), "Cluster(remotes={Remote(name='r1'): ['foo', 'bar'], Remote(name='r2'): ['baz']})")
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_str():
- r1 = remote.Remote('r1', ssh=fudge.Fake('SSH'))
- r2 = remote.Remote('r2', ssh=fudge.Fake('SSH'))
- c = cluster.Cluster(
- remotes=[
- (r1, ['foo', 'bar']),
- (r2, ['baz']),
- ],
- )
- eq(str(c), "r1[foo,bar] r2[baz]")
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_run_all():
- r1 = fudge.Fake('Remote').has_attr(name='r1')
- ret1 = fudge.Fake('RemoteProcess')
- r1.expects('run').with_args(args=['test']).returns(ret1)
- r2 = fudge.Fake('Remote').has_attr(name='r2')
- ret2 = fudge.Fake('RemoteProcess')
- r2.expects('run').with_args(args=['test']).returns(ret2)
- c = cluster.Cluster(
- remotes=[
- (r1, ['foo', 'bar']),
- (r2, ['baz']),
- ],
- )
- got = c.run(args=['test'])
- eq(len(got), 2)
- eq(got, [ret1, ret2])
- # check identity not equality
- assert got[0] is ret1
- assert got[1] is ret2
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_only_one():
- r1 = fudge.Fake('r1')
- r2 = fudge.Fake('r2')
- r3 = fudge.Fake('r3')
- c = cluster.Cluster(
- remotes=[
- (r1, ['foo', 'bar']),
- (r2, ['bar']),
- (r3, ['foo']),
- ],
- )
- c_foo = c.only('foo')
- eq(c_foo.remotes, {r1: ['foo', 'bar'], r3: ['foo']})
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_only_two():
- r1 = fudge.Fake('r1')
- r2 = fudge.Fake('r2')
- r3 = fudge.Fake('r3')
- c = cluster.Cluster(
- remotes=[
- (r1, ['foo', 'bar']),
- (r2, ['bar']),
- (r3, ['foo']),
- ],
- )
- c_both = c.only('foo', 'bar')
- eq(c_both.remotes, {r1: ['foo', 'bar']})
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_only_none():
- r1 = fudge.Fake('r1')
- r2 = fudge.Fake('r2')
- r3 = fudge.Fake('r3')
- c = cluster.Cluster(
- remotes=[
- (r1, ['foo', 'bar']),
- (r2, ['bar']),
- (r3, ['foo']),
- ],
- )
- c_none = c.only('impossible')
- eq(c_none.remotes, {})
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_only_match():
- r1 = fudge.Fake('r1')
- r2 = fudge.Fake('r2')
- r3 = fudge.Fake('r3')
- c = cluster.Cluster(
- remotes=[
- (r1, ['foo', 'bar']),
- (r2, ['bar']),
- (r3, ['foo']),
- ],
- )
- c_foo = c.only('foo', lambda role: role.startswith('b'))
- eq(c_foo.remotes, {r1: ['foo', 'bar']})
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_exclude_one():
- r1 = fudge.Fake('r1')
- r2 = fudge.Fake('r2')
- r3 = fudge.Fake('r3')
- c = cluster.Cluster(
- remotes=[
- (r1, ['foo', 'bar']),
- (r2, ['bar']),
- (r3, ['foo']),
- ],
- )
- c_foo = c.exclude('foo')
- eq(c_foo.remotes, {r2: ['bar']})
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_exclude_two():
- r1 = fudge.Fake('r1')
- r2 = fudge.Fake('r2')
- r3 = fudge.Fake('r3')
- c = cluster.Cluster(
- remotes=[
- (r1, ['foo', 'bar']),
- (r2, ['bar']),
- (r3, ['foo']),
- ],
- )
- c_both = c.exclude('foo', 'bar')
- eq(c_both.remotes, {r2: ['bar'], r3: ['foo']})
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_exclude_none():
- r1 = fudge.Fake('r1')
- r2 = fudge.Fake('r2')
- r3 = fudge.Fake('r3')
- c = cluster.Cluster(
- remotes=[
- (r1, ['foo', 'bar']),
- (r2, ['bar']),
- (r3, ['foo']),
- ],
- )
- c_none = c.exclude('impossible')
- eq(c_none.remotes, {r1: ['foo', 'bar'], r2: ['bar'], r3: ['foo']})
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_exclude_match():
- r1 = fudge.Fake('r1')
- r2 = fudge.Fake('r2')
- r3 = fudge.Fake('r3')
- c = cluster.Cluster(
- remotes=[
- (r1, ['foo', 'bar']),
- (r2, ['bar']),
- (r3, ['foo']),
- ],
- )
- c_foo = c.exclude('foo', lambda role: role.startswith('b'))
- eq(c_foo.remotes, {r2: ['bar'], r3: ['foo']})
diff --git a/teuthology/orchestra/test/test_connection.py b/teuthology/orchestra/test/test_connection.py
deleted file mode 100644
index 371722bd9..000000000
--- a/teuthology/orchestra/test/test_connection.py
+++ /dev/null
@@ -1,77 +0,0 @@
-from nose.tools import eq_ as eq
-
-import fudge
-import nose
-
-from .util import assert_raises
-
-from .. import connection
-
-
-def test_split_user_just_host():
- got = connection.split_user('somehost.example.com')
- eq(got, (None, 'somehost.example.com'))
-
-
-def test_split_user_both():
- got = connection.split_user('jdoe@somehost.example.com')
- eq(got, ('jdoe', 'somehost.example.com'))
-
-
-def test_split_user_empty_user():
- s = '@somehost.example.com'
- e = assert_raises(AssertionError, connection.split_user, s)
- eq(str(e), 'Bad input to split_user: {s!r}'.format(s=s))
-
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_connect():
- sshclient = fudge.Fake('SSHClient')
- ssh = sshclient.expects_call().with_args().returns_fake()
- ssh.remember_order()
- ssh.expects('load_system_host_keys').with_args()
- ssh.expects('connect').with_args(
- hostname='orchestra.test.newdream.net.invalid',
- username='jdoe',
- timeout=60,
- )
- transport = ssh.expects('get_transport').with_args().returns_fake()
- transport.remember_order()
- transport.expects('set_keepalive').with_args(False)
- got = connection.connect(
- 'jdoe@orchestra.test.newdream.net.invalid',
- _SSHClient=sshclient,
- )
- assert got is ssh
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_connect_override_hostkeys():
- sshclient = fudge.Fake('SSHClient')
- ssh = sshclient.expects_call().with_args().returns_fake()
- ssh.remember_order()
- host_keys = fudge.Fake('HostKeys')
- host_keys.expects('add').with_args(
- hostname='orchestra.test.newdream.net.invalid',
- keytype='ssh-rsa',
- key='frobnitz',
- )
- ssh.expects('get_host_keys').with_args().returns(host_keys)
- ssh.expects('connect').with_args(
- hostname='orchestra.test.newdream.net.invalid',
- username='jdoe',
- timeout=60,
- )
- transport = ssh.expects('get_transport').with_args().returns_fake()
- transport.remember_order()
- transport.expects('set_keepalive').with_args(False)
- create_key = fudge.Fake('create_key')
- create_key.expects_call().with_args('ssh-rsa', 'testkey').returns('frobnitz')
- got = connection.connect(
- 'jdoe@orchestra.test.newdream.net.invalid',
- host_key='ssh-rsa testkey',
- _SSHClient=sshclient,
- _create_key=create_key,
- )
- assert got is ssh
diff --git a/teuthology/orchestra/test/test_integration.py b/teuthology/orchestra/test/test_integration.py
deleted file mode 100644
index 39e15fc4b..000000000
--- a/teuthology/orchestra/test/test_integration.py
+++ /dev/null
@@ -1,73 +0,0 @@
-from .. import monkey; monkey.patch_all()
-
-from nose.tools import eq_ as eq
-from cStringIO import StringIO
-
-import os
-import nose
-
-from .. import connection, run
-
-from .util import assert_raises
-
-HOST = None
-
-def setup():
- try:
- host = os.environ['ORCHESTRA_TEST_HOST']
- except KeyError:
- raise nose.SkipTest(
- 'To run integration tests, set environment '
- + 'variable ORCHESTRA_TEST_HOST to user@host to use.',
- )
- global HOST
- HOST = host
-
-def test_crash():
- ssh = connection.connect(HOST)
- e = assert_raises(
- run.CommandCrashedError,
- run.run,
- client=ssh,
- args=['sh', '-c', 'kill -ABRT $$'],
- )
- eq(e.command, "sh -c 'kill -ABRT $$'")
- eq(str(e), "Command crashed: \"sh -c 'kill -ABRT $$'\"")
-
-def test_lost():
- ssh = connection.connect(HOST)
- e = assert_raises(
- run.ConnectionLostError,
- run.run,
- client=ssh,
- args=['sh', '-c', 'kill -ABRT $PPID'],
- )
- eq(e.command, "sh -c 'kill -ABRT $PPID'")
- eq(str(e), "SSH connection was lost: \"sh -c 'kill -ABRT $PPID'\"")
-
-def test_pipe():
- ssh = connection.connect(HOST)
- r = run.run(
- client=ssh,
- args=['cat'],
- stdin=run.PIPE,
- stdout=StringIO(),
- wait=False,
- )
- eq(r.stdout.getvalue(), '')
- r.stdin.write('foo\n')
- r.stdin.write('bar\n')
- r.stdin.close()
-
- got = r.exitstatus.get()
- eq(got, 0)
- eq(r.stdout.getvalue(), 'foo\nbar\n')
-
-def test_and():
- ssh = connection.connect(HOST)
- r = run.run(
- client=ssh,
- args=['true', run.Raw('&&'), 'echo', 'yup'],
- stdout=StringIO(),
- )
- eq(r.stdout.getvalue(), 'yup\n')
diff --git a/teuthology/orchestra/test/test_remote.py b/teuthology/orchestra/test/test_remote.py
deleted file mode 100644
index 039f7cf09..000000000
--- a/teuthology/orchestra/test/test_remote.py
+++ /dev/null
@@ -1,60 +0,0 @@
-from nose.tools import eq_ as eq
-
-import fudge
-import fudge.inspector
-import nose
-
-from .. import remote
-from ..run import RemoteProcess
-
-
-def test_shortname():
- r = remote.Remote(
- name='jdoe@xyzzy.example.com',
- shortname='xyz',
- ssh=fudge.Fake('SSHConnection'),
- )
- eq(r.shortname, 'xyz')
- eq(str(r), 'xyz')
-
-
-def test_shortname_default():
- r = remote.Remote(
- name='jdoe@xyzzy.example.com',
- ssh=fudge.Fake('SSHConnection'),
- )
- eq(r.shortname, 'jdoe@xyzzy.example.com')
- eq(str(r), 'jdoe@xyzzy.example.com')
-
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_run():
- ssh = fudge.Fake('SSHConnection')
- run = fudge.Fake('run')
- args = [
- 'something',
- 'more',
- ]
- foo = object()
- ret = RemoteProcess(
- command='fakey',
- stdin=None,
- stdout=None,
- stderr=None,
- exitstatus=None,
- )
- run.expects_call().with_args(
- client=fudge.inspector.arg.passes_test(lambda v: v is ssh),
- args=fudge.inspector.arg.passes_test(lambda v: v is args),
- foo=fudge.inspector.arg.passes_test(lambda v: v is foo),
- ).returns(ret)
- r = remote.Remote(name='jdoe@xyzzy.example.com', ssh=ssh)
- # monkey patch ook ook
- r._runner = run
- got = r.run(
- args=args,
- foo=foo,
- )
- assert got is ret
- assert got.remote is r
diff --git a/teuthology/orchestra/test/test_run.py b/teuthology/orchestra/test/test_run.py
deleted file mode 100644
index 0452758b9..000000000
--- a/teuthology/orchestra/test/test_run.py
+++ /dev/null
@@ -1,392 +0,0 @@
-from nose.tools import eq_ as eq
-from cStringIO import StringIO
-
-import fudge
-import gevent.event
-import nose
-import logging
-
-from .. import run
-
-from .util import assert_raises
-
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_run_log_simple():
- ssh = fudge.Fake('SSHConnection')
- cmd = ssh.expects('exec_command')
- cmd.with_args("foo 'bar baz'")
- in_ = fudge.Fake('ChannelFile(stdin)')
- out = fudge.Fake('ChannelFile(stdout)')
- err = fudge.Fake('ChannelFile(stderr)')
- cmd.returns((in_, out, err))
- in_.expects('close').with_args()
- in_chan = fudge.Fake('channel')
- in_chan.expects('shutdown_write').with_args()
- in_.has_attr(channel=in_chan)
- out.expects('xreadlines').with_args().returns(['foo', 'bar'])
- err.expects('xreadlines').with_args().returns(['bad'])
- logger = fudge.Fake('logger')
- log_err = fudge.Fake('log_err')
- logger.expects('getChild').with_args('err').returns(log_err)
- log_err.expects('log').with_args(logging.INFO, 'bad')
- log_out = fudge.Fake('log_out')
- logger.expects('getChild').with_args('out').returns(log_out)
- log_out.expects('log').with_args(logging.INFO, 'foo')
- log_out.expects('log').with_args(logging.INFO, 'bar')
- channel = fudge.Fake('channel')
- out.has_attr(channel=channel)
- channel.expects('recv_exit_status').with_args().returns(0)
- r = run.run(
- client=ssh,
- logger=logger,
- args=['foo', 'bar baz'],
- )
- eq(r.exitstatus, 0)
-
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_run_capture_stdout():
- ssh = fudge.Fake('SSHConnection')
- cmd = ssh.expects('exec_command')
- cmd.with_args("foo 'bar baz'")
- in_ = fudge.Fake('ChannelFile(stdin)')
- out = fudge.Fake('ChannelFile(stdout)')
- err = fudge.Fake('ChannelFile(stderr)')
- cmd.returns((in_, out, err))
- in_.expects('close').with_args()
- in_chan = fudge.Fake('channel')
- in_chan.expects('shutdown_write').with_args()
- in_.has_attr(channel=in_chan)
- out.remember_order()
- out.expects('read').with_args().returns('foo\nb')
- out.expects('read').with_args().returns('ar\n')
- out.expects('read').with_args().returns('')
- err.expects('xreadlines').with_args().returns(['bad'])
- logger = fudge.Fake('logger')
- log_err = fudge.Fake('log_err')
- logger.expects('getChild').with_args('err').returns(log_err)
- log_err.expects('log').with_args(logging.INFO, 'bad')
- channel = fudge.Fake('channel')
- out.has_attr(channel=channel)
- channel.expects('recv_exit_status').with_args().returns(0)
- out_f = StringIO()
- r = run.run(
- client=ssh,
- logger=logger,
- args=['foo', 'bar baz'],
- stdout=out_f,
- )
- eq(r.exitstatus, 0)
- assert r.stdout is out_f
- eq(r.stdout.getvalue(), 'foo\nbar\n')
-
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_run_status_bad():
- ssh = fudge.Fake('SSHConnection')
- cmd = ssh.expects('exec_command')
- cmd.with_args("foo")
- in_ = fudge.Fake('ChannelFile').is_a_stub()
- out = fudge.Fake('ChannelFile').is_a_stub()
- err = fudge.Fake('ChannelFile').is_a_stub()
- cmd.returns((in_, out, err))
- out.expects('xreadlines').with_args().returns([])
- err.expects('xreadlines').with_args().returns([])
- logger = fudge.Fake('logger').is_a_stub()
- channel = fudge.Fake('channel')
- out.has_attr(channel=channel)
- channel.expects('recv_exit_status').with_args().returns(42)
- e = assert_raises(
- run.CommandFailedError,
- run.run,
- client=ssh,
- logger=logger,
- args=['foo'],
- )
- eq(e.command, 'foo')
- eq(e.exitstatus, 42)
- eq(str(e), "Command failed with status 42: 'foo'")
-
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_run_status_bad_nocheck():
- ssh = fudge.Fake('SSHConnection')
- cmd = ssh.expects('exec_command')
- cmd.with_args("foo")
- in_ = fudge.Fake('ChannelFile').is_a_stub()
- out = fudge.Fake('ChannelFile').is_a_stub()
- err = fudge.Fake('ChannelFile').is_a_stub()
- cmd.returns((in_, out, err))
- out.expects('xreadlines').with_args().returns([])
- err.expects('xreadlines').with_args().returns([])
- logger = fudge.Fake('logger').is_a_stub()
- channel = fudge.Fake('channel')
- out.has_attr(channel=channel)
- channel.expects('recv_exit_status').with_args().returns(42)
- r = run.run(
- client=ssh,
- logger=logger,
- args=['foo'],
- check_status=False,
- )
- eq(r.exitstatus, 42)
-
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_run_status_crash():
- ssh = fudge.Fake('SSHConnection')
- cmd = ssh.expects('exec_command')
- cmd.with_args("foo")
- in_ = fudge.Fake('ChannelFile').is_a_stub()
- out = fudge.Fake('ChannelFile').is_a_stub()
- err = fudge.Fake('ChannelFile').is_a_stub()
- cmd.returns((in_, out, err))
- out.expects('xreadlines').with_args().returns([])
- err.expects('xreadlines').with_args().returns([])
- logger = fudge.Fake('logger').is_a_stub()
- channel = fudge.Fake('channel')
- out.has_attr(channel=channel)
- channel.expects('recv_exit_status').with_args().returns(-1)
- transport = ssh.expects('get_transport').with_args().returns_fake()
- transport.expects('is_active').with_args().returns(True)
- e = assert_raises(
- run.CommandCrashedError,
- run.run,
- client=ssh,
- logger=logger,
- args=['foo'],
- )
- eq(e.command, 'foo')
- eq(str(e), "Command crashed: 'foo'")
-
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_run_status_crash_nocheck():
- ssh = fudge.Fake('SSHConnection')
- cmd = ssh.expects('exec_command')
- cmd.with_args("foo")
- in_ = fudge.Fake('ChannelFile').is_a_stub()
- out = fudge.Fake('ChannelFile').is_a_stub()
- err = fudge.Fake('ChannelFile').is_a_stub()
- cmd.returns((in_, out, err))
- out.expects('xreadlines').with_args().returns([])
- err.expects('xreadlines').with_args().returns([])
- logger = fudge.Fake('logger').is_a_stub()
- channel = fudge.Fake('channel')
- out.has_attr(channel=channel)
- channel.expects('recv_exit_status').with_args().returns(-1)
- r = run.run(
- client=ssh,
- logger=logger,
- args=['foo'],
- check_status=False,
- )
- assert r.exitstatus is None
-
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_run_status_lost():
- ssh = fudge.Fake('SSHConnection')
- cmd = ssh.expects('exec_command')
- cmd.with_args("foo")
- in_ = fudge.Fake('ChannelFile').is_a_stub()
- out = fudge.Fake('ChannelFile').is_a_stub()
- err = fudge.Fake('ChannelFile').is_a_stub()
- cmd.returns((in_, out, err))
- out.expects('xreadlines').with_args().returns([])
- err.expects('xreadlines').with_args().returns([])
- logger = fudge.Fake('logger').is_a_stub()
- channel = fudge.Fake('channel')
- out.has_attr(channel=channel)
- channel.expects('recv_exit_status').with_args().returns(-1)
- transport = ssh.expects('get_transport').with_args().returns_fake()
- transport.expects('is_active').with_args().returns(False)
- e = assert_raises(
- run.ConnectionLostError,
- run.run,
- client=ssh,
- logger=logger,
- args=['foo'],
- )
-
- eq(e.command, 'foo')
- eq(str(e), "SSH connection was lost: 'foo'")
-
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_run_status_lost_nocheck():
- ssh = fudge.Fake('SSHConnection')
- cmd = ssh.expects('exec_command')
- cmd.with_args("foo")
- in_ = fudge.Fake('ChannelFile').is_a_stub()
- out = fudge.Fake('ChannelFile').is_a_stub()
- err = fudge.Fake('ChannelFile').is_a_stub()
- cmd.returns((in_, out, err))
- out.expects('xreadlines').with_args().returns([])
- err.expects('xreadlines').with_args().returns([])
- logger = fudge.Fake('logger').is_a_stub()
- channel = fudge.Fake('channel')
- out.has_attr(channel=channel)
- channel.expects('recv_exit_status').with_args().returns(-1)
- r = run.run(
- client=ssh,
- logger=logger,
- args=['foo'],
- check_status=False,
- )
- assert r.exitstatus is None
-
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_run_nowait():
- ssh = fudge.Fake('SSHConnection')
- cmd = ssh.expects('exec_command')
- cmd.with_args("foo")
- in_ = fudge.Fake('ChannelFile').is_a_stub()
- out = fudge.Fake('ChannelFile').is_a_stub()
- err = fudge.Fake('ChannelFile').is_a_stub()
- cmd.returns((in_, out, err))
- out.expects('xreadlines').with_args().returns([])
- err.expects('xreadlines').with_args().returns([])
- logger = fudge.Fake('logger').is_a_stub()
- channel = fudge.Fake('channel')
- out.has_attr(channel=channel)
- channel.expects('recv_exit_status').with_args().returns(42)
- r = run.run(
- client=ssh,
- logger=logger,
- args=['foo'],
- wait=False,
- )
- eq(r.command, 'foo')
- assert isinstance(r.exitstatus, gevent.event.AsyncResult)
- e = assert_raises(
- run.CommandFailedError,
- r.exitstatus.get,
- )
- eq(e.exitstatus, 42)
- eq(str(e), "Command failed with status 42: 'foo'")
-
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_run_stdin_pipe():
- ssh = fudge.Fake('SSHConnection')
- cmd = ssh.expects('exec_command')
- cmd.with_args("foo")
- in_ = fudge.Fake('ChannelFile').is_a_stub()
- out = fudge.Fake('ChannelFile').is_a_stub()
- err = fudge.Fake('ChannelFile').is_a_stub()
- cmd.returns((in_, out, err))
- out.expects('xreadlines').with_args().returns([])
- err.expects('xreadlines').with_args().returns([])
- logger = fudge.Fake('logger').is_a_stub()
- channel = fudge.Fake('channel')
- out.has_attr(channel=channel)
- channel.expects('recv_exit_status').with_args().returns(0)
- r = run.run(
- client=ssh,
- logger=logger,
- args=['foo'],
- stdin=run.PIPE,
- wait=False,
- )
- r.stdin.write('bar')
- eq(r.command, 'foo')
- assert isinstance(r.exitstatus, gevent.event.AsyncResult)
- eq(r.exitstatus.ready(), False)
- got = r.exitstatus.get()
- eq(got, 0)
-
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_run_stdout_pipe():
- ssh = fudge.Fake('SSHConnection')
- cmd = ssh.expects('exec_command')
- cmd.with_args("foo")
- in_ = fudge.Fake('ChannelFile').is_a_stub()
- out = fudge.Fake('ChannelFile').is_a_stub()
- err = fudge.Fake('ChannelFile').is_a_stub()
- cmd.returns((in_, out, err))
- out.expects('read').with_args().returns('one')
- out.expects('read').with_args().returns('two')
- out.expects('read').with_args().returns('')
- err.expects('xreadlines').with_args().returns([])
- logger = fudge.Fake('logger').is_a_stub()
- channel = fudge.Fake('channel')
- out.has_attr(channel=channel)
- channel.expects('recv_exit_status').with_args().returns(0)
- r = run.run(
- client=ssh,
- logger=logger,
- args=['foo'],
- stdout=run.PIPE,
- wait=False,
- )
- eq(r.command, 'foo')
- assert isinstance(r.exitstatus, gevent.event.AsyncResult)
- eq(r.exitstatus.ready(), False)
- eq(r.stdout.read(), 'one')
- eq(r.stdout.read(), 'two')
- eq(r.stdout.read(), '')
- got = r.exitstatus.get()
- eq(got, 0)
-
-
-@nose.with_setup(fudge.clear_expectations)
-@fudge.with_fakes
-def test_run_stderr_pipe():
- ssh = fudge.Fake('SSHConnection')
- cmd = ssh.expects('exec_command')
- cmd.with_args("foo")
- in_ = fudge.Fake('ChannelFile').is_a_stub()
- out = fudge.Fake('ChannelFile').is_a_stub()
- err = fudge.Fake('ChannelFile').is_a_stub()
- cmd.returns((in_, out, err))
- out.expects('xreadlines').with_args().returns([])
- err.expects('read').with_args().returns('one')
- err.expects('read').with_args().returns('two')
- err.expects('read').with_args().returns('')
- logger = fudge.Fake('logger').is_a_stub()
- channel = fudge.Fake('channel')
- out.has_attr(channel=channel)
- channel.expects('recv_exit_status').with_args().returns(0)
- r = run.run(
- client=ssh,
- logger=logger,
- args=['foo'],
- stderr=run.PIPE,
- wait=False,
- )
- eq(r.command, 'foo')
- assert isinstance(r.exitstatus, gevent.event.AsyncResult)
- eq(r.exitstatus.ready(), False)
- eq(r.stderr.read(), 'one')
- eq(r.stderr.read(), 'two')
- eq(r.stderr.read(), '')
- got = r.exitstatus.get()
- eq(got, 0)
-
-
-def test_quote_simple():
- got = run.quote(['a b', ' c', 'd e '])
- eq(got, "'a b' ' c' 'd e '")
-
-def test_quote_and_quote():
- got = run.quote(['echo', 'this && is embedded', '&&', 'that was standalone'])
- eq(got, "echo 'this && is embedded' '&&' 'that was standalone'")
-
-def test_quote_and_raw():
- got = run.quote(['true', run.Raw('&&'), 'echo', 'yay'])
- eq(got, "true && echo yay")
diff --git a/teuthology/orchestra/test/util.py b/teuthology/orchestra/test/util.py
deleted file mode 100644
index f693d4082..000000000
--- a/teuthology/orchestra/test/util.py
+++ /dev/null
@@ -1,12 +0,0 @@
-def assert_raises(excClass, callableObj, *args, **kwargs):
- """
- Like unittest.TestCase.assertRaises, but returns the exception.
- """
- try:
- callableObj(*args, **kwargs)
- except excClass, e:
- return e
- else:
- if hasattr(excClass,'__name__'): excName = excClass.__name__
- else: excName = str(excClass)
- raise AssertionError("%s not raised" % excName)
diff --git a/teuthology/parallel.py b/teuthology/parallel.py
deleted file mode 100644
index dbc69ba42..000000000
--- a/teuthology/parallel.py
+++ /dev/null
@@ -1,115 +0,0 @@
-import logging
-import sys
-
-import gevent.pool
-import gevent.queue
-
-log = logging.getLogger(__name__)
-
-class ExceptionHolder(object):
- def __init__(self, exc_info):
- self.exc_info = exc_info
-
-def capture_traceback(func, *args, **kwargs):
- """
- Utility function to capture tracebacks of any exception func
- raises.
- """
- try:
- return func(*args, **kwargs)
- except Exception:
- return ExceptionHolder(sys.exc_info())
-
-def resurrect_traceback(exc):
- if isinstance(exc, ExceptionHolder):
- exc_info = exc.exc_info
- elif isinstance(exc, BaseException):
- print type(exc)
- exc_info = (type(exc), exc, None)
- else:
- return
-
- raise exc_info[0], exc_info[1], exc_info[2]
-
-class parallel(object):
- """
- This class is a context manager for running functions in parallel.
-
- You add functions to be run with the spawn method::
-
- with parallel() as p:
- for foo in bar:
- p.spawn(quux, foo, baz=True)
-
- You can iterate over the results (which are in arbitrary order)::
-
- with parallel() as p:
- for foo in bar:
- p.spawn(quux, foo, baz=True)
- for result in p:
- print result
-
- If one of the spawned functions throws an exception, it will be thrown
- when iterating over the results, or when the with block ends.
-
- At the end of the with block, the main thread waits until all
- spawned functions have completed, or, if one exited with an exception,
- kills the rest and raises the exception.
- """
-
- def __init__(self):
- self.group = gevent.pool.Group()
- self.results = gevent.queue.Queue()
- self.count = 0
- self.any_spawned = False
- self.iteration_stopped = False
-
- def spawn(self, func, *args, **kwargs):
- self.count += 1
- self.any_spawned = True
- greenlet = self.group.spawn(capture_traceback, func, *args, **kwargs)
- greenlet.link(self._finish)
-
- def __enter__(self):
- return self
-
- def __exit__(self, type_, value, traceback):
- if value is not None:
- self.group.kill(block=True)
- return False
-
- try:
- # raises if any greenlets exited with an exception
- for result in self:
- log.debug('result is %s', repr(result))
- pass
- except:
- self.group.kill(block=True)
- raise
- return True
-
- def __iter__(self):
- return self
-
- def next(self):
- if not self.any_spawned or self.iteration_stopped:
- raise StopIteration()
- result = self.results.get()
-
- try:
- resurrect_traceback(result)
- except StopIteration:
- self.iteration_stopped = True
- raise
-
- return result
-
- def _finish(self, greenlet):
- if greenlet.successful():
- self.results.put(greenlet.value)
- else:
- self.results.put(greenlet.exception)
-
- self.count -= 1
- if self.count <= 0:
- self.results.put(StopIteration())
diff --git a/teuthology/queue.py b/teuthology/queue.py
deleted file mode 100644
index 8ff69cacd..000000000
--- a/teuthology/queue.py
+++ /dev/null
@@ -1,150 +0,0 @@
-import argparse
-import logging
-import os
-import subprocess
-import sys
-import tempfile
-import yaml
-
-import beanstalkc
-
-from teuthology import safepath
-
-log = logging.getLogger(__name__)
-
-def connect(ctx):
- host = ctx.teuthology_config['queue_host']
- port = ctx.teuthology_config['queue_port']
- return beanstalkc.Connection(host=host, port=port)
-
-def worker():
- parser = argparse.ArgumentParser(description="""
-Grab jobs from a beanstalk queue and run the teuthology tests they
-describe. One job is run at a time.
-""")
- parser.add_argument(
- '-v', '--verbose',
- action='store_true', default=None,
- help='be more verbose',
- )
- parser.add_argument(
- '--archive-dir',
- metavar='DIR',
- help='path under which to archive results',
- required=True,
- )
- parser.add_argument(
- '-l', '--log-dir',
- help='path in which to store logs',
- required=True,
- )
- parser.add_argument(
- '-t', '--tube',
- help='which beanstalk tube to read jobs from',
- required=True,
- )
-
- ctx = parser.parse_args()
-
- loglevel = logging.INFO
- if ctx.verbose:
- loglevel = logging.DEBUG
-
- logging.basicConfig(
- level=loglevel,
- filename=os.path.join(ctx.log_dir, 'worker.{pid}'.format(pid=os.getpid())),
- format='%(asctime)s.%(msecs)03d %(levelname)s:%(name)s:%(message)s',
- datefmt='%Y-%m-%dT%H:%M:%S',
- )
-
- if not os.path.isdir(ctx.archive_dir):
- sys.exit("{prog}: archive directory must exist: {path}".format(
- prog=os.path.basename(sys.argv[0]),
- path=ctx.archive_dir,
- ))
-
- from teuthology.misc import read_config
- read_config(ctx)
-
- beanstalk = connect(ctx)
- beanstalk.watch(ctx.tube)
- beanstalk.ignore('default')
-
- while True:
- job = beanstalk.reserve(timeout=60)
- if job is None:
- continue
-
- # bury the job so it won't be re-run if it fails
- job.bury()
- log.debug('Reserved job %d', job.jid)
- log.debug('Config is: %s', job.body)
- job_config = yaml.safe_load(job.body)
- safe_archive = safepath.munge(job_config['name'])
- teuthology_branch = job_config.get('config', {}).get('teuthology_branch', 'master')
-
- teuth_path = os.path.join(os.getenv("HOME"), 'teuthology-' + teuthology_branch, 'virtualenv', 'bin')
- if not os.path.isdir(teuth_path):
- raise Exception('Teuthology branch ' + teuthology_branch + ' not found at ' + teuth_path)
- if job_config.get('last_in_suite'):
- log.debug('Generating coverage for %s', job_config['name'])
- args = [
- os.path.join(teuth_path, 'teuthology-results'),
- '--timeout',
- str(job_config.get('results_timeout', 21600)),
- '--email',
- job_config['email'],
- '--archive-dir',
- os.path.join(ctx.archive_dir, safe_archive),
- '--name',
- job_config['name'],
- ]
- subprocess.Popen(args=args)
- else:
- log.debug('Creating archive dir...')
- safepath.makedirs(ctx.archive_dir, safe_archive)
- archive_path = os.path.join(ctx.archive_dir, safe_archive, str(job.jid))
- log.info('Running job %d', job.jid)
- run_job(job_config, archive_path, teuth_path)
- job.delete()
-
-def run_job(job_config, archive_path, teuth_path):
- arg = [
- os.path.join(teuth_path, 'teuthology'),
- ]
-
- if job_config['verbose']:
- arg.append('-v')
-
- arg.extend([
- '--lock',
- '--block',
- '--owner', job_config['owner'],
- '--archive', archive_path,
- '--name', job_config['name'],
- ])
- if job_config['description'] is not None:
- arg.extend(['--description', job_config['description']])
- arg.append('--')
-
- with tempfile.NamedTemporaryFile(
- prefix='teuthology-worker.',
- suffix='.tmp',
- ) as tmp:
- yaml.safe_dump(data=job_config['config'], stream=tmp)
- tmp.flush()
- arg.append(tmp.name)
- p = subprocess.Popen(
- args=arg,
- close_fds=True,
- stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT,
- )
- child = logging.getLogger(__name__ + '.child')
- for line in p.stdout:
- child.info(': %s', line.rstrip('\n'))
- p.wait()
- if p.returncode != 0:
- log.error('Child exited with code %d', p.returncode)
- else:
- log.info('Success!')
diff --git a/teuthology/run.py b/teuthology/run.py
deleted file mode 100644
index 653fb4c2a..000000000
--- a/teuthology/run.py
+++ /dev/null
@@ -1,338 +0,0 @@
-import argparse
-import os
-import yaml
-import StringIO
-import contextlib
-
-def config_file(string):
- config = {}
- try:
- with file(string) as f:
- g = yaml.safe_load_all(f)
- for new in g:
- config.update(new)
- except IOError, e:
- raise argparse.ArgumentTypeError(str(e))
- return config
-
-class MergeConfig(argparse.Action):
- def __call__(self, parser, namespace, values, option_string=None):
- config = getattr(namespace, self.dest)
- from teuthology.misc import deep_merge
- for new in values:
- deep_merge(config, new)
-
-def parse_args():
- parser = argparse.ArgumentParser(description='Run ceph integration tests')
- parser.add_argument(
- '-v', '--verbose',
- action='store_true', default=None,
- help='be more verbose',
- )
- parser.add_argument(
- 'config',
- metavar='CONFFILE',
- nargs='+',
- type=config_file,
- action=MergeConfig,
- default={},
- help='config file to read',
- )
- parser.add_argument(
- '-a', '--archive',
- metavar='DIR',
- help='path to archive results in',
- )
- parser.add_argument(
- '--description',
- help='job description',
- )
- parser.add_argument(
- '--owner',
- help='job owner',
- )
- parser.add_argument(
- '--lock',
- action='store_true',
- default=False,
- help='lock machines for the duration of the run',
- )
- parser.add_argument(
- '--machine-type',
- default=None,
- help='Type of machine to lock/run tests on.',
- )
- parser.add_argument(
- '--os-type',
- default='ubuntu',
- help='Distro/OS of machine to run test on.',
- )
- parser.add_argument(
- '--block',
- action='store_true',
- default=False,
- help='block until locking machines succeeds (use with --lock)',
- )
- parser.add_argument(
- '--name',
- metavar='NAME',
- help='name for this teuthology run',
- )
-
- args = parser.parse_args()
- return args
-
-def main():
- from gevent import monkey; monkey.patch_all(dns=False)
- from .orchestra import monkey; monkey.patch_all()
-
- import logging
-
- log = logging.getLogger(__name__)
- ctx = parse_args()
-
- loglevel = logging.INFO
- if ctx.verbose:
- loglevel = logging.DEBUG
-
- logging.basicConfig(
- level=loglevel,
- )
-
-
- if 'targets' in ctx.config and 'roles' in ctx.config:
- targets = len(ctx.config['targets'])
- roles = len(ctx.config['roles'])
- assert targets >= roles, \
- '%d targets are needed for all roles but found %d listed.' % (roles, targets)
-
- machine_type = ctx.machine_type
- if machine_type is None:
- fallback_default = ctx.config.get('machine_type', 'plana')
- machine_type = ctx.config.get('machine-type', fallback_default)
-
- if ctx.block:
- assert ctx.lock, \
- 'the --block option is only supported with the --lock option'
-
- from teuthology.misc import read_config
- read_config(ctx)
-
- log.debug('\n '.join(['Config:', ] + yaml.safe_dump(ctx.config, default_flow_style=False).splitlines()))
-
- ctx.summary = dict(success=True)
-
- if ctx.owner is None:
- from teuthology.misc import get_user
- ctx.owner = get_user()
- ctx.summary['owner'] = ctx.owner
-
- if ctx.description is not None:
- ctx.summary['description'] = ctx.description
-
- if ctx.archive is not None:
- os.mkdir(ctx.archive)
-
- handler = logging.FileHandler(
- filename=os.path.join(ctx.archive, 'teuthology.log'),
- )
- formatter = logging.Formatter(
- fmt='%(asctime)s.%(msecs)03d %(levelname)s:%(name)s:%(message)s',
- datefmt='%Y-%m-%dT%H:%M:%S',
- )
- handler.setFormatter(formatter)
- logging.getLogger().addHandler(handler)
-
- with file(os.path.join(ctx.archive, 'pid'), 'w') as f:
- f.write('%d' % os.getpid())
-
- with file(os.path.join(ctx.archive, 'owner'), 'w') as f:
- f.write(ctx.owner + '\n')
-
- with file(os.path.join(ctx.archive, 'orig.config.yaml'), 'w') as f:
- yaml.safe_dump(ctx.config, f, default_flow_style=False)
-
- for task in ctx.config['tasks']:
- assert 'kernel' not in task, \
- 'kernel installation shouldn be a base-level item, not part of the tasks list'
-
- init_tasks = []
- if ctx.lock:
- assert 'targets' not in ctx.config, \
- 'You cannot specify targets in a config file when using the --lock option'
- init_tasks.append({'internal.lock_machines': (len(ctx.config['roles']), machine_type)})
-
- init_tasks.extend([
- {'internal.save_config': None},
- {'internal.check_lock': None},
- {'internal.connect': None},
- {'internal.check_conflict': None},
- {'internal.check_ceph_data': None},
- {'internal.vm_setup': None},
- ])
- if 'kernel' in ctx.config:
- from teuthology.misc import get_distro
- distro = get_distro(ctx)
- if distro == 'ubuntu':
- init_tasks.append({'kernel': ctx.config['kernel']})
- init_tasks.extend([
- {'internal.base': None},
- {'internal.archive': None},
- {'internal.coredump': None},
- {'internal.syslog': None},
- {'internal.timer': None},
- ])
-
- ctx.config['tasks'][:0] = init_tasks
-
- from teuthology.run_tasks import run_tasks
- try:
- run_tasks(tasks=ctx.config['tasks'], ctx=ctx)
- finally:
- if not ctx.summary.get('success') and ctx.config.get('nuke-on-error'):
- from teuthology.nuke import nuke
- # only unlock if we locked them in the first place
- nuke(ctx, log, ctx.lock)
- if ctx.archive is not None:
- with file(os.path.join(ctx.archive, 'summary.yaml'), 'w') as f:
- yaml.safe_dump(ctx.summary, f, default_flow_style=False)
- with contextlib.closing(StringIO.StringIO()) as f:
- yaml.safe_dump(ctx.summary, f)
- log.info('Summary data:\n%s' % f.getvalue())
- with contextlib.closing(StringIO.StringIO()) as f:
- if 'email-on-error' in ctx.config and not ctx.summary.get('success', False):
- yaml.safe_dump(ctx.summary, f)
- yaml.safe_dump(ctx.config, f)
- emsg = f.getvalue()
- subject = "Teuthology error -- %s" % ctx.summary['failure_reason']
- from teuthology.suite import email_results
- email_results(subject,"Teuthology",ctx.config['email-on-error'],emsg)
- if ctx.summary.get('success', True):
- log.info('pass')
- else:
- log.info('FAIL')
- import sys
- sys.exit(1)
-
-def schedule():
- parser = argparse.ArgumentParser(description='Schedule ceph integration tests')
- parser.add_argument(
- 'config',
- metavar='CONFFILE',
- nargs='*',
- type=config_file,
- action=MergeConfig,
- default={},
- help='config file to read',
- )
- parser.add_argument(
- '--name',
- help='name of suite run the job is part of',
- )
- parser.add_argument(
- '--last-in-suite',
- action='store_true',
- default=False,
- help='mark the last job in a suite so suite post-processing can be run',
- )
- parser.add_argument(
- '--email',
- help='where to send the results of a suite (only applies to the last job in a suite)',
- )
- parser.add_argument(
- '--timeout',
- help='how many seconds to wait for jobs to finish before emailing results (only applies to the last job in a suite',
- type=int,
- )
- parser.add_argument(
- '--description',
- help='job description',
- )
- parser.add_argument(
- '--owner',
- help='job owner',
- )
- parser.add_argument(
- '--delete',
- metavar='JOBID',
- type=int,
- nargs='*',
- help='list of jobs to remove from the queue',
- )
- parser.add_argument(
- '-n', '--num',
- default=1,
- type=int,
- help='number of times to run/queue the job'
- )
- parser.add_argument(
- '-v', '--verbose',
- action='store_true',
- default=False,
- help='be more verbose',
- )
- parser.add_argument(
- '-w', '--worker',
- default='plana',
- help='which worker to use (type of machine)',
- )
- parser.add_argument(
- '-s', '--show',
- metavar='JOBID',
- type=int,
- nargs='*',
- help='output the contents of specified jobs in the queue',
- )
-
- ctx = parser.parse_args()
- if not ctx.last_in_suite:
- assert not ctx.email, '--email is only applicable to the last job in a suite'
- assert not ctx.timeout, '--timeout is only applicable to the last job in a suite'
-
- from teuthology.misc import read_config, get_user
- if ctx.owner is None:
- ctx.owner = 'scheduled_{user}'.format(user=get_user())
- read_config(ctx)
-
- import teuthology.queue
- beanstalk = teuthology.queue.connect(ctx)
-
- tube=ctx.worker
- beanstalk.use(tube)
-
- if ctx.show:
- for jobid in ctx.show:
- job = beanstalk.peek(jobid)
- if job is None and ctx.verbose:
- print 'job {jid} is not in the queue'.format(jid=jobid)
- else:
- print 'job {jid} contains: '.format(jid=jobid), job.body
- return
-
- if ctx.delete:
- for jobid in ctx.delete:
- job = beanstalk.peek(jobid)
- if job is None:
- print 'job {jid} is not in the queue'.format(jid=jobid)
- else:
- job.delete()
- return
-
- job_config = dict(
- config=ctx.config,
- name=ctx.name,
- last_in_suite=ctx.last_in_suite,
- email=ctx.email,
- description=ctx.description,
- owner=ctx.owner,
- verbose=ctx.verbose,
- )
- if ctx.timeout is not None:
- job_config['results_timeout'] = ctx.timeout
-
- job = yaml.safe_dump(job_config)
- num = ctx.num
- while num > 0:
- jid = beanstalk.put(job, ttr=60*60*24)
- print 'Job scheduled with ID {jid}'.format(jid=jid)
- num -= 1
diff --git a/teuthology/run_tasks.py b/teuthology/run_tasks.py
deleted file mode 100644
index 8193839a6..000000000
--- a/teuthology/run_tasks.py
+++ /dev/null
@@ -1,71 +0,0 @@
-import sys
-import logging
-
-log = logging.getLogger(__name__)
-
-def run_one_task(taskname, **kwargs):
- submod = taskname
- subtask = 'task'
- if '.' in taskname:
- (submod, subtask) = taskname.rsplit('.', 1)
- parent = __import__('teuthology.task', globals(), locals(), [submod], 0)
- mod = getattr(parent, submod)
- fn = getattr(mod, subtask)
- return fn(**kwargs)
-
-def run_tasks(tasks, ctx):
- stack = []
- try:
- for taskdict in tasks:
- try:
- ((taskname, config),) = taskdict.iteritems()
- except ValueError:
- raise RuntimeError('Invalid task definition: %s' % taskdict)
- log.info('Running task %s...', taskname)
- manager = run_one_task(taskname, ctx=ctx, config=config)
- if hasattr(manager, '__enter__'):
- manager.__enter__()
- stack.append(manager)
- except Exception, e:
- ctx.summary['success'] = False
- if 'failure_reason' not in ctx.summary:
- ctx.summary['failure_reason'] = str(e)
- log.exception('Saw exception from tasks')
- if ctx.config.get('interactive-on-error'):
- from .task import interactive
- log.warning('Saw failure, going into interactive mode...')
- interactive.task(ctx=ctx, config=None)
- finally:
- try:
- exc_info = sys.exc_info()
- while stack:
- manager = stack.pop()
- log.debug('Unwinding manager %s', manager)
- try:
- suppress = manager.__exit__(*exc_info)
- except Exception, e:
- ctx.summary['success'] = False
- if 'failure_reason' not in ctx.summary:
- ctx.summary['failure_reason'] = str(e)
- log.exception('Manager failed: %s', manager)
-
- if exc_info == (None, None, None):
- # if first failure is in an __exit__, we don't
- # have exc_info set yet
- exc_info = sys.exc_info()
-
- if ctx.config.get('interactive-on-error'):
- from .task import interactive
- log.warning('Saw failure, going into interactive mode...')
- interactive.task(ctx=ctx, config=None)
- else:
- if suppress:
- sys.exc_clear()
- exc_info = (None, None, None)
-
- if exc_info != (None, None, None):
- log.debug('Exception was not quenched, exiting: %s: %s', exc_info[0].__name__, exc_info[1])
- raise SystemExit(1)
- finally:
- # be careful about cyclic references
- del exc_info
diff --git a/teuthology/safepath.py b/teuthology/safepath.py
deleted file mode 100644
index b8115a25e..000000000
--- a/teuthology/safepath.py
+++ /dev/null
@@ -1,42 +0,0 @@
-import errno
-import os
-
-def munge(path):
- """
- Munge a potentially hostile path name to be safe to use.
-
- This very definitely changes the meaning of the path,
- but it only does that for unsafe paths.
- """
- # explicitly ignoring windows as a platform
- segments = path.split('/')
- # filter out empty segments like foo//bar
- segments = [s for s in segments if s!='']
- # filter out no-op segments like foo/./bar
- segments = [s for s in segments if s!='.']
- # all leading dots become underscores; makes .. safe too
- for idx, seg in enumerate(segments):
- if seg.startswith('.'):
- segments[idx] = '_'+seg[1:]
- # empty string, "/", "//", etc
- if not segments:
- segments = ['_']
- return '/'.join(segments)
-
-
-def makedirs(root, path):
- """
- os.makedirs gets confused if the path contains '..', and root might.
-
- This relies on the fact that `path` has been normalized by munge().
- """
- segments = path.split('/')
- for seg in segments:
- root = os.path.join(root, seg)
- try:
- os.mkdir(root)
- except OSError as e:
- if e.errno == errno.EEXIST:
- pass
- else:
- raise
diff --git a/teuthology/suite.py b/teuthology/suite.py
deleted file mode 100644
index 36c7d7ddd..000000000
--- a/teuthology/suite.py
+++ /dev/null
@@ -1,405 +0,0 @@
-import argparse
-import copy
-import errno
-import itertools
-import logging
-import os
-
-# this file is responsible for submitting tests into the queue
-# by generating combinations of facets found in
-# https://github.com/ceph/ceph-qa-suite.git
-
-import subprocess
-import sys
-import time
-import yaml
-
-from teuthology import misc as teuthology
-from teuthology import safepath
-
-log = logging.getLogger(__name__)
-
-def main():
- parser = argparse.ArgumentParser(description="""
-Run a suite of ceph integration tests.
-
-A suite is a set of collections.
-
-A collection is a directory containing facets.
-
-A facet is a directory containing config snippets.
-
-Running a collection means running teuthology for every configuration
-combination generated by taking one config snippet from each facet.
-
-Any config files passed on the command line will be used for every
-combination, and will override anything in the suite.
-""")
- parser.add_argument(
- '-v', '--verbose',
- action='store_true', default=None,
- help='be more verbose',
- )
- parser.add_argument(
- '--name',
- help='name for this suite',
- required=True,
- )
- parser.add_argument(
- '--collections',
- metavar='DIR',
- nargs='+',
- required=True,
- help='the collections to run',
- )
- parser.add_argument(
- '--owner',
- help='job owner',
- )
- parser.add_argument(
- '--email',
- help='address to email test failures to',
- )
- parser.add_argument(
- '--timeout',
- help='how many seconds to wait for jobs to finish before emailing results',
- )
- parser.add_argument(
- '-n', '--num',
- default=1,
- type=int,
- help='number of times to run/queue each job'
- )
- parser.add_argument(
- '-w', '--worker',
- default='plana',
- help='which worker to use (type of machine)',
- )
- parser.add_argument(
- 'config',
- metavar='CONFFILE',
- nargs='*',
- default=[],
- help='config file to read',
- )
-
- args = parser.parse_args()
-
- loglevel = logging.INFO
- if args.verbose:
- loglevel = logging.DEBUG
-
- logging.basicConfig(
- level=loglevel,
- )
-
- base_arg = [
- os.path.join(os.path.dirname(sys.argv[0]), 'teuthology-schedule'),
- '--name', args.name,
- '--num', str(args.num),
- '--worker', args.worker,
- ]
- if args.verbose:
- base_arg.append('-v')
- if args.owner:
- base_arg.extend(['--owner', args.owner])
-
- for collection in args.collections:
- if not os.path.isdir(collection):
- print >>sys.stderr, 'Collection %s is not a directory' % collection
- sys.exit(1)
-
- collections = [
- (collection,
- os.path.basename(safepath.munge(collection)))
- for collection in args.collections
- ]
-
- for collection, collection_name in sorted(collections):
- log.info('Collection %s in %s' % (collection_name, collection))
- facets = [
- f for f in sorted(os.listdir(collection))
- if not f.startswith('.')
- and os.path.isdir(os.path.join(collection, f))
- ]
- facet_configs = (
- [(f, name, os.path.join(collection, f, name))
- for name in sorted(os.listdir(os.path.join(collection, f)))
- if not name.startswith('.')
- and name.endswith('.yaml')
- ]
- for f in facets
- )
- for configs in itertools.product(*facet_configs):
- description = 'collection:%s ' % (collection_name);
- description += ' '.join('{facet}:{name}'.format(
- facet=facet, name=name)
- for facet, name, path in configs)
- log.info(
- 'Running teuthology-schedule with facets %s', description
- )
- arg = copy.deepcopy(base_arg)
- arg.extend([
- '--description', description,
- '--',
- ])
- arg.extend(args.config)
- arg.extend(path for facet, name, path in configs)
- subprocess.check_call(
- args=arg,
- )
-
- arg = copy.deepcopy(base_arg)
- arg.append('--last-in-suite')
- if args.email:
- arg.extend(['--email', args.email])
- if args.timeout:
- arg.extend(['--timeout', args.timeout])
- subprocess.check_call(
- args=arg,
- )
-
-def ls():
- parser = argparse.ArgumentParser(description='List teuthology job results')
- parser.add_argument(
- '--archive-dir',
- metavar='DIR',
- help='path under which to archive results',
- required=True,
- )
- parser.add_argument(
- '-v', '--verbose',
- action='store_true', default=False,
- help='show reasons tests failed',
- )
- args = parser.parse_args()
-
- for j in sorted(os.listdir(args.archive_dir)):
- job_dir = os.path.join(args.archive_dir, j)
- if j.startswith('.') or not os.path.isdir(job_dir):
- continue
-
- summary = {}
- try:
- with file(os.path.join(job_dir, 'summary.yaml')) as f:
- g = yaml.safe_load_all(f)
- for new in g:
- summary.update(new)
- except IOError, e:
- if e.errno == errno.ENOENT:
- print '%s ' % j,
-
- # pid
- try:
- pidfile = os.path.join(job_dir, 'pid')
- found = False
- if os.path.isfile(pidfile):
- pid = open(pidfile, 'r').read()
- if os.path.isdir("/proc/%s" % pid):
- cmdline = open('/proc/%s/cmdline' % pid, 'r').read()
- if cmdline.find(args.archive_dir) >= 0:
- print '(pid %s)' % pid,
- found = True
- if not found:
- print '(no process or summary.yaml)',
- # tail
- tail = os.popen(
- 'tail -1 %s/%s/teuthology.log' % (args.archive_dir, j)
- ).read().rstrip()
- print tail,
- except IOError, e:
- continue
- print ''
- continue
- else:
- raise
-
- print "{job} {success} {owner} {desc} {duration}s".format(
- job=j,
- owner=summary.get('owner', '-'),
- desc=summary.get('description', '-'),
- success='pass' if summary.get('success', False) else 'FAIL',
- duration=int(summary.get('duration', 0)),
- )
- if args.verbose and 'failure_reason' in summary:
- print ' {reason}'.format(reason=summary['failure_reason'])
-
-def generate_coverage(args):
- log.info('starting coverage generation')
- subprocess.Popen(
- args=[
- os.path.join(os.path.dirname(sys.argv[0]), 'teuthology-coverage'),
- '-v',
- '-o',
- os.path.join(args.teuthology_config['coverage_output_dir'], args.name),
- '--html-output',
- os.path.join(args.teuthology_config['coverage_html_dir'], args.name),
- '--cov-tools-dir',
- args.teuthology_config['coverage_tools_dir'],
- args.archive_dir,
- ],
- )
-
-def email_results(subject, from_, to, body):
- log.info('Sending results to {to}: {body}'.format(to=to, body=body))
- import smtplib
- from email.mime.text import MIMEText
- msg = MIMEText(body)
- msg['Subject'] = subject
- msg['From'] = from_
- msg['To'] = to
- log.debug('sending email %s', msg.as_string())
- smtp = smtplib.SMTP('localhost')
- smtp.sendmail(msg['From'], [msg['To']], msg.as_string())
- smtp.quit()
-
-def results():
- parser = argparse.ArgumentParser(description='Email teuthology suite results')
- parser.add_argument(
- '--email',
- help='address to email test failures to',
- )
- parser.add_argument(
- '--timeout',
- help='how many seconds to wait for all tests to finish (default no wait)',
- type=int,
- default=0,
- )
- parser.add_argument(
- '--archive-dir',
- metavar='DIR',
- help='path under which results for the suite are stored',
- required=True,
- )
- parser.add_argument(
- '--name',
- help='name of the suite',
- required=True,
- )
- parser.add_argument(
- '-v', '--verbose',
- action='store_true', default=False,
- help='be more verbose',
- )
- args = parser.parse_args()
-
- loglevel = logging.INFO
- if args.verbose:
- loglevel = logging.DEBUG
-
- logging.basicConfig(
- level=loglevel,
- )
-
- teuthology.read_config(args)
-
- handler = logging.FileHandler(
- filename=os.path.join(args.archive_dir, 'results.log'),
- )
- formatter = logging.Formatter(
- fmt='%(asctime)s.%(msecs)03d %(levelname)s:%(message)s',
- datefmt='%Y-%m-%dT%H:%M:%S',
- )
- handler.setFormatter(formatter)
- logging.getLogger().addHandler(handler)
-
- try:
- _results(args)
- except:
- log.exception('error generating results')
- raise
-
-def _results(args):
- running_tests = [
- f for f in sorted(os.listdir(args.archive_dir))
- if not f.startswith('.')
- and os.path.isdir(os.path.join(args.archive_dir, f))
- and not os.path.exists(os.path.join(args.archive_dir, f, 'summary.yaml'))
- ]
- starttime = time.time()
- log.info('Waiting up to %d seconds for tests to finish...', args.timeout)
- while running_tests and args.timeout > 0:
- if os.path.exists(os.path.join(
- args.archive_dir,
- running_tests[-1], 'summary.yaml')):
- running_tests.pop()
- else:
- if time.time() - starttime > args.timeout:
- log.warn('test(s) did not finish before timeout of %d seconds',
- args.timeout)
- break
- time.sleep(10)
- log.info('Tests finished! gathering results...')
-
- descriptions = []
- failures = []
- num_failures = 0
- unfinished = []
- passed = []
- all_jobs = sorted(os.listdir(args.archive_dir))
- for j in all_jobs:
- job_dir = os.path.join(args.archive_dir, j)
- if j.startswith('.') or not os.path.isdir(job_dir):
- continue
- summary_fn = os.path.join(job_dir, 'summary.yaml')
- if not os.path.exists(summary_fn):
- unfinished.append(j)
- continue
- summary = {}
- with file(summary_fn) as f:
- g = yaml.safe_load_all(f)
- for new in g:
- summary.update(new)
- desc = '{test}: ({duration}s) {desc}'.format(
- duration=int(summary.get('duration', 0)),
- desc=summary['description'],
- test=j,
- )
- descriptions.append(desc)
- if summary['success']:
- passed.append(desc)
- else:
- failures.append(desc)
- num_failures += 1
- if 'failure_reason' in summary:
- failures.append(' {reason}'.format(
- reason=summary['failure_reason'],
- ))
-
- if failures or unfinished:
- subject = ('{num_failed} failed, {num_hung} hung, '
- '{num_passed} passed in {suite}'.format(
- num_failed=num_failures,
- num_hung=len(unfinished),
- num_passed=len(passed),
- suite=args.name,
- ))
- body = """
-The following tests failed:
-
-{failures}
-
-These tests may be hung (did not finish in {timeout} seconds after the last test in the suite):
-{unfinished}
-
-These tests passed:
-{passed}""".format(
- failures='\n'.join(failures),
- unfinished='\n'.join(unfinished),
- passed='\n'.join(passed),
- timeout=args.timeout,
- )
- else:
- subject = '{num_passed} passed in {suite}'.format(suite=args.name, num_passed=len(passed))
- body = '\n'.join(descriptions)
-
- try:
- if args.email:
- email_results(
- subject=subject,
- from_=args.teuthology_config['results_sending_email'],
- to=args.email,
- body=body,
- )
- finally:
- generate_coverage(args)
diff --git a/teuthology/task/adjust-ulimits b/teuthology/task/adjust-ulimits
deleted file mode 100755
index 4fb558e10..000000000
--- a/teuthology/task/adjust-ulimits
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-set -e
-ulimit -c unlimited
-ulimit -n 16384
-exec "$@"
diff --git a/teuthology/task/args.py b/teuthology/task/args.py
deleted file mode 100644
index fe88b06db..000000000
--- a/teuthology/task/args.py
+++ /dev/null
@@ -1,37 +0,0 @@
-def gen_args(name, args):
- usage = [""]
- usage += [name + ':']
- usage += \
- [" {key}: <{usage}> ({default})".format(
- key = key, usage = usage, default = default)
- for (key, usage, default, _) in args]
- usage.append('')
- usage.append(name + ':')
- usage += \
- [" {key}: {default}".format(
- key = key, default = default)
- for (key, _, default, _) in args]
- usage = '\n'.join(' ' + i for i in usage)
- def ret(config):
- class Object(object): pass
- obj = Object()
- for (key, usage, default, conv) in args:
- if key in config:
- setattr(obj, key, conv(config[key]))
- else:
- setattr(obj, key, conv(default))
- return obj
- return usage, ret
-
-def argify(name, args):
- (usage, config_func) = gen_args(name, args)
- def ret1(f):
- def ret2(**kwargs):
- config = kwargs.get('config', {})
- if config is None:
- config = {}
- kwargs['config'] = config_func(config)
- return f(**kwargs)
- ret2.__doc__ = f.__doc__ + usage
- return ret2
- return ret1
diff --git a/teuthology/task/chdir-coredump b/teuthology/task/chdir-coredump
deleted file mode 100644
index 9c0b4581d..000000000
--- a/teuthology/task/chdir-coredump
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/sh
-set -e
-
-testdir=$(readlink -e $(dirname $0))
-# valgrind only dumps to cwd, so cwd there...
-cd ${testdir}/archive/coredump
-
-exec "$@"
diff --git a/teuthology/task/clock.py b/teuthology/task/clock.py
deleted file mode 100644
index 15ebf1bdb..000000000
--- a/teuthology/task/clock.py
+++ /dev/null
@@ -1,93 +0,0 @@
-import logging
-import contextlib
-
-from ..orchestra import run
-
-log = logging.getLogger(__name__)
-
-@contextlib.contextmanager
-def task(ctx, config):
- """
- Sync or skew clock
-
- This will initially sync the clocks. Eventually it should let us also
- skew by some number of seconds.
-
- example:
-
- tasks:
- - clock:
- - ceph:
- - interactive:
-
- to sync.
-
- """
-
- log.info('Syncing clocks and checking initial clock skew...')
- for rem in ctx.cluster.remotes.iterkeys():
- rem.run(
- args=[
- 'sudo',
- 'service', 'ntp', 'stop',
- run.Raw(';'),
- 'sudo',
- 'ntpdate',
-# 'clock1.dreamhost.com',
-# 'clock2.dreamhost.com',
-# 'clock3.dreamhost.com',
-# 'time.apple.com',
- '0.debian.pool.ntp.org',
- '1.debian.pool.ntp.org',
- '2.debian.pool.ntp.org',
- '3.debian.pool.ntp.org',
- run.Raw(';'),
- 'sudo',
- 'service', 'ntp', 'start',
- run.Raw(';'),
- 'PATH=/usr/bin:/usr/sbin',
- 'ntpdc', '-p',
- ],
- logger=log.getChild(rem.name),
- )
-
- try:
- yield
-
- finally:
- log.info('Checking final clock skew...')
- for rem in ctx.cluster.remotes.iterkeys():
- rem.run(
- args=[
- 'PATH=/usr/bin:/usr/sbin',
- 'ntpdc', '-p',
- ],
- logger=log.getChild(rem.name),
- )
-
-
-@contextlib.contextmanager
-def check(ctx, config):
- log.info('Checking initial clock skew...')
- for rem in ctx.cluster.remotes.iterkeys():
- rem.run(
- args=[
- 'PATH=/usr/bin:/usr/sbin',
- 'ntpdc', '-p',
- ],
- logger=log.getChild(rem.name),
- )
-
- try:
- yield
-
- finally:
- log.info('Checking final clock skew...')
- for rem in ctx.cluster.remotes.iterkeys():
- rem.run(
- args=[
- 'PATH=/usr/bin:/usr/sbin',
- 'ntpdc', '-p',
- ],
- logger=log.getChild(rem.name),
- )
diff --git a/teuthology/task/daemon-helper b/teuthology/task/daemon-helper
deleted file mode 100755
index 6dc92b2ef..000000000
--- a/teuthology/task/daemon-helper
+++ /dev/null
@@ -1,84 +0,0 @@
-#!/usr/bin/python
-
-"""
-Helper script for running long-living processes.
-
-(Name says daemon, but that is intended to mean "long-living", we
-assume child process does not double-fork.)
-
-We start the command passed as arguments, with /dev/null as stdin, and
-then wait for EOF on stdin.
-
-When EOF is seen on stdin, the child process is killed.
-
-When the child process exits, this helper exits too.
-"""
-
-import fcntl
-import os
-import select
-import signal
-import struct
-import subprocess
-import sys
-
-end_signal = signal.SIGKILL
-if sys.argv[1] == "term":
- end_signal = signal.SIGTERM
-
-cmd_start = 2
-
-nostdin = False
-if sys.argv[cmd_start] == "nostdin":
- nostdin = True
- cmd_start += 1
-
-proc = None
-if nostdin:
- proc = subprocess.Popen(
- args=sys.argv[cmd_start:],
- )
-else:
- with file('/dev/null', 'rb') as devnull:
- proc = subprocess.Popen(
- args=sys.argv[cmd_start:],
- stdin=devnull,
- )
-
-flags = fcntl.fcntl(0, fcntl.F_GETFL)
-fcntl.fcntl(0, fcntl.F_SETFL, flags | os.O_NDELAY)
-
-saw_eof = False
-while True:
- r,w,x = select.select([0], [], [0], 0.2)
- if r:
- data = os.read(0, 1)
- if not data:
- saw_eof = True
- proc.send_signal(end_signal)
- break
- else:
- sig, = struct.unpack('!b', data)
- proc.send_signal(sig)
-
- if proc.poll() is not None:
- # child exited
- break
-
-exitstatus = proc.wait()
-if exitstatus > 0:
- print >>sys.stderr, '{me}: command failed with exit status {exitstatus:d}'.format(
- me=os.path.basename(sys.argv[0]),
- exitstatus=exitstatus,
- )
- sys.exit(exitstatus)
-elif exitstatus < 0:
- if saw_eof and exitstatus == -end_signal:
- # suppress error from the exit we intentionally caused
- pass
- else:
- print >>sys.stderr, '{me}: command crashed with signal {signal:d}'.format(
- me=os.path.basename(sys.argv[0]),
- signal=-exitstatus,
- )
- sys.exit(1)
diff --git a/teuthology/task/edit_sudoers.sh b/teuthology/task/edit_sudoers.sh
deleted file mode 100755
index 6ab40a5d8..000000000
--- a/teuthology/task/edit_sudoers.sh
+++ /dev/null
@@ -1,10 +0,0 @@
-#! /bin/sh
-
-sudo vi -e /etc/sudoers < /sys/kernel/debug/dynamic_debug/control
- - echo 'module ceph +p' > /sys/kernel/debug/dynamic_debug/control
- - interactive:
-
- """
- log.info('Executing custom commands...')
- assert isinstance(config, dict), "task exec got invalid config"
-
- testdir = teuthology.get_testdir(ctx)
-
- if 'all' in config and len(config) == 1:
- a = config['all']
- roles = teuthology.all_roles(ctx.cluster)
- config = dict((id_, a) for id_ in roles)
-
- for role, ls in config.iteritems():
- (remote,) = ctx.cluster.only(role).remotes.iterkeys()
- log.info('Running commands on role %s host %s', role, remote.name)
- for c in ls:
- c.replace('$TESTDIR', testdir)
- remote.run(
- args=[
- 'sudo',
- 'TESTDIR={tdir}'.format(tdir=testdir),
- 'bash',
- '-c',
- c],
- )
-
diff --git a/teuthology/task/hadoop.py b/teuthology/task/hadoop.py
deleted file mode 100644
index a6575c762..000000000
--- a/teuthology/task/hadoop.py
+++ /dev/null
@@ -1,526 +0,0 @@
-from cStringIO import StringIO
-
-import contextlib
-import logging
-
-from teuthology import misc as teuthology
-from teuthology import contextutil
-from teuthology.parallel import parallel
-from ..orchestra import run
-
-log = logging.getLogger(__name__)
-
-###################
-# This installeds and configures Hadoop, but requires that Ceph is already installed and running.
-##################
-
-## Check that there is exactly one master and at least one slave configured
-@contextlib.contextmanager
-def validate_config(ctx, config):
- log.info('Vaidating Hadoop configuration')
- slaves = ctx.cluster.only(teuthology.is_type('hadoop.slave'))
-
- if (len(slaves.remotes) < 1):
- raise Exception("At least one hadoop.slave must be specified")
- else:
- log.info(str(len(slaves.remotes)) + " slaves specified")
-
- masters = ctx.cluster.only(teuthology.is_type('hadoop.master'))
- if (len(masters.remotes) == 1):
- pass
- else:
- raise Exception("Exactly one hadoop.master must be specified. Currently there are " + str(len(masters.remotes)))
-
- try:
- yield
-
- finally:
- pass
-
-## Add required entries to conf/hadoop-env.sh
-def write_hadoop_env(ctx, config):
- hadoopEnvFile = "{tdir}/apache_hadoop/conf/hadoop-env.sh".format(tdir=teuthology.get_testdir(ctx))
-
- hadoopNodes = ctx.cluster.only(teuthology.is_type('hadoop'))
- for remote, roles_for_host in hadoopNodes.remotes.iteritems():
- teuthology.write_file(remote, hadoopEnvFile,
-'''export JAVA_HOME=/usr/lib/jvm/default-java
-export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:/usr/share/java/libcephfs.jar:{tdir}/apache_hadoop/build/hadoop-core*.jar:{tdir}/inktank_hadoop/build/hadoop-cephfs.jar
-export HADOOP_NAMENODE_OPTS="-Dcom.sun.management.jmxremote $HADOOP_NAMENODE_OPTS"
-export HADOOP_SECONDARYNAMENODE_OPTS="-Dcom.sun.management.jmxremote $HADOOP_SECONDARYNAMENODE_OPTS"
-export HADOOP_DATANODE_OPTS="-Dcom.sun.management.jmxremote $HADOOP_DATANODE_OPTS"
-export HADOOP_BALANCER_OPTS="-Dcom.sun.management.jmxremote $HADOOP_BALANCER_OPTS"
-export HADOOP_JOBTRACKER_OPTS="-Dcom.sun.management.jmxremote $HADOOP_JOBTRACKER_OPTS"
-'''.format(tdir=teuthology.get_testdir(ctx)) )
- log.info("wrote file: " + hadoopEnvFile + " to host: " + str(remote))
-
-## Add required entries to conf/core-site.xml
-def write_core_site(ctx, config):
- testdir = teuthology.get_testdir(ctx)
- coreSiteFile = "{tdir}/apache_hadoop/conf/core-site.xml".format(tdir=testdir)
-
- hadoopNodes = ctx.cluster.only(teuthology.is_type('hadoop'))
- for remote, roles_for_host in hadoopNodes.remotes.iteritems():
-
- # check the config to see if we should use hdfs or ceph
- default_fs_string = ""
- if config.get('hdfs'):
- default_fs_string = 'hdfs://{master_ip}:54310'.format(master_ip=get_hadoop_master_ip(ctx))
- else:
- default_fs_string = 'ceph:///'
-
- teuthology.write_file(remote, coreSiteFile,
-'''
-
-
-
-
- hadoop.tmp.dir
- /tmp/hadoop/tmp
-
-
- fs.default.name
- {default_fs}
-
-
- ceph.conf.file
- /etc/ceph/ceph.conf
-
-
- fs.ceph.impl
- org.apache.hadoop.fs.ceph.CephFileSystem
-
-
-'''.format(tdir=teuthology.get_testdir(ctx), default_fs=default_fs_string))
-
- log.info("wrote file: " + coreSiteFile + " to host: " + str(remote))
-
-## finds the hadoop.master in the ctx and then pulls out just the IP address
-def get_hadoop_master_ip(ctx):
- remote, _ = _get_master(ctx)
- master_name,master_port= remote.ssh.get_transport().getpeername()
- log.info('master name: {name} port {port}'.format(name=master_name,port=master_port))
- return master_name
-
-## Add required entries to conf/mapred-site.xml
-def write_mapred_site(ctx):
- mapredSiteFile = "{tdir}/apache_hadoop/conf/mapred-site.xml".format(tdir=teuthology.get_testdir(ctx))
-
- master_ip = get_hadoop_master_ip(ctx)
- log.info('adding host {remote} as jobtracker'.format(remote=master_ip))
-
- hadoopNodes = ctx.cluster.only(teuthology.is_type('hadoop'))
- for remote, roles_for_host in hadoopNodes.remotes.iteritems():
- teuthology.write_file(remote, mapredSiteFile,
-'''
-
-
-
-
- mapred.job.tracker
- {remote}:54311
-
-
-'''.format(remote=master_ip))
-
- log.info("wrote file: " + mapredSiteFile + " to host: " + str(remote))
-
-## Add required entries to conf/hdfs-site.xml
-def write_hdfs_site(ctx):
- hdfsSiteFile = "{tdir}/apache_hadoop/conf/hdfs-site.xml".format(tdir=teuthology.get_testdir(ctx))
-
- hadoopNodes = ctx.cluster.only(teuthology.is_type('hadoop'))
- for remote, roles_for_host in hadoopNodes.remotes.iteritems():
- teuthology.write_file(remote, hdfsSiteFile,
-'''
-
-
-
-
- dfs.replication
- 1
-
-
-''' )
- log.info("wrote file: " + hdfsSiteFile + " to host: " + str(remote))
-
-## Add required entries to conf/slaves
-## These nodes host TaskTrackers and DataNodes
-def write_slaves(ctx):
- log.info('Setting up slave nodes...')
-
- slavesFile = "{tdir}/apache_hadoop/conf/slaves".format(tdir=teuthology.get_testdir(ctx))
- tmpFile = StringIO()
-
- slaves = ctx.cluster.only(teuthology.is_type('hadoop.slave'))
- for remote, roles_for_host in slaves.remotes.iteritems():
- tmpFile.write('{remote}\n'.format(remote=remote.ssh.get_transport().getpeername()[0]))
-
- tmpFile.seek(0)
-
- hadoopNodes = ctx.cluster.only(teuthology.is_type('hadoop'))
- for remote, roles_for_host in hadoopNodes.remotes.iteritems():
- teuthology.write_file(remote=remote, path=slavesFile, data=tmpFile)
- tmpFile.seek(0)
- log.info("wrote file: " + slavesFile + " to host: " + str(remote))
-
-## Add required entries to conf/masters
-## These nodes host JobTrackers and Namenodes
-def write_master(ctx):
- mastersFile = "{tdir}/apache_hadoop/conf/masters".format(tdir=teuthology.get_testdir(ctx))
- master = _get_master(ctx)
- master_remote, _ = master
-
-
- hadoopNodes = ctx.cluster.only(teuthology.is_type('hadoop'))
- for remote, roles_for_host in hadoopNodes.remotes.iteritems():
- teuthology.write_file(remote, mastersFile, '{master_host}\n'.format(master_host=master_remote.ssh.get_transport().getpeername()[0]))
- log.info("wrote file: " + mastersFile + " to host: " + str(remote))
-
-## Call the various functions that configure Hadoop
-def _configure_hadoop(ctx, config):
- log.info('writing out config files')
-
- write_hadoop_env(ctx, config)
- write_core_site(ctx, config)
- write_mapred_site(ctx)
- write_hdfs_site(ctx)
- write_slaves(ctx)
- write_master(ctx)
-
-
-
-@contextlib.contextmanager
-def configure_hadoop(ctx, config):
- _configure_hadoop(ctx,config)
-
- log.info('config.get(hdfs): {hdfs}'.format(hdfs=config.get('hdfs')))
-
- if config.get('hdfs'):
- log.info('hdfs option specified. Setting up hdfs')
-
- # let's run this from the master
- master = _get_master(ctx)
- remote, _ = master
- remote.run(
- args=["{tdir}/apache_hadoop/bin/hadoop".format(tdir=teuthology.get_testdir(ctx)),
- "namenode",
- "-format"],
- wait=True,
- )
-
- log.info('done setting up hadoop')
-
- try:
- yield
-
- finally:
- log.info('Removing hdfs directory')
- run.wait(
- ctx.cluster.run(
- args=[
- 'rm',
- '-rf',
- '/tmp/hadoop',
- ],
- wait=False,
- ),
- )
-
-def _start_hadoop(ctx, remote, config):
- testdir = teuthology.get_testdir(ctx)
- if config.get('hdfs'):
- remote.run(
- args=['{tdir}/apache_hadoop/bin/start-dfs.sh'.format(tdir=testdir), ],
- wait=True,
- )
- log.info('done starting hdfs')
-
- remote.run(
- args=['{tdir}/apache_hadoop/bin/start-mapred.sh'.format(tdir=testdir), ],
- wait=True,
- )
- log.info('done starting mapred')
-
-
-def _stop_hadoop(ctx, remote, config):
- testdir = teuthology.get_testdir(ctx)
- remote.run(
- args=['{tdir}/apache_hadoop/bin/stop-mapred.sh'.format(tdir=testdir), ],
- wait=True,
- )
-
- if config.get('hdfs'):
- remote.run(
- args=['{tdir}/apache_hadoop/bin/stop-dfs.sh'.format(tdir=testdir), ],
- wait=True,
- )
-
- log.info('done stopping hadoop')
-
-def _get_master(ctx):
- master = ctx.cluster.only(teuthology.is_type('hadoop.master'))
- assert 1 == len(master.remotes.items()), 'There must be exactly 1 hadoop.master configured'
-
- return master.remotes.items()[0]
-
-@contextlib.contextmanager
-def start_hadoop(ctx, config):
- master = _get_master(ctx)
- remote, _ = master
-
- log.info('Starting hadoop on {remote}\n'.format(remote=remote.ssh.get_transport().getpeername()[0]))
- _start_hadoop(ctx, remote, config)
-
- try:
- yield
-
- finally:
- log.info('Running stop-mapred.sh on {remote}'.format(remote=remote.ssh.get_transport().getpeername()[0]))
- _stop_hadoop(ctx, remote, config)
-
-# download and untar the most recent apache hadoop binaries into {testdir}/apache_hadoop
-def _download_apache_hadoop_binaries(ctx, remote, hadoop_url):
- log.info('_download_apache_hadoop_binaries: path {path} on host {host}'.format(path=hadoop_url, host=str(remote)))
- fileName = 'apache-hadoop.tgz'
- testdir = teuthology.get_testdir(ctx)
- remote.run(
- args=[
- 'mkdir', '-p', '-m0755', '{tdir}/apache_hadoop'.format(tdir=testdir),
- run.Raw('&&'),
- 'echo',
- '{fileName}'.format(fileName=fileName),
- run.Raw('|'),
- 'wget',
- '-nv',
- '-O-',
- '--base={url}'.format(url=hadoop_url),
- # need to use --input-file to make wget respect --base
- '--input-file=-',
- run.Raw('|'),
- 'tar', '-xzf', '-', '-C', '{tdir}/apache_hadoop'.format(tdir=testdir),
- ],
- )
-
-# download and untar the most recent Inktank hadoop binaries into {testdir}/hadoop
-def _download_inktank_hadoop_binaries(ctx, remote, hadoop_url):
- log.info('_download_inktank_hadoop_binaries: path {path} on host {host}'.format(path=hadoop_url, host=str(remote)))
- fileName = 'hadoop.tgz'
- testdir = teuthology.get_testdir(ctx)
- remote.run(
- args=[
- 'mkdir', '-p', '-m0755', '{tdir}/inktank_hadoop'.format(tdir=testdir),
- run.Raw('&&'),
- 'echo',
- '{fileName}'.format(fileName=fileName),
- run.Raw('|'),
- 'wget',
- '-nv',
- '-O-',
- '--base={url}'.format(url=hadoop_url),
- # need to use --input-file to make wget respect --base
- '--input-file=-',
- run.Raw('|'),
- 'tar', '-xzf', '-', '-C', '{tdir}/inktank_hadoop'.format(tdir=testdir),
- ],
- )
-
-# copy hadoop-cephfs.jar and hadoop-cephfs-test.jar into apache_hadoop
-def _copy_hadoop_cephfs_jars(ctx, remote, from_dir, to_dir):
- testdir = teuthology.get_testdir(ctx)
- log.info('copy jars from {from_dir} to {to_dir} on host {host}'.format(from_dir=from_dir, to_dir=to_dir, host=str(remote)))
- file_names = [ 'hadoop-cephfs.jar', 'hadoop-cephfs-test.jar' ]
- for file_name in file_names:
- log.info('Copying file {file_name}'.format(file_name=file_name))
- remote.run(
- args=[ 'cp', '{tdir}/{from_dir}/{file_name}'.format(tdir=testdir,from_dir=from_dir,file_name=file_name),
- '{tdir}/{to_dir}/'.format(tdir=testdir,to_dir=to_dir)
- ],
- )
-
-def _node_binaries(ctx, config, remote, inktank_hadoop_bindir_url, apache_hadoop_bindir_url):
- _download_inktank_hadoop_binaries(ctx, remote, inktank_hadoop_bindir_url)
- _download_apache_hadoop_binaries(ctx, remote, apache_hadoop_bindir_url)
- _copy_hadoop_cephfs_jars(ctx, remote, 'inktank_hadoop/build', 'apache_hadoop/build')
-
-@contextlib.contextmanager
-def binaries(ctx, config):
- path = config.get('path')
-
- if path is None:
- # fetch Apache Hadoop from gitbuilder
- log.info('Fetching and unpacking Apache Hadoop binaries from gitbuilder...')
- apache_sha1, apache_hadoop_bindir_url = teuthology.get_ceph_binary_url(
- package='apache-hadoop',
- branch=config.get('apache_branch'),
- tag=config.get('tag'),
- sha1=config.get('sha1'),
- flavor=config.get('flavor'),
- format=config.get('format'),
- dist=config.get('dist'),
- arch=config.get('arch'),
- )
- log.info('apache_hadoop_bindir_url %s' % (apache_hadoop_bindir_url))
- ctx.summary['apache-hadoop-sha1'] = apache_sha1
-
- # fetch Inktank Hadoop from gitbuilder
- log.info('Fetching and unpacking Inktank Hadoop binaries from gitbuilder...')
- inktank_sha1, inktank_hadoop_bindir_url = teuthology.get_ceph_binary_url(
- package='hadoop',
- branch=config.get('inktank_branch'),
- tag=config.get('tag'),
- sha1=config.get('sha1'),
- flavor=config.get('flavor'),
- format=config.get('format'),
- dist=config.get('dist'),
- arch=config.get('arch'),
- )
- log.info('inktank_hadoop_bindir_url %s' % (inktank_hadoop_bindir_url))
- ctx.summary['inktank-hadoop-sha1'] = inktank_sha1
-
- else:
- raise Exception("The hadoop task does not support the path argument at present")
-
- with parallel() as p:
- hadoopNodes = ctx.cluster.only(teuthology.is_type('hadoop'))
- # these can happen independently
- for remote in hadoopNodes.remotes.iterkeys():
- p.spawn(_node_binaries, ctx, config, remote, inktank_hadoop_bindir_url, apache_hadoop_bindir_url)
-
- try:
- yield
- finally:
- log.info('Removing hadoop binaries...')
- run.wait(
- ctx.cluster.run(
- args=[ 'rm', '-rf', '--', '{tdir}/apache_hadoop'.format(tdir=teuthology.get_testdir(ctx))],
- wait=False,
- ),
- )
- run.wait(
- ctx.cluster.run(
- args=[ 'rm', '-rf', '--', '{tdir}/inktank_hadoop'.format(tdir=teuthology.get_testdir(ctx))],
- wait=False,
- ),
- )
-
-## A Hadoop NameNode will stay in safe mode for 30 seconds by default.
-## This method blocks until the NameNode is out of safe mode.
-@contextlib.contextmanager
-def out_of_safemode(ctx, config):
-
- if config.get('hdfs'):
- log.info('Waiting for the Namenode to exit safe mode...')
-
- master = _get_master(ctx)
- remote, _ = master
- remote.run(
- args=["{tdir}/apache_hadoop/bin/hadoop".format(tdir=teuthology.get_testdir(ctx)),
- "dfsadmin",
- "-safemode",
- "wait"],
- wait=True,
- )
- else:
- pass
-
- try:
- yield
- finally:
- pass
-
-@contextlib.contextmanager
-def task(ctx, config):
- """
- Set up and tear down a Hadoop cluster.
-
- This depends on either having ceph installed prior to hadoop, like so:
-
- roles:
- - [mon.0, mds.0, osd.0, hadoop.master.0]
- - [mon.1, osd.1, hadoop.slave.0]
- - [mon.2, hadoop.slave.1]
-
- tasks:
- - ceph:
- - hadoop:
-
- Or if you want to use HDFS under Hadoop, this will configure Hadoop
- for HDFS and start it along with MapReduce. Note that it does not
- require Ceph be installed.
-
- roles:
- - [hadoop.master.0]
- - [hadoop.slave.0]
- - [hadoop.slave.1]
-
- tasks:
- - hadoop:
- hdfs: True
-
- This task requires exactly one hadoop.master be specified
- and at least one hadoop.slave.
-
- This does *not* do anything with the Hadoop setup. To run wordcount,
- you could use pexec like so (after the hadoop task):
-
- - pexec:
- hadoop.slave.0:
- - mkdir -p /tmp/hadoop_input
- - wget http://ceph.com/qa/hadoop_input_files.tar -O /tmp/hadoop_input/files.tar
- - cd /tmp/hadoop_input/; tar -xf /tmp/hadoop_input/files.tar
- - {tdir}/hadoop/bin/hadoop fs -mkdir wordcount_input
- - {tdir}/hadoop/bin/hadoop fs -put /tmp/hadoop_input/*txt wordcount_input/
- - {tdir}/hadoop/bin/hadoop jar {tdir}/hadoop/build/hadoop-example*jar wordcount wordcount_input wordcount_output
- - rm -rf /tmp/hadoop_input
- """.format(tdir=teuthology.get_testdir(ctx))
-
- if config is None:
- config = {}
- assert isinstance(config, dict), \
- "task hadoop only supports a dictionary for configuration"
-
- dist = 'precise'
- format = 'jar'
- arch = 'x86_64'
- flavor = config.get('flavor', 'basic')
-
- ctx.summary['flavor'] = flavor
-
- overrides = ctx.config.get('overrides', {})
- teuthology.deep_merge(config, overrides.get('hadoop', {}))
-
- apache_branch = None
- if config.get('apache_hadoop_branch') is not None:
- apache_branch = config.get('apache_hadoop_branch')
- else:
- apache_branch = 'branch-1.0' # hadoop branch to acquire
-
- inktank_branch = None
- if config.get('inktank_hadoop_branch') is not None:
- inktank_branch = config.get('inktank_hadoop_branch')
- else:
- inktank_branch = 'cephfs/branch-1.0' # default branch name
-
- # replace any '/' with a '_' to match the artifact paths
- inktank_branch = inktank_branch.replace('/','_')
- apache_branch = apache_branch.replace('/','_')
-
- with contextutil.nested(
- lambda: validate_config(ctx=ctx, config=config),
- lambda: binaries(ctx=ctx, config=dict(
- tag=config.get('tag'),
- sha1=config.get('sha1'),
- path=config.get('path'),
- flavor=flavor,
- dist=config.get('dist', dist),
- format=format,
- arch=arch,
- apache_branch=apache_branch,
- inktank_branch=inktank_branch,
- )),
- lambda: configure_hadoop(ctx=ctx, config=config),
- lambda: start_hadoop(ctx=ctx, config=config),
- lambda: out_of_safemode(ctx=ctx, config=config),
- ):
- yield
diff --git a/teuthology/task/install.py b/teuthology/task/install.py
deleted file mode 100644
index 3964951ad..000000000
--- a/teuthology/task/install.py
+++ /dev/null
@@ -1,897 +0,0 @@
-from cStringIO import StringIO
-
-import contextlib
-import logging
-import time
-
-from teuthology import misc as teuthology
-from teuthology import contextutil
-from teuthology.parallel import parallel
-from ..orchestra import run
-from ..orchestra.run import CommandFailedError
-
-log = logging.getLogger(__name__)
-
-# Should the RELEASE value get extracted from somewhere?
-RELEASE = "1-0"
-
-# This is intended to be a complete listing of ceph packages. If we're going
-# to hardcode this stuff, I don't want to do it in more than once place.
-PACKAGES = {}
-PACKAGES['ceph'] = {}
-PACKAGES['ceph']['deb'] = [
- 'ceph',
- 'ceph-dbg',
- 'ceph-mds',
- 'ceph-mds-dbg',
- 'ceph-common',
- 'ceph-common-dbg',
- 'ceph-fuse',
- 'ceph-fuse-dbg',
- 'ceph-test',
- 'ceph-test-dbg',
- 'radosgw',
- 'radosgw-dbg',
- 'python-ceph',
- 'libcephfs1',
- 'libcephfs1-dbg',
- 'libcephfs-java',
- 'librados2',
- 'librados2-dbg',
- 'librbd1',
- 'librbd1-dbg',
-]
-PACKAGES['ceph']['rpm'] = [
- 'ceph-debug',
- 'ceph-radosgw',
- 'ceph-test',
- 'ceph-devel',
- 'ceph',
- 'ceph-fuse',
- 'rest-bench',
- 'libcephfs_jni1',
- 'libcephfs1',
- 'python-ceph',
-]
-
-
-def _run_and_log_error_if_fails(remote, args):
- response = StringIO()
- try:
- remote.run(
- args=args,
- stdout=response,
- stderr=response,
- )
- except CommandFailedError:
- log.error(response.getvalue().strip())
- raise
-
-
-def _get_config_value_for_remote(ctx, remote, config, key):
- # This function was written to figure out which branch should be used for a
- # given remote. 'all' overrides any applicable roles.
-
- roles = ctx.cluster.remotes[remote]
- if 'all' in config:
- return config['all'][key]
- elif roles:
- for role in roles:
- if role in config and key in config[role]:
- return config[role][key]
- if key in config:
- return config[key]
-
-
-def _get_baseurlinfo_and_dist(ctx, remote, config):
- retval = {}
- relval = None
- r = remote.run(
- args=['arch'],
- stdout=StringIO(),
- )
- retval['arch'] = r.stdout.getvalue().strip()
- r = remote.run(
- args=['lsb_release', '-is'],
- stdout=StringIO(),
- )
- retval['distro'] = r.stdout.getvalue().strip()
- r = remote.run(
- args=[
- 'lsb_release', '-rs'], stdout=StringIO())
- retval['relval'] = r.stdout.getvalue().strip()
- dist_name = None
- if ((retval['distro'] == 'CentOS') | (retval['distro'] == 'RedHatEnterpriseServer')):
- relval = retval['relval']
- relval = relval[0:relval.find('.')]
- distri = 'centos'
- retval['distro_release'] = '%s%s' % (distri, relval)
- retval['dist'] = retval['distro_release']
- dist_name = 'el'
- retval['dist_release'] = '%s%s' % (dist_name, relval)
- elif retval['distro'] == 'Fedora':
- distri = retval['distro']
- dist_name = 'fc'
- retval['distro_release'] = '%s%s' % (dist_name, retval['relval'])
- retval['dist_release'] = retval['distro_release']
- else:
- r = remote.run(
- args=['lsb_release', '-sc'],
- stdout=StringIO(),
- )
- retval['dist'] = r.stdout.getvalue().strip()
- retval['distro_release'] = None
- retval['dist_release'] = None
-
- # branch/tag/sha1 flavor
- retval['flavor'] = config.get('flavor', 'basic')
-
- uri = None
- log.info('config is %s', config)
- tag = _get_config_value_for_remote(ctx, remote, config, 'tag')
- branch = _get_config_value_for_remote(ctx, remote, config, 'branch')
- sha1 = _get_config_value_for_remote(ctx, remote, config, 'sha1')
- if tag:
- uri = 'ref/' + tag
- elif branch:
- uri = 'ref/' + branch
- elif sha1:
- uri = 'sha1/' + sha1
- else:
- # FIXME: Should master be the default?
- log.debug("defaulting to master branch")
- uri = 'ref/master'
- retval['uri'] = uri
-
- return retval
-
-
-def _get_baseurl(ctx, remote, config):
- # get distro name and arch
- baseparms = _get_baseurlinfo_and_dist(ctx, remote, config)
- base_url = 'http://{host}/{proj}-{pkg_type}-{dist}-{arch}-{flavor}/{uri}'.format(
- host=ctx.teuthology_config.get('gitbuilder_host',
- 'gitbuilder.ceph.com'),
- proj=config.get('project', 'ceph'),
- pkg_type=remote.system_type,
- **baseparms
- )
- return base_url
-
-
-class VersionNotFoundError(Exception):
- def __init__(self, url):
- self.url = url
-
- def __str__(self):
- return "Failed to fetch package version from %s" % self.url
-
-
-def _block_looking_for_package_version(remote, base_url, wait=False):
- """
- Look for, and parse, a file called 'version' in base_url.
-
- wait -- wait forever for the file to show up. (default False)
- """
- while True:
- r = remote.run(
- args=['wget', '-q', '-O-', base_url + '/version'],
- stdout=StringIO(),
- check_status=False,
- )
- if r.exitstatus != 0:
- if wait:
- log.info('Package not there yet, waiting...')
- time.sleep(15)
- continue
- raise VersionNotFoundError(base_url)
- break
- version = r.stdout.getvalue().strip()
- return version
-
-
-def _update_deb_package_list_and_install(ctx, remote, debs, config):
- """
- updates the package list so that apt-get can
- download the appropriate packages
- """
-
- # check for ceph release key
- r = remote.run(
- args=[
- 'sudo', 'apt-key', 'list', run.Raw('|'), 'grep', 'Ceph',
- ],
- stdout=StringIO(),
- )
- if r.stdout.getvalue().find('Ceph automated package') == -1:
- # if it doesn't exist, add it
- remote.run(
- args=[
- 'wget', '-q', '-O-',
- 'https://ceph.com/git/?p=ceph.git;a=blob_plain;f=keys/autobuild.asc',
- run.Raw('|'),
- 'sudo', 'apt-key', 'add', '-',
- ],
- stdout=StringIO(),
- )
-
- baseparms = _get_baseurlinfo_and_dist(ctx, remote, config)
- log.info("Installing packages: {pkglist} on remote deb {arch}".format(
- pkglist=", ".join(debs), arch=baseparms['arch'])
- )
- # get baseurl
- base_url = _get_baseurl(ctx, remote, config)
- log.info('Pulling from %s', base_url)
-
- # get package version string
- while True:
- r = remote.run(
- args=[
- 'wget', '-q', '-O-', base_url + '/version',
- ],
- stdout=StringIO(),
- check_status=False,
- )
- if r.exitstatus != 0:
- if config.get('wait_for_package'):
- log.info('Package not there yet, waiting...')
- time.sleep(15)
- continue
- raise Exception('failed to fetch package version from %s' %
- base_url + '/version')
- version = r.stdout.getvalue().strip()
- log.info('Package version is %s', version)
- break
-
- remote.run(
- args=[
- 'echo', 'deb', base_url, baseparms['dist'], 'main',
- run.Raw('|'),
- 'sudo', 'tee', '/etc/apt/sources.list.d/{proj}.list'.format(proj=config.get('project', 'ceph')),
- ],
- stdout=StringIO(),
- )
- remote.run(
- args=[
- 'sudo', 'apt-get', 'update', run.Raw('&&'),
- 'sudo', 'DEBIAN_FRONTEND=noninteractive', 'apt-get', '-y', '--force-yes',
- '-o', run.Raw('Dpkg::Options::="--force-confdef"'), '-o', run.Raw('Dpkg::Options::="--force-confold"'),
- 'install',
- ] + ['%s=%s' % (d, version) for d in debs],
- stdout=StringIO(),
- )
-
-
-def _yum_fix_repo_priority(remote, project):
- remote.run(
- args=[
- 'sudo',
- 'sed',
- '-i',
- run.Raw('\':a;N;$!ba;s/enabled=1\\ngpg/enabled=1\\npriority=1\\ngpg/g\''),
- '/etc/yum.repos.d/%s.repo' % project,
- ]
- )
-
-
-def _update_rpm_package_list_and_install(ctx, remote, rpm, config):
- baseparms = _get_baseurlinfo_and_dist(ctx, remote, config)
- log.info("Installing packages: {pkglist} on remote rpm {arch}".format(
- pkglist=", ".join(rpm), arch=baseparms['arch']))
- host = ctx.teuthology_config.get('gitbuilder_host',
- 'gitbuilder.ceph.com')
- dist_release = baseparms['dist_release']
- distro_release = baseparms['distro_release']
- start_of_url = 'http://{host}/ceph-rpm-{distro_release}-{arch}-{flavor}/{uri}'.format(host=host, **baseparms)
- ceph_release = 'ceph-release-{release}.{dist_release}.noarch'.format(
- release=RELEASE, dist_release=dist_release)
- rpm_name = "{rpm_nm}.rpm".format(rpm_nm=ceph_release)
- base_url = "{start_of_url}/noarch/{rpm_name}".format(
- start_of_url=start_of_url, rpm_name=rpm_name)
- err_mess = StringIO()
- try:
- # When this was one command with a pipe, it would sometimes
- # fail with the message 'rpm: no packages given for install'
- remote.run(args=['wget', base_url, ],)
- remote.run(args=['sudo', 'rpm', '-i', rpm_name, ], stderr=err_mess, )
- except:
- cmp_msg = 'package {pkg} is already installed'.format(
- pkg=ceph_release)
- if cmp_msg != err_mess.getvalue().strip():
- raise
-
- remote.run(args=['rm', '-f', rpm_name])
-
- #Fix Repo Priority
- _yum_fix_repo_priority(remote, config.get('project', 'ceph'))
-
- remote.run(
- args=[
- 'sudo', 'yum', 'clean', 'all',
- ])
- version_no = StringIO()
- version_url = "{start_of_url}/version".format(start_of_url=start_of_url)
- while True:
- r = remote.run(args=['wget', '-q', '-O-', version_url, ],
- stdout=version_no, check_status=False)
- if r.exitstatus != 0:
- if config.get('wait_for_package'):
- log.info('Package not there yet, waiting...')
- time.sleep(15)
- continue
- raise Exception('failed to fetch package version from %s' %
- version_url)
- version = r.stdout.getvalue().strip()
- log.info('Package version is %s', version)
- break
-
- tmp_vers = version_no.getvalue().strip()[1:]
- dloc = tmp_vers.rfind('-')
- t_vers1 = tmp_vers[0:dloc]
- t_vers2 = tmp_vers[dloc + 1:]
- trailer = "-{tv1}-{tv2}.{dist_release}".format(tv1=t_vers1, tv2=t_vers2, dist_release=dist_release)
- for cpack in rpm:
- pk_err_mess = StringIO()
- pkg2add = "{cpack}{trailer}".format(cpack=cpack, trailer=trailer)
- remote.run(args=['sudo', 'yum', 'install', pkg2add, '-y', ],
- stderr=pk_err_mess)
-
-
-def purge_data(ctx):
- """
- Purge /var/lib/ceph
- """
- with parallel() as p:
- for remote in ctx.cluster.remotes.iterkeys():
- p.spawn(_purge_data, remote)
-
-
-def _purge_data(remote):
- log.info('Purging /var/lib/ceph on %s', remote)
- remote.run(args=[
- 'sudo',
- 'rm', '-rf', '--one-file-system', '--', '/var/lib/ceph',
- run.Raw('||'),
- 'true',
- run.Raw(';'),
- 'test', '-d', '/var/lib/ceph',
- run.Raw('&&'),
- 'sudo',
- 'find', '/var/lib/ceph',
- '-mindepth', '1',
- '-maxdepth', '2',
- '-type', 'd',
- '-exec', 'umount', '{}', ';',
- run.Raw(';'),
- 'sudo',
- 'rm', '-rf', '--one-file-system', '--', '/var/lib/ceph',
- ])
-
-
-def install_packages(ctx, pkgs, config):
- """
- installs Debian packages.
- """
- install_pkgs = {
- "deb": _update_deb_package_list_and_install,
- "rpm": _update_rpm_package_list_and_install,
- }
- with parallel() as p:
- for remote in ctx.cluster.remotes.iterkeys():
- system_type = teuthology.get_system_type(remote)
- p.spawn(
- install_pkgs[system_type],
- ctx, remote, pkgs[system_type], config)
-
-
-def _remove_deb(ctx, config, remote, debs):
- log.info("Removing packages: {pkglist} on Debian system.".format(
- pkglist=", ".join(debs)))
- # first ask nicely
- remote.run(
- args=[
- 'for', 'd', 'in',
- ] + debs + [
- run.Raw(';'),
- 'do',
- 'sudo', 'DEBIAN_FRONTEND=noninteractive', 'apt-get', '-y', '--force-yes',
- '-o', run.Raw('Dpkg::Options::="--force-confdef"'), '-o', run.Raw('Dpkg::Options::="--force-confold"'), 'purge',
- run.Raw('$d'),
- run.Raw('||'),
- 'true',
- run.Raw(';'),
- 'done',
- ])
- # mop up anything that is broken
- remote.run(
- args=[
- 'dpkg', '-l',
- run.Raw('|'),
- 'grep', '^.HR',
- run.Raw('|'),
- 'awk', '{print $2}',
- run.Raw('|'),
- 'sudo',
- 'xargs', '--no-run-if-empty',
- 'dpkg', '-P', '--force-remove-reinstreq',
- ])
- # then let apt clean up
- remote.run(
- args=[
- 'sudo', 'DEBIAN_FRONTEND=noninteractive', 'apt-get', '-y', '--force-yes',
- '-o', run.Raw('Dpkg::Options::="--force-confdef"'), '-o', run.Raw('Dpkg::Options::="--force-confold"'),
- 'autoremove',
- ],
- stdout=StringIO(),
- )
-
-
-def _remove_rpm(ctx, config, remote, rpm):
- log.info("Removing packages: {pkglist} on rpm system.".format(
- pkglist=", ".join(rpm)))
- baseparms = _get_baseurlinfo_and_dist(ctx, remote, config)
- dist_release = baseparms['dist_release']
- remote.run(
- args=[
- 'for', 'd', 'in',
- ] + rpm + [
- run.Raw(';'),
- 'do',
- 'sudo', 'yum', 'remove',
- run.Raw('$d'),
- '-y',
- run.Raw('||'),
- 'true',
- run.Raw(';'),
- 'done',
- ])
- remote.run(
- args=[
- 'sudo', 'yum', 'clean', 'all',
- ])
- projRelease = '%s-release-%s.%s.noarch' % (config.get('project', 'ceph'), RELEASE, dist_release)
- remote.run(args=['sudo', 'yum', 'erase', projRelease, '-y'])
- remote.run(
- args=[
- 'sudo', 'yum', 'clean', 'expire-cache',
- ])
-
-
-def remove_packages(ctx, config, pkgs):
- remove_pkgs = {
- "deb": _remove_deb,
- "rpm": _remove_rpm,
- }
- with parallel() as p:
- for remote in ctx.cluster.remotes.iterkeys():
- system_type = teuthology.get_system_type(remote)
- p.spawn(remove_pkgs[system_type], ctx, config, remote, pkgs[system_type])
-
-
-def _remove_sources_list_deb(remote, proj):
- remote.run(
- args=[
- 'sudo', 'rm', '-f', '/etc/apt/sources.list.d/{proj}.list'.format(proj=proj),
- run.Raw('&&'),
- 'sudo', 'apt-get', 'update',
- # ignore failure
- run.Raw('||'),
- 'true',
- ],
- stdout=StringIO(),
- )
-
-
-def _remove_sources_list_rpm(remote, proj):
- remote.run(
- args=[
- 'sudo', 'rm', '-f', '/etc/yum.repos.d/{proj}.repo'.format(proj=proj),
- run.Raw('||'),
- 'true',
- ],
- stdout=StringIO(),
- )
- # There probably should be a way of removing these files that is implemented in the yum/rpm
- # remove procedures for the ceph package.
- remote.run(
- args=[
- 'sudo', 'rm', '-fr', '/var/lib/{proj}'.format(proj=proj),
- run.Raw('||'),
- 'true',
- ],
- stdout=StringIO(),
- )
- remote.run(
- args=[
- 'sudo', 'rm', '-fr', '/var/log/{proj}'.format(proj=proj),
- run.Raw('||'),
- 'true',
- ],
- stdout=StringIO(),
- )
-
-
-def remove_sources(ctx, config):
- remove_sources_pkgs = {
- 'deb': _remove_sources_list_deb,
- 'rpm': _remove_sources_list_rpm,
- }
- log.info("Removing {proj} sources lists".format(proj=config.get('project', 'ceph')))
- with parallel() as p:
- for remote in ctx.cluster.remotes.iterkeys():
- system_type = teuthology.get_system_type(remote)
- p.spawn(remove_sources_pkgs[system_type], remote, config.get('project', 'ceph'))
-
-deb_packages = {'ceph': [
- 'ceph',
- 'ceph-dbg',
- 'ceph-mds',
- 'ceph-mds-dbg',
- 'ceph-common',
- 'ceph-common-dbg',
- 'ceph-fuse',
- 'ceph-fuse-dbg',
- 'ceph-test',
- 'ceph-test-dbg',
- 'radosgw',
- 'radosgw-dbg',
- 'python-ceph',
- 'libcephfs1',
- 'libcephfs1-dbg',
-]}
-
-rpm_packages = {'ceph': [
- 'ceph-debug',
- 'ceph-radosgw',
- 'ceph-test',
- 'ceph-devel',
- 'ceph',
- 'ceph-fuse',
- 'rest-bench',
- 'libcephfs_jni1',
- 'libcephfs1',
- 'python-ceph',
-]}
-
-
-@contextlib.contextmanager
-def install(ctx, config):
-
- project = config.get('project', 'ceph')
-
- global deb_packages
- global rpm_packages
- debs = deb_packages.get(project, [])
- rpm = rpm_packages.get(project, [])
-
- # pull any additional packages out of config
- extra_pkgs = config.get('extra_packages')
- log.info('extra packages: {packages}'.format(packages=extra_pkgs))
- debs += extra_pkgs
- rpm += extra_pkgs
-
- # the extras option right now is specific to the 'ceph' project
- extras = config.get('extras')
- if extras is not None:
- debs = ['ceph-test', 'ceph-test-dbg', 'ceph-fuse', 'ceph-fuse-dbg', 'librados2', 'librados2-dbg', 'librbd1', 'librbd1-dbg', 'python-ceph']
- rpm = ['ceph-fuse', 'librbd1', 'librados2', 'ceph-test', 'python-ceph']
-
- # install lib deps (so we explicitly specify version), but do not
- # uninstall them, as other packages depend on them (e.g., kvm)
- proj_install_debs = {'ceph': [
- 'librados2',
- 'librados2-dbg',
- 'librbd1',
- 'librbd1-dbg',
- ]}
-
- proj_install_rpm = {'ceph': [
- 'librbd1',
- 'librados2',
- ]}
-
- install_debs = proj_install_debs.get(project, [])
- install_rpm = proj_install_rpm.get(project, [])
-
- install_info = {
- "deb": debs + install_debs,
- "rpm": rpm + install_rpm}
- remove_info = {
- "deb": debs,
- "rpm": rpm}
- install_packages(ctx, install_info, config)
- try:
- yield
- finally:
- remove_packages(ctx, config, remove_info)
- remove_sources(ctx, config)
- if project == 'ceph':
- purge_data(ctx)
-
-
-def _upgrade_deb_packages(ctx, config, remote, debs, branch):
- """
- upgrade all packages
- """
- # check for ceph release key
- r = remote.run(
- args=[
- 'sudo', 'apt-key', 'list', run.Raw('|'), 'grep', 'Ceph',
- ],
- stdout=StringIO(),
- )
- if r.stdout.getvalue().find('Ceph automated package') == -1:
- # if it doesn't exist, add it
- remote.run(
- args=[
- 'wget', '-q', '-O-',
- 'https://ceph.com/git/?p=ceph.git;a=blob_plain;f=keys/autobuild.asc',
- run.Raw('|'),
- 'sudo', 'apt-key', 'add', '-',
- ],
- stdout=StringIO(),
- )
-
- # get distro name and arch
- r = remote.run(
- args=['lsb_release', '-sc'],
- stdout=StringIO(),
- )
- dist = r.stdout.getvalue().strip()
- r = remote.run(
- args=['arch'],
- stdout=StringIO(),
- )
- arch = r.stdout.getvalue().strip()
- log.info("dist %s arch %s", dist, arch)
-
- # branch/tag/sha1 flavor
- flavor = 'basic'
- uri = 'ref/' + branch
- base_url = 'http://{host}/{proj}-deb-{dist}-{arch}-{flavor}/{uri}'.format(
- host=ctx.teuthology_config.get('gitbuilder_host',
- 'gitbuilder.ceph.com'),
- proj=config.get('project', 'ceph'),
- dist=dist,
- arch=arch,
- flavor=flavor,
- uri=uri,
- )
- log.info('Pulling from %s', base_url)
-
- # get package version string
- while True:
- r = remote.run(
- args=[
- 'wget', '-q', '-O-', base_url + '/version',
- ],
- stdout=StringIO(),
- check_status=False,
- )
- if r.exitstatus != 0:
- time.sleep(15)
- raise Exception('failed to fetch package version from %s' %
- base_url + '/version')
- version = r.stdout.getvalue().strip()
- log.info('Package version is %s', version)
- break
- remote.run(
- args=[
- 'echo', 'deb', base_url, dist, 'main',
- run.Raw('|'),
- 'sudo', 'tee', '/etc/apt/sources.list.d/{proj}.list'.format(proj=config.get('project', 'ceph')),
- ],
- stdout=StringIO(),
- )
- remote.run(
- args=[
- 'sudo', 'apt-get', 'update', run.Raw('&&'),
- 'sudo', 'DEBIAN_FRONTEND=noninteractive', 'apt-get', '-y', '--force-yes',
- '-o', run.Raw('Dpkg::Options::="--force-confdef"'), '-o', run.Raw('Dpkg::Options::="--force-confold"'),
- 'install',
- ] + ['%s=%s' % (d, version) for d in debs],
- stdout=StringIO(),
- )
-
-
-def _upgrade_rpm_packages(ctx, config, remote, pkgs, branch):
- """
- Upgrade RPM packages.
- """
- distinfo = _get_baseurlinfo_and_dist(ctx, remote, config)
- log.info(
- "Host {host} is: {distro} {ver} {arch}".format(
- host=remote.shortname,
- distro=distinfo['distro'],
- ver=distinfo['relval'],
- arch=distinfo['arch'],)
- )
-
- base_url = _get_baseurl(ctx, remote, config)
- log.info('Repo base URL: %s', base_url)
- version = _block_looking_for_package_version(
- remote,
- base_url,
- config.get('wait_for_package', False))
- # FIXME: 'version' as retreived from the repo is actually the RPM version
- # PLUS *part* of the release. Example:
- # Right now, ceph master is given the following version in the repo file:
- # v0.67-rc3.164.gd5aa3a9 - whereas in reality the RPM version is 0.61.7
- # and the release is 37.g1243c97.el6 (for centos6).
- # Point being, I have to mangle a little here.
- if version[0] == 'v':
- version = version[1:]
- version = "{repover}.{therest}".format(
- repover=version,
- therest=distinfo['dist_release'],
- )
-
- project = config.get('project', 'ceph')
-
- # Remove the -release package before upgrading it
- args = ['sudo', 'rpm', '-ev', '%s-release' % project]
- _run_and_log_error_if_fails(remote, args)
-
- # Build the new -release package path
- release_rpm = "{base}/noarch/{proj}-release-{release}.{dist_release}.noarch.rpm".format(
- base=base_url,
- proj=project,
- release=RELEASE,
- dist_release=distinfo['dist_release'],
- )
-
- # Upgrade the -release package
- args = ['sudo', 'rpm', '-Uv', release_rpm]
- _run_and_log_error_if_fails(remote, args)
- _yum_fix_repo_priority(remote, project)
-
- # Build a space-separated string consisting of $PKG-$VER for yum
- pkgs_with_vers = ["%s-%s" % (pkg, version) for pkg in pkgs]
-
- # Actually upgrade the project packages
- # FIXME: This currently outputs nothing until the command is finished
- # executing. That sucks; fix it.
- args = ['sudo', 'yum', '-y', 'install']
- args += pkgs_with_vers
- _run_and_log_error_if_fails(remote, args)
-
-
-@contextlib.contextmanager
-def upgrade(ctx, config):
- """
- upgrades project debian packages.
-
- For example::
-
- tasks:
- - install.upgrade:
- all:
- branch: end
- or
- tasks:
- - install.upgrade:
- mon.a:
- branch: end
- osd.0:
- branch: other
- """
- assert config is None or isinstance(config, dict), \
- "install.upgrade only supports a dictionary for configuration"
-
- for i in config.keys():
- assert isinstance(config.get(i), dict), 'host supports dictionary'
-
- branch = None
-
- project = config.get('project', 'ceph')
-
- # FIXME: extra_pkgs is not distro-agnostic
- extra_pkgs = config.get('extra_packages', [])
- log.info('extra packages: {packages}'.format(packages=extra_pkgs))
-
- if config.get('all') is not None:
- node = config.get('all')
- for var, branch_val in node.iteritems():
- if var == 'branch' or var == 'tag' or var == 'sha1':
- branch = branch_val
- for remote in ctx.cluster.remotes.iterkeys():
- system_type = teuthology.get_system_type(remote)
- assert system_type in ('deb', 'rpm')
- pkgs = PACKAGES[project][system_type]
- log.info("Upgrading {proj} {system_type} packages: {pkgs}".format(
- proj=project, system_type=system_type, pkgs=', '.join(pkgs)))
- # FIXME: again, make extra_pkgs distro-agnostic
- pkgs += extra_pkgs
- if system_type == 'deb':
- _upgrade_deb_packages(ctx, config, remote, pkgs, branch)
- elif system_type == 'rpm':
- _upgrade_rpm_packages(ctx, config, remote, pkgs, branch)
- else:
- list_roles = []
- for role in config.keys():
- (remote,) = ctx.cluster.only(role).remotes.iterkeys()
- kkeys = config.get(role)
- if remote in list_roles:
- continue
- else:
- for var, branch_val in kkeys.iteritems():
- if var == 'branch' or var == 'tag' or var == 'sha1':
- branch = branch_val
- system_type = teuthology.get_system_type(remote)
- assert system_type in ('deb', 'rpm')
- pkgs = PACKAGES[project][system_type]
- _upgrade_deb_packages(ctx, config, remote, pkgs, branch)
- list_roles.append(remote)
- yield
-
-
-@contextlib.contextmanager
-def task(ctx, config):
- """
- Install packages
-
- tasks:
- - install:
- project: ceph
- branch: bar
- - install:
- project: samba
- branch: foo
- extra_packages: ['samba']
-
- Overrides are project specific:
-
- overrides:
- install:
- ceph:
- sha1: ...
-
- """
- if config is None:
- config = {}
- assert isinstance(config, dict), \
- "task install only supports a dictionary for configuration"
-
- project, = config.get('project', 'ceph'),
- log.debug('project %s' % project)
- overrides = ctx.config.get('overrides')
- if overrides:
- install_overrides = overrides.get('install', {})
- teuthology.deep_merge(config, install_overrides.get(project, {}))
- log.debug('config %s' % config)
-
- # Flavor tells us what gitbuilder to fetch the prebuilt software
- # from. It's a combination of possible keywords, in a specific
- # order, joined by dashes. It is used as a URL path name. If a
- # match is not found, the teuthology run fails. This is ugly,
- # and should be cleaned up at some point.
-
- flavor = config.get('flavor', 'basic')
-
- if config.get('path'):
- # local dir precludes any other flavors
- flavor = 'local'
- else:
- if config.get('valgrind'):
- log.info('Using notcmalloc flavor and running some daemons under valgrind')
- flavor = 'notcmalloc'
- else:
- if config.get('coverage'):
- log.info('Recording coverage for this run.')
- flavor = 'gcov'
-
- ctx.summary['flavor'] = flavor
-
- with contextutil.nested(
- lambda: install(ctx=ctx, config=dict(
- branch=config.get('branch'),
- tag=config.get('tag'),
- sha1=config.get('sha1'),
- flavor=flavor,
- extra_packages=config.get('extra_packages', []),
- extras=config.get('extras', None),
- wait_for_package=ctx.config.get('wait-for-package', False),
- project=project,
- )),
- ):
- yield
diff --git a/teuthology/task/interactive.py b/teuthology/task/interactive.py
deleted file mode 100644
index debbf51fb..000000000
--- a/teuthology/task/interactive.py
+++ /dev/null
@@ -1,33 +0,0 @@
-import code
-import readline
-import rlcompleter
-rlcompleter.__name__ # silence pyflakes
-
-readline.parse_and_bind('tab: complete')
-
-def task(ctx, config):
- """
- Run an interactive Python shell, with the cluster accessible via
- the ``ctx`` variable.
-
- Hit ``control-D`` to continue.
-
- This is also useful to pause the execution of the test between two
- tasks, either to perform ad hoc operations, or to examine the
- state of the cluster. You can also use it to easily bring up a
- Ceph cluster for ad hoc testing.
-
- For example::
-
- tasks:
- - ceph:
- - interactive:
- """
- code.interact(
- banner='Ceph test interactive mode, use ctx to interact with the cluster, press control-D to exit...',
- # TODO simplify this
- local=dict(
- ctx=ctx,
- config=config,
- ),
- )
diff --git a/teuthology/task/internal.py b/teuthology/task/internal.py
deleted file mode 100644
index 755af8f52..000000000
--- a/teuthology/task/internal.py
+++ /dev/null
@@ -1,540 +0,0 @@
-from cStringIO import StringIO
-import contextlib
-import gevent
-import logging
-import os
-import time
-import yaml
-import re
-import subprocess
-
-from teuthology import lockstatus
-from teuthology import lock
-from teuthology import misc as teuthology
-from teuthology.parallel import parallel
-from ..orchestra import run
-
-log = logging.getLogger(__name__)
-
-@contextlib.contextmanager
-def base(ctx, config):
- log.info('Creating base directory...')
- test_basedir = teuthology.get_testdir_base(ctx)
- testdir = teuthology.get_testdir(ctx)
- # make base dir if it doesn't exist
- run.wait(
- ctx.cluster.run(
- args=[
- 'mkdir', '-m0755', '-p', '--',
- test_basedir,
- ],
- wait=False,
- )
- )
- # only create testdir if its not set to basedir
- if test_basedir != testdir:
- run.wait(
- ctx.cluster.run(
- args=[
- 'mkdir', '-m0755', '--',
- testdir,
- ],
- wait=False,
- )
- )
-
- try:
- yield
- finally:
- log.info('Tidying up after the test...')
- # if this fails, one of the earlier cleanups is flawed; don't
- # just cram an rm -rf here
- run.wait(
- ctx.cluster.run(
- args=[
- 'rmdir',
- '--',
- testdir,
- ],
- wait=False,
- ),
- )
-
-
-@contextlib.contextmanager
-def lock_machines(ctx, config):
- log.info('Locking machines...')
- assert isinstance(config[0], int), 'config must be an integer'
- machine_type = config[1]
- config = config[0]
-
- while True:
- # make sure there are enough machines up
- machines = lock.list_locks(ctx)
- if machines is None:
- if ctx.block:
- log.warn('error listing machines, trying again')
- time.sleep(20)
- continue
- else:
- assert 0, 'error listing machines'
- num_up = len(filter(lambda machine: machine['up'] and machine['type'] == machine_type, machines))
- assert num_up >= config, 'not enough machines are up'
-
- # make sure there are machines for non-automated jobs to run
- num_free = len(filter(
- lambda machine: machine['up'] and machine['locked'] == 0 and machine['type'] == machine_type,
- machines
- ))
- if num_free < 6 and ctx.owner.startswith('scheduled'):
- if ctx.block:
- log.info('waiting for more machines to be free...')
- time.sleep(10)
- continue
- else:
- assert 0, 'not enough machines free'
-
- newly_locked = lock.lock_many(ctx, config, machine_type, ctx.owner, ctx.archive)
- if len(newly_locked) == config:
- vmlist = []
- for lmach in newly_locked:
- if lock.create_if_vm(ctx,lmach):
- vmlist.append(lmach)
- if vmlist:
- log.info('Waiting for virtual machines to come up')
- keyscan_out = ''
- loopcount=0
- while len(keyscan_out.splitlines()) != len(vmlist):
- loopcount += 1
- time.sleep(10)
- keyscan_out, current_locks = lock.keyscan_check(ctx, vmlist)
- log.info('virtual machine is stil unavailable')
- if loopcount == 40:
- loopcount = 0
- log.info('virtual machine(s) still not up, recreating unresponsive ones.')
- for guest in vmlist:
- if guest not in keyscan_out:
- log.info('recreating: ' + guest)
- lock.destroy_if_vm(ctx, 'ubuntu@' + guest)
- lock.create_if_vm(ctx, 'ubuntu@' + guest)
- if lock.update_keys(ctx, keyscan_out, current_locks):
- log.info("Error in virtual machine keys")
- newscandict = {}
- for dkey in newly_locked.iterkeys():
- stats = lockstatus.get_status(ctx, dkey)
- newscandict[dkey] = stats['sshpubkey']
- ctx.config['targets'] = newscandict
- else:
- ctx.config['targets'] = newly_locked
- log.info('\n '.join(['Locked targets:', ] + yaml.safe_dump(ctx.config['targets'], default_flow_style=False).splitlines()))
- break
- elif not ctx.block:
- assert 0, 'not enough machines are available'
-
- log.warn('Could not lock enough machines, waiting...')
- time.sleep(10)
- try:
- yield
- finally:
- if ctx.summary.get('success', False):
- log.info('Unlocking machines...')
- for machine in ctx.config['targets'].iterkeys():
- lock.unlock(ctx, machine, ctx.owner)
-
-def save_config(ctx, config):
- log.info('Saving configuration')
- if ctx.archive is not None:
- with file(os.path.join(ctx.archive, 'config.yaml'), 'w') as f:
- yaml.safe_dump(ctx.config, f, default_flow_style=False)
-
-def check_lock(ctx, config):
- if ctx.config.get('check-locks') == False:
- log.info('Lock checking disabled.')
- return
- log.info('Checking locks...')
- for machine in ctx.config['targets'].iterkeys():
- status = lockstatus.get_status(ctx, machine)
- log.debug('machine status is %s', repr(status))
- assert status is not None, \
- 'could not read lock status for {name}'.format(name=machine)
- assert status['up'], 'machine {name} is marked down'.format(name=machine)
- assert status['locked'], \
- 'machine {name} is not locked'.format(name=machine)
- assert status['locked_by'] == ctx.owner, \
- 'machine {name} is locked by {user}, not {owner}'.format(
- name=machine,
- user=status['locked_by'],
- owner=ctx.owner,
- )
-
-@contextlib.contextmanager
-def timer(ctx, config):
- log.info('Starting timer...')
- start = time.time()
- try:
- yield
- finally:
- duration = time.time() - start
- log.info('Duration was %f seconds', duration)
- ctx.summary['duration'] = duration
-
-def connect(ctx, config):
- log.info('Opening connections...')
- from ..orchestra import connection, remote
- from ..orchestra import cluster
- remotes = []
- machs = []
- for name in ctx.config['targets'].iterkeys():
- machs.append(name)
- for t, key in ctx.config['targets'].iteritems():
- log.debug('connecting to %s', t)
- try:
- if ctx.config['sshkeys'] == 'ignore':
- key = None
- except (AttributeError, KeyError):
- pass
- for machine in ctx.config['targets'].iterkeys():
- if teuthology.is_vm(machine):
- key = None
- break
- remotes.append(
- remote.Remote(name=t,
- ssh=connection.connect(user_at_host=t,
- host_key=key,
- keep_alive=True),
- console=None))
- ctx.cluster = cluster.Cluster()
- if 'roles' in ctx.config:
- for rem, roles in zip(remotes, ctx.config['roles']):
- assert all(isinstance(role, str) for role in roles), \
- "Roles in config must be strings: %r" % roles
- ctx.cluster.add(rem, roles)
- log.info('roles: %s - %s' % (rem, roles))
- else:
- for rem in remotes:
- ctx.cluster.add(rem, rem.name)
-
-def check_ceph_data(ctx, config):
- log.info('Checking for old /var/lib/ceph...')
- processes = ctx.cluster.run(
- args=[
- 'test', '!', '-e', '/var/lib/ceph',
- ],
- wait=False,
- )
- failed = False
- for proc in processes:
- assert isinstance(proc.exitstatus, gevent.event.AsyncResult)
- try:
- proc.exitstatus.get()
- except run.CommandFailedError:
- log.error('Host %s has stale /var/lib/ceph, check lock and nuke/cleanup.', proc.remote.shortname)
- failed = True
- if failed:
- raise RuntimeError('Stale /var/lib/ceph detected, aborting.')
-
-def check_conflict(ctx, config):
- log.info('Checking for old test directory...')
- test_basedir = teuthology.get_testdir_base(ctx)
- processes = ctx.cluster.run(
- args=[
- 'test', '!', '-e', test_basedir,
- ],
- wait=False,
- )
- for proc in processes:
- assert isinstance(proc.exitstatus, gevent.event.AsyncResult)
- try:
- proc.exitstatus.get()
- except run.CommandFailedError:
- # base dir exists
- r = proc.remote.run(
- args=[
- 'ls', test_basedir, run.Raw('|'), 'wc', '-l'
- ],
- stdout=StringIO(),
- )
-
- if int(r.stdout.getvalue()) > 0:
- log.error('WARNING: Host %s has stale test directories, these need to be investigated and cleaned up!',
- proc.remote.shortname)
-
- # testdir might be the same as base dir (if test_path is set)
- # need to bail out in that case if the testdir exists
- testdir = teuthology.get_testdir(ctx)
- processes = ctx.cluster.run(
- args=[
- 'test', '!', '-e', testdir,
- ],
- wait=False,
- )
- failed = False
- for proc in processes:
- assert isinstance(proc.exitstatus, gevent.event.AsyncResult)
- try:
- proc.exitstatus.get()
- except run.CommandFailedError:
- log.error('Host %s has stale test directory %s, check lock and cleanup.', proc.remote.shortname, testdir)
- failed = True
- if failed:
- raise RuntimeError('Stale jobs detected, aborting.')
-
-@contextlib.contextmanager
-def archive(ctx, config):
- log.info('Creating archive directory...')
- testdir = teuthology.get_testdir(ctx)
- archive_dir = '{tdir}/archive'.format(tdir=testdir)
- run.wait(
- ctx.cluster.run(
- args=[
- 'install', '-d', '-m0755', '--', archive_dir,
- ],
- wait=False,
- )
- )
-
- try:
- yield
- except:
- # we need to know this below
- ctx.summary['success'] = False
- raise
- finally:
- if ctx.archive is not None and \
- not (ctx.config.get('archive-on-error') and ctx.summary['success']):
- log.info('Transferring archived files...')
- logdir = os.path.join(ctx.archive, 'remote')
- if (not os.path.exists(logdir)):
- os.mkdir(logdir)
- for remote in ctx.cluster.remotes.iterkeys():
- path = os.path.join(logdir, remote.shortname)
- teuthology.pull_directory(remote, archive_dir, path)
-
- log.info('Removing archive directory...')
- run.wait(
- ctx.cluster.run(
- args=[
- 'rm',
- '-rf',
- '--',
- archive_dir,
- ],
- wait=False,
- ),
- )
-
-@contextlib.contextmanager
-def coredump(ctx, config):
- log.info('Enabling coredump saving...')
- archive_dir = '{tdir}/archive'.format(tdir=teuthology.get_testdir(ctx))
- run.wait(
- ctx.cluster.run(
- args=[
- 'install', '-d', '-m0755', '--',
- '{adir}/coredump'.format(adir=archive_dir),
- run.Raw('&&'),
- 'sudo', 'sysctl', '-w', 'kernel.core_pattern={adir}/coredump/%t.%p.core'.format(adir=archive_dir),
- ],
- wait=False,
- )
- )
-
- try:
- yield
- finally:
- run.wait(
- ctx.cluster.run(
- args=[
- 'sudo', 'sysctl', '-w', 'kernel.core_pattern=core',
- run.Raw('&&'),
- # don't litter the archive dir if there were no cores dumped
- 'rmdir',
- '--ignore-fail-on-non-empty',
- '--',
- '{adir}/coredump'.format(adir=archive_dir),
- ],
- wait=False,
- )
- )
-
- # set success=false if the dir is still there = coredumps were
- # seen
- for remote in ctx.cluster.remotes.iterkeys():
- r = remote.run(
- args=[
- 'if', 'test', '!', '-e', '{adir}/coredump'.format(adir=archive_dir), run.Raw(';'), 'then',
- 'echo', 'OK', run.Raw(';'),
- 'fi',
- ],
- stdout=StringIO(),
- )
- if r.stdout.getvalue() != 'OK\n':
- log.warning('Found coredumps on %s, flagging run as failed', remote)
- ctx.summary['success'] = False
- if 'failure_reason' not in ctx.summary:
- ctx.summary['failure_reason'] = \
- 'Found coredumps on {remote}'.format(remote=remote)
-
-@contextlib.contextmanager
-def syslog(ctx, config):
- if ctx.archive is None:
- # disable this whole feature if we're not going to archive the data anyway
- yield
- return
-
- log.info('Starting syslog monitoring...')
-
- archive_dir = '{tdir}/archive'.format(tdir=teuthology.get_testdir(ctx))
- run.wait(
- ctx.cluster.run(
- args=[
- 'mkdir', '-m0755', '--',
- '{adir}/syslog'.format(adir=archive_dir),
- ],
- wait=False,
- )
- )
-
- CONF = '/etc/rsyslog.d/80-cephtest.conf'
- conf_fp = StringIO("""
-kern.* -{adir}/syslog/kern.log;RSYSLOG_FileFormat
-*.*;kern.none -{adir}/syslog/misc.log;RSYSLOG_FileFormat
-""".format(adir=archive_dir))
- try:
- for rem in ctx.cluster.remotes.iterkeys():
- teuthology.sudo_write_file(
- remote=rem,
- path=CONF,
- data=conf_fp,
- )
- conf_fp.seek(0)
- run.wait(
- ctx.cluster.run(
- args=[
- 'sudo',
- 'service',
- # a mere reload (SIGHUP) doesn't seem to make
- # rsyslog open the files
- 'rsyslog',
- 'restart',
- ],
- wait=False,
- ),
- )
-
- yield
- finally:
- log.info('Shutting down syslog monitoring...')
-
- run.wait(
- ctx.cluster.run(
- args=[
- 'sudo',
- 'rm',
- '-f',
- '--',
- CONF,
- run.Raw('&&'),
- 'sudo',
- 'service',
- 'rsyslog',
- 'restart',
- ],
- wait=False,
- ),
- )
- # race condition: nothing actually says rsyslog had time to
- # flush the file fully. oh well.
-
- log.info('Checking logs for errors...')
- for remote in ctx.cluster.remotes.iterkeys():
- log.debug('Checking %s', remote.name)
- r = remote.run(
- args=[
- 'egrep',
- '\\bBUG\\b|\\bINFO\\b|\\bDEADLOCK\\b',
- run.Raw('{adir}/archive/syslog/*.log'.format(adir=archive_dir)),
- run.Raw('|'),
- 'grep', '-v', 'task .* blocked for more than .* seconds',
- run.Raw('|'),
- 'grep', '-v', 'lockdep is turned off',
- run.Raw('|'),
- 'grep', '-v', 'trying to register non-static key',
- run.Raw('|'),
- 'grep', '-v', 'DEBUG: fsize', # xfs_fsr
- run.Raw('|'),
- 'grep', '-v', 'CRON', # ignore cron noise
- run.Raw('|'),
- 'grep', '-v', 'inconsistent lock state', # FIXME see #2523
- run.Raw('|'),
- 'grep', '-v', '*** DEADLOCK ***', # part of lockdep output
- run.Raw('|'),
- 'grep', '-v', 'INFO: possible irq lock inversion dependency detected', # FIXME see #2590 and #147
- run.Raw('|'),
- 'grep', '-v', 'INFO: possible recursive locking detected', # FIXME see #3040
- run.Raw('|'),
- 'grep', '-v', 'BUG: lock held when returning to user space', # REMOVE ME when btrfs sb_internal crap is fixed
- run.Raw('|'),
- 'grep', '-v', 'INFO: possible circular locking dependency detected', # FIXME remove when xfs stops being noisy and lame.
- run.Raw('|'),
- 'head', '-n', '1',
- ],
- stdout=StringIO(),
- )
- stdout = r.stdout.getvalue()
- if stdout != '':
- log.error('Error in syslog on %s: %s', remote.name, stdout)
- ctx.summary['success'] = False
- if 'failure_reason' not in ctx.summary:
- ctx.summary['failure_reason'] = \
- "'{error}' in syslog".format(error=stdout)
-
- log.info('Compressing syslogs...')
- run.wait(
- ctx.cluster.run(
- args=[
- 'find',
- '{adir}/archive/syslog'.format(adir=archive_dir),
- '-name',
- '*.log',
- '-print0',
- run.Raw('|'),
- 'xargs',
- '-0',
- '--no-run-if-empty',
- '--',
- 'gzip',
- '--',
- ],
- wait=False,
- ),
- )
-
-def vm_setup(ctx, config):
- """
- Look for virtual machines and handle their initialization
- """
- with parallel() as p:
- editinfo = os.path.join(os.path.dirname(__file__),'edit_sudoers.sh')
- for remote in ctx.cluster.remotes.iterkeys():
- mname = re.match(".*@([^\.]*)\.?.*", str(remote)).group(1)
- if teuthology.is_vm(mname):
- r = remote.run(args=['test', '-e', '/ceph-qa-ready',],
- stdout=StringIO(),
- check_status=False,)
- if r.exitstatus != 0:
- p1 = subprocess.Popen(['cat', editinfo], stdout=subprocess.PIPE)
- p2 = subprocess.Popen(['ssh','-t','-t',str(remote), 'sudo', 'sh'],stdin=p1.stdout, stdout=subprocess.PIPE)
- _,err = p2.communicate()
- if err:
- log.info("Edit of /etc/sudoers failed: %s",err)
- p.spawn(_handle_vm_init, remote)
-
-def _handle_vm_init(remote):
- log.info('Running ceph_qa_chef on ', remote)
- remote.run(args=['wget','-q','-O-',
- 'http://ceph.com/git/?p=ceph-qa-chef.git;a=blob_plain;f=solo/solo-from-scratch;hb=HEAD',
- run.Raw('|'),
- 'sh',
- ])
-
diff --git a/teuthology/task/kcon_most b/teuthology/task/kcon_most
deleted file mode 100755
index cef3d899a..000000000
--- a/teuthology/task/kcon_most
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/bin/sh
-
-# Adapted from ceph repo src/script/kcon_most.sh
-
-p() {
- echo "$*" > /sys/kernel/debug/dynamic_debug/control
-}
-
-usage() {
- echo "usage: $0 [on|off]"
- exit 1
-}
-
-if [ $# != "1" ];
-then
- usage
-fi
-
-if [ "$1" != "on" -a "$1" != "off" ];
-then
- usage
-fi
-
-if [ $1 = "on" ];
-then
- p 'module ceph +p'
- p 'module libceph +p'
- p 'module rbd +p'
- p 'file net/ceph/messenger.c -p'
- p 'file' `grep -- --- /sys/kernel/debug/dynamic_debug/control | grep ceph | awk '{print $1}' | sed 's/:/ line /'` '+p'
- p 'file' `grep -- === /sys/kernel/debug/dynamic_debug/control | grep ceph | awk '{print $1}' | sed 's/:/ line /'` '+p'
-else
- p 'module ceph -p'
- p 'module libceph -p'
- p 'module rbd -p'
- p 'file' `grep -- --- /sys/kernel/debug/dynamic_debug/control | grep ceph | awk '{print $1}' | sed 's/:/ line /'` '-p'
- p 'file' `grep -- === /sys/kernel/debug/dynamic_debug/control | grep ceph | awk '{print $1}' | sed 's/:/ line /'` '-p'
-fi
-exit 0
diff --git a/teuthology/task/kcon_most.py b/teuthology/task/kcon_most.py
deleted file mode 100644
index f9817313c..000000000
--- a/teuthology/task/kcon_most.py
+++ /dev/null
@@ -1,64 +0,0 @@
-import contextlib
-import logging
-
-from teuthology import misc as teuthology
-
-log = logging.getLogger(__name__)
-
-@contextlib.contextmanager
-def task(ctx, config):
- """
- Enable most ceph console logging
-
- Example that enables logging on all clients::
-
- tasks:
- - ceph:
- - kclient:
- - kcon_most
- - interactive:
-
- Example that enables logging only on the client using kclient::
-
- tasks:
- - ceph:
- - kclient: [client.0]
- - kcon_most [client.0]
- - interactive:
- """
- log.info('Enable additional kernel logging...')
- assert config is None or isinstance(config, list), \
- "task kcon_most got invalid config"
-
- if config is None:
- config = ['client.{id}'.format(id=id_)
- for id_ in teuthology.all_roles_of_type(ctx.cluster, 'client')]
- clients = list(teuthology.get_clients(ctx=ctx, roles=config))
-
- testdir = teuthology.get_testdir(ctx)
-
- for id_, remote in clients:
- # TODO: Don't have to run this more than once per node (remote)
- log.info('Enable logging on client.{id} at {remote} ...'.format(
- id=id_, remote=remote))
- remote.run(
- args=[
- 'sudo',
- '{tdir}/kcon_most'.format(tdir=testdir),
- 'on'
- ],
- )
-
- try:
- yield
- finally:
- log.info('Disable extra kernel logging on clients...')
- for id_, remote in clients:
- log.debug('Disable extra kernel logging on client.{id}...'.format(id=id_))
- remote.run(
- args=[
- 'sudo',
- '{tdir}/kcon_most'.format(tdir=testdir),
- 'off'
- ],
- )
diff --git a/teuthology/task/kernel.py b/teuthology/task/kernel.py
deleted file mode 100644
index a5ef4ae74..000000000
--- a/teuthology/task/kernel.py
+++ /dev/null
@@ -1,541 +0,0 @@
-from cStringIO import StringIO
-
-import logging
-import re
-import shlex
-
-from teuthology import misc as teuthology
-from ..orchestra import run
-
-log = logging.getLogger(__name__)
-
-def normalize_config(ctx, config):
- """
- Returns a config whose keys are all real roles.
- Generic roles (client, mon, osd, etc.) are replaced with
- the actual roles (client.0, client.1, etc.). If the config
- specifies a different version for a specific role, this is
- unchanged.
-
- For example, with 3 OSDs this::
-
- osd:
- tag: v3.0
- kdb: true
- osd.1:
- branch: new_btrfs
- kdb: false
- osd.3:
- deb: /path/to/linux-whatever.deb
-
- is transformed into::
-
- osd.0:
- tag: v3.0
- kdb: true
- osd.1:
- branch: new_btrfs
- kdb: false
- osd.2:
- tag: v3.0
- kdb: true
- osd.3:
- deb: /path/to/linux-whatever.deb
-
- If config is None or just specifies a version to use,
- it is applied to all nodes.
- """
- if config is None or \
- len(filter(lambda x: x in ['tag', 'branch', 'sha1', 'kdb',
- 'deb'],
- config.keys())) == len(config.keys()):
- new_config = {}
- if config is None:
- config = {'branch': 'master'}
- for _, roles_for_host in ctx.cluster.remotes.iteritems():
- new_config[roles_for_host[0]] = config
- return new_config
-
- new_config = {}
- for role, role_config in config.iteritems():
- if role_config is None:
- role_config = {'branch': 'master'}
- if '.' in role:
- new_config[role] = role_config
- else:
- for id_ in teuthology.all_roles_of_type(ctx.cluster, role):
- name = '{type}.{id}'.format(type=role, id=id_)
- # specific overrides generic
- if name not in config:
- new_config[name] = role_config
- return new_config
-
-def _find_arch_and_dist(ctx):
- """
- Return the arch and distro value as a tuple.
- """
- info = ctx.config.get('machine_type', 'plana')
- if teuthology.is_arm(info):
- return ('armv7l', 'quantal')
- return ('x86_64', 'precise')
-
-def validate_config(ctx, config):
- for _, roles_for_host in ctx.cluster.remotes.iteritems():
- kernel = None
- for role in roles_for_host:
- role_kernel = config.get(role, kernel)
- if kernel is None:
- kernel = role_kernel
- elif role_kernel is not None:
- assert kernel == role_kernel, \
- "everything on the same host must use the same kernel"
- if role in config:
- del config[role]
-
-def _vsplitter(version):
- """kernels from Calxeda are named ...ceph-...highbank
- kernels that we generate named ...-g
- This routine finds the text in front of the sha1 that is used by
- need_to_install() to extract information from the kernel name.
- """
-
- if version.endswith('highbank'):
- return 'ceph-'
- return '-g'
-
-def need_to_install(ctx, role, sha1):
- ret = True
- log.info('Checking kernel version of {role}, want {sha1}...'.format(
- role=role,
- sha1=sha1))
- version_fp = StringIO()
- ctx.cluster.only(role).run(
- args=[
- 'uname',
- '-r',
- ],
- stdout=version_fp,
- )
- version = version_fp.getvalue().rstrip('\n')
- splt = _vsplitter(version)
- if splt in version:
- _, current_sha1 = version.rsplit(splt, 1)
- dloc = current_sha1.find('-')
- if dloc > 0:
- current_sha1 = current_sha1[0:dloc]
- log.debug('current kernel version is: {version} sha1 {sha1}'.format(
- version=version,
- sha1=current_sha1))
- if sha1.startswith(current_sha1):
- log.debug('current sha1 is the same, do not need to install')
- ret = False
- else:
- log.debug('current kernel version is: {version}, unknown sha1'.format(
- version=version))
- version_fp.close()
- return ret
-
-def install_firmware(ctx, config):
- # uri = 'git://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git'
- uri = 'git://ceph.com/git/linux-firmware.git'
- fw_dir = '/lib/firmware/updates'
-
- for role in config.iterkeys():
- (role_remote,) = ctx.cluster.only(role).remotes.keys()
- log.info('Installing linux-firmware on {role}...'.format(role=role))
- role_remote.run(
- args=[
- # kludge around mysterious 0-byte .git/HEAD files
- 'cd', fw_dir,
- run.Raw('&&'),
- 'test', '-d', '.git',
- run.Raw('&&'),
- 'test', '!', '-s', '.git/HEAD',
- run.Raw('&&'),
- 'sudo', 'rm', '-rf', '.git',
- run.Raw(';'),
- # init
- 'sudo', 'install', '-d', '-m0755', fw_dir,
- run.Raw('&&'),
- 'cd', fw_dir,
- run.Raw('&&'),
- 'sudo', 'git', 'init',
- ],
- )
- role_remote.run(
- args=[
- 'sudo', 'git', '--git-dir=%s/.git' % fw_dir, 'config',
- '--get', 'remote.origin.url', run.Raw('>/dev/null'),
- run.Raw('||'),
- 'sudo', 'git', '--git-dir=%s/.git' % fw_dir,
- 'remote', 'add', 'origin', uri,
- ],
- )
- role_remote.run(
- args=[
- 'cd', fw_dir,
- run.Raw('&&'),
- 'sudo', 'git', 'fetch', 'origin',
- run.Raw('&&'),
- 'sudo', 'git', 'reset', '--hard', 'origin/master'
- ],
- )
-
-def download_deb(ctx, config):
- procs = {}
- for role, src in config.iteritems():
- (role_remote,) = ctx.cluster.only(role).remotes.keys()
- if src.find('/') >= 0:
- # local deb
- log.info('Copying kernel deb {path} to {role}...'.format(path=src,
- role=role))
- f = open(src, 'r')
- proc = role_remote.run(
- args=[
- 'python', '-c',
- 'import shutil, sys; shutil.copyfileobj(sys.stdin, file(sys.argv[1], "wb"))',
- '/tmp/linux-image.deb',
- ],
- wait=False,
- stdin=f
- )
- procs[role_remote.name] = proc
-
- else:
- log.info('Downloading kernel {sha1} on {role}...'.format(sha1=src,
- role=role))
- larch, ldist = _find_arch_and_dist(ctx)
- _, deb_url = teuthology.get_ceph_binary_url(
- package='kernel',
- sha1=src,
- format='deb',
- flavor='basic',
- arch=larch,
- dist=ldist,
- )
-
- log.info('fetching kernel from {url}'.format(url=deb_url))
- proc = role_remote.run(
- args=[
- 'sudo', 'rm', '-f', '/tmp/linux-image.deb',
- run.Raw('&&'),
- 'echo',
- 'linux-image.deb',
- run.Raw('|'),
- 'wget',
- '-nv',
- '-O',
- '/tmp/linux-image.deb',
- '--base={url}'.format(url=deb_url),
- '--input-file=-',
- ],
- wait=False)
- procs[role_remote.name] = proc
-
- for name, proc in procs.iteritems():
- log.debug('Waiting for download/copy to %s to complete...', name)
- proc.exitstatus.get()
-
-
-def _no_grub_link(in_file, remote, kernel_ver):
- boot1 = '/boot/%s' % in_file
- boot2 = '%s.old' % boot1
- remote.run(
- args=[
- 'if', 'test', '-e', boot1, run.Raw(';'), 'then',
- 'sudo', 'mv', boot1, boot2, run.Raw(';'), 'fi',],
- )
- remote.run(
- args=['sudo', 'ln', '-s', '%s-%s' % (in_file, kernel_ver) , boot1, ],
- )
-
-def install_and_reboot(ctx, config):
- procs = {}
- kernel_title = ''
- for role, src in config.iteritems():
- log.info('Installing kernel {src} on {role}...'.format(src=src,
- role=role))
- (role_remote,) = ctx.cluster.only(role).remotes.keys()
- proc = role_remote.run(
- args=[
- # install the kernel deb
- 'sudo',
- 'dpkg',
- '-i',
- '/tmp/linux-image.deb',
- ],
- )
-
- # collect kernel image name from the .deb
- cmdout = StringIO()
- proc = role_remote.run(
- args=[
- # extract the actual boot image name from the deb
- 'dpkg-deb',
- '--fsys-tarfile',
- '/tmp/linux-image.deb',
- run.Raw('|'),
- 'tar',
- '-t',
- '-v',
- '-f', '-',
- '--wildcards',
- '--',
- './boot/vmlinuz-*',
- run.Raw('|'),
- 'sed',
- r'-e s;.*\./boot/vmlinuz-;;',
- ],
- stdout = cmdout,
- )
- kernel_title = cmdout.getvalue().rstrip()
- cmdout.close()
- log.info('searching for kernel {}'.format(kernel_title))
-
- if kernel_title.endswith("-highbank"):
- _no_grub_link('vmlinuz', role_remote, kernel_title)
- _no_grub_link('initrd.img', role_remote, kernel_title)
- proc = role_remote.run(
- args=[
- 'sudo',
- 'shutdown',
- '-r',
- 'now',
- ],
- wait=False,
- )
- procs[role_remote.name] = proc
- continue
-
- # look for menuentry for our kernel, and collect any
- # submenu entries for their titles. Assume that if our
- # kernel entry appears later in the file than a submenu entry,
- # it's actually nested under that submenu. If it gets more
- # complex this will totally break.
-
- cmdout = StringIO()
- proc = role_remote.run(
- args=[
- 'egrep',
- '(submenu|menuentry.*' + kernel_title + ').*{',
- '/boot/grub/grub.cfg'
- ],
- stdout = cmdout,
- )
- submenu_title = ''
- default_title = ''
- for l in cmdout.getvalue().split('\n'):
- fields = shlex.split(l)
- if len(fields) >= 2:
- command, title = fields[:2]
- if command == 'submenu':
- submenu_title = title + '>'
- if command == 'menuentry':
- if title.endswith(kernel_title):
- default_title = title
- break
- cmdout.close()
- log.info('submenu_title:{}'.format(submenu_title))
- log.info('default_title:{}'.format(default_title))
-
- proc = role_remote.run(
- args=[
- # use the title(s) to construct the content of
- # the grub menu entry, so we can default to it.
- '/bin/echo',
- '-e',
- r'cat </dev/null'),
- run.Raw('&&'),
- 'sudo',
- 'chmod',
- 'a+x',
- '--',
- '/etc/grub.d/01_ceph_kernel.tmp~',
- run.Raw('&&'),
- 'sudo',
- 'mv',
- '--',
- '/etc/grub.d/01_ceph_kernel.tmp~',
- '/etc/grub.d/01_ceph_kernel',
- # update grub again so it accepts our default
- run.Raw('&&'),
- 'sudo',
- 'update-grub',
- run.Raw('&&'),
- 'rm',
- '/tmp/linux-image.deb',
- run.Raw('&&'),
- 'sudo',
- 'shutdown',
- '-r',
- 'now',
- ],
- wait=False,
- )
- procs[role_remote.name] = proc
-
- for name, proc in procs.iteritems():
- log.debug('Waiting for install on %s to complete...', name)
- proc.exitstatus.get()
-
-def enable_disable_kdb(ctx, config):
- for role, enable in config.iteritems():
- (role_remote,) = ctx.cluster.only(role).remotes.keys()
- if "mira" in role_remote.name:
- serialdev = "ttyS2"
- else:
- serialdev = "ttyS1"
- if enable:
- log.info('Enabling kdb on {role}...'.format(role=role))
- role_remote.run(
- args=[
- 'echo', serialdev,
- run.Raw('|'),
- 'sudo', 'tee', '/sys/module/kgdboc/parameters/kgdboc'
- ])
- else:
- log.info('Disabling kdb on {role}...'.format(role=role))
- role_remote.run(
- args=[
- 'echo', '',
- run.Raw('|'),
- 'sudo', 'tee', '/sys/module/kgdboc/parameters/kgdboc'
- ])
-
-def wait_for_reboot(ctx, need_install, timeout):
- """
- Loop reconnecting and checking kernel versions until
- they're all correct or the timeout is exceeded.
- """
- import time
- starttime = time.time()
- while need_install:
- teuthology.reconnect(ctx, timeout)
- for client in need_install.keys():
- log.info('Checking client {client} for new kernel version...'.format(client=client))
- try:
- assert not need_to_install(ctx, client, need_install[client]), \
- 'failed to install new kernel version within timeout'
- del need_install[client]
- except:
- # ignore connection resets and asserts while time is left
- if time.time() - starttime > timeout:
- raise
- time.sleep(1)
-
-
-def task(ctx, config):
- """
- Make sure the specified kernel is installed.
- This can be a branch, tag, or sha1 of ceph-client.git.
-
- To install the kernel from the master branch on all hosts::
-
- kernel:
- tasks:
- - ceph:
-
- To wait 5 minutes for hosts to reboot::
-
- kernel:
- timeout: 300
- tasks:
- - ceph:
-
- To specify different kernels for each client::
-
- kernel:
- client.0:
- branch: foo
- client.1:
- tag: v3.0rc1
- client.2:
- sha1: db3540522e955c1ebb391f4f5324dff4f20ecd09
- tasks:
- - ceph:
-
- You can specify a branch, tag, or sha1 for all roles
- of a certain type (more specific roles override this)::
-
- kernel:
- client:
- tag: v3.0
- osd:
- branch: btrfs_fixes
- client.1:
- branch: more_specific_branch
- osd.3:
- branch: master
-
- To enable kdb::
-
- kernel:
- kdb: true
-
- """
- assert config is None or isinstance(config, dict), \
- "task kernel only supports a dictionary for configuration"
-
- timeout = 300
- if config is not None and 'timeout' in config:
- timeout = config.pop('timeout')
-
- config = normalize_config(ctx, config)
- validate_config(ctx, config)
- log.info('config %s' % config)
-
- need_install = {} # sha1 to dl, or path to deb
- need_sha1 = {} # sha1
- kdb = {}
- for role, role_config in config.iteritems():
- if role_config.get('deb'):
- path = role_config.get('deb')
- match = re.search('\d+-g(\w{7})', path)
- if match:
- sha1 = match.group(1)
- log.info('kernel deb sha1 appears to be %s', sha1)
- if need_to_install(ctx, role, sha1):
- need_install[role] = path
- need_sha1[role] = sha1
- else:
- log.info('unable to extract sha1 from deb path, forcing install')
- assert False
- else:
- larch, ldist = _find_arch_and_dist(ctx)
- sha1, _ = teuthology.get_ceph_binary_url(
- package='kernel',
- branch=role_config.get('branch'),
- tag=role_config.get('tag'),
- sha1=role_config.get('sha1'),
- flavor='basic',
- format='deb',
- dist=ldist,
- arch=larch,
- )
- log.debug('sha1 for {role} is {sha1}'.format(role=role, sha1=sha1))
- ctx.summary['{role}-kernel-sha1'.format(role=role)] = sha1
- if need_to_install(ctx, role, sha1):
- need_install[role] = sha1
- need_sha1[role] = sha1
-
- # enable or disable kdb if specified, otherwise do not touch
- if role_config.get('kdb') is not None:
- kdb[role] = role_config.get('kdb')
-
- if need_install:
- install_firmware(ctx, need_install)
- download_deb(ctx, need_install)
- install_and_reboot(ctx, need_install)
- wait_for_reboot(ctx, need_sha1, timeout)
-
- enable_disable_kdb(ctx, kdb)
diff --git a/teuthology/task/knfsd.py b/teuthology/task/knfsd.py
deleted file mode 100644
index dc46dac1c..000000000
--- a/teuthology/task/knfsd.py
+++ /dev/null
@@ -1,137 +0,0 @@
-import contextlib
-import logging
-import os
-
-from teuthology import misc as teuthology
-
-log = logging.getLogger(__name__)
-
-@contextlib.contextmanager
-def task(ctx, config):
- """
- Export/Unexport a ``nfs server`` client.
-
- The config is optional and defaults to exporting on all clients. If
- a config is given, it is expected to be a list or dict of clients to do
- this operation on. You must have specified ``ceph-fuse`` or
- ``kclient`` on all clients specified for knfsd.
-
- Example that exports all clients::
-
- tasks:
- - ceph:
- - kclient:
- - knfsd:
- - interactive:
-
- Example that uses both ``kclient` and ``ceph-fuse``::
-
- tasks:
- - ceph:
- - ceph-fuse: [client.0]
- - kclient: [client.1]
- - knfsd: [client.0, client.1]
- - interactive:
-
- Example that specifies export options::
-
- tasks:
- - ceph:
- - kclient: [client.0, client.1]
- - knfsd:
- client.0:
- options: [rw,root_squash]
- client.1:
- - interactive:
-
- Note that when options aren't specified, rw,no_root_squash is the default.
- When you specify options, the defaults are as specified by exports(5).
-
- So if empty options are specified, i.e. options: [] these are the defaults:
- ro,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,
- no_subtree_check,secure_locks,acl,anonuid=65534,anongid=65534
-
- """
- log.info('Exporting nfs server...')
-
- if config is None:
- config = dict(('client.{id}'.format(id=id_), None)
- for id_ in teuthology.all_roles_of_type(ctx.cluster, 'client'))
- elif isinstance(config, list):
- config = dict((name, None) for name in config)
-
- clients = list(teuthology.get_clients(ctx=ctx, roles=config.keys()))
-
- for id_, remote in clients:
- mnt = os.path.join(teuthology.get_testdir(ctx), 'mnt.{id}'.format(id=id_))
- client_config = config.get("client.%s" % id_)
- if client_config is None:
- client_config = {}
- log.debug("Client client.%s config is %s" % (id_, client_config))
-
- if client_config.get('options') is not None:
- opts = ','.join(client_config.get('options'))
- else:
- opts = 'rw,no_root_squash'
-
- # Undocumented option to export to any client in case
- # testing in interactive mode from other unspecified clients.
- wildcard = False
- if client_config.get('wildcard') is not None:
- wildcard = True
-
- log.info('Exporting knfsd client.{id} at {remote} *:{mnt} ({opt})...'.format(
- id=id_, remote=remote, mnt=mnt, opt=opts))
-
- """
- Should the user want to run with root_squash enabled, there is no
- way to write anything to the initial ceph root dir which is set to
- rwxr-xr-x root root.
-
- This could possibly break test cases that make assumptions about
- the initial state of the root dir.
- """
- remote.run(
- args=[
- 'sudo',
- 'chmod',
- "777",
- '{MNT}'.format(MNT=mnt),
- ],
- )
- args=[
- 'sudo',
- "exportfs",
- '-o',
- 'fsid=123{id},{opt}'.format(id=id_,opt=opts),
- ]
-
- if wildcard:
- args += ['*:{MNT}'.format(MNT=mnt)]
- else:
- """
- DEFAULT
- Prevent bogus clients from old runs from access our
- export. Specify all specify node addresses for this run.
- """
- ips = [host for (host, port) in (remote.ssh.get_transport().getpeername() for (remote, roles) in ctx.cluster.remotes.items())]
- for ip in ips:
- args += [ '{ip}:{MNT}'.format(ip=ip, MNT=mnt) ]
-
- log.info('remote run {args}'.format(args=args))
- remote.run( args=args )
-
- try:
- yield
- finally:
- log.info('Unexporting nfs server...')
- for id_, remote in clients:
- log.debug('Unexporting client client.{id}...'.format(id=id_))
- mnt = os.path.join(teuthology.get_testdir(ctx), 'mnt.{id}'.format(id=id_))
- remote.run(
- args=[
- 'sudo',
- 'exportfs',
- '-au',
- ],
- )
diff --git a/teuthology/task/localdir.py b/teuthology/task/localdir.py
deleted file mode 100644
index 8b54217e4..000000000
--- a/teuthology/task/localdir.py
+++ /dev/null
@@ -1,64 +0,0 @@
-import contextlib
-import logging
-import os
-
-from teuthology import misc as teuthology
-from ..orchestra import run
-
-log = logging.getLogger(__name__)
-
-@contextlib.contextmanager
-def task(ctx, config):
- """
- Create a mount dir 'client' that is just the local disk:
-
- Example that "mounts" all clients:
-
- tasks:
- - localdir:
- - interactive:
-
- Example for a specific client:
-
- tasks:
- - localdir: [client.2]
- - interactive:
-
- """
- log.info('Creating local mnt dirs...')
-
- testdir = teuthology.get_testdir(ctx)
-
- if config is None:
- config = list('client.{id}'.format(id=id_)
- for id_ in teuthology.all_roles_of_type(ctx.cluster,
- 'client'))
-
- clients = list(teuthology.get_clients(ctx=ctx, roles=config))
- for id_, remote in clients:
- mnt = os.path.join(testdir, 'mnt.{id}'.format(id=id_))
- log.info('Creating dir {remote} {mnt}...'.format(
- remote=remote, mnt=mnt))
- remote.run(
- args=[
- 'mkdir',
- '--',
- mnt,
- ],
- )
-
- try:
- yield
-
- finally:
- log.info('Removing local mnt dirs...')
- for id_, remote in clients:
- mnt = os.path.join(testdir, 'mnt.{id}'.format(id=id_))
- remote.run(
- args=[
- 'rm',
- '-rf',
- '--',
- mnt,
- ],
- )
diff --git a/teuthology/task/lockfile.py b/teuthology/task/lockfile.py
deleted file mode 100644
index 748b99806..000000000
--- a/teuthology/task/lockfile.py
+++ /dev/null
@@ -1,230 +0,0 @@
-import logging
-import os
-
-from ..orchestra import run
-from teuthology import misc as teuthology
-import time
-import gevent
-
-
-log = logging.getLogger(__name__)
-
-def task(ctx, config):
- """
- This task is designed to test locking. It runs an executable
- for each lock attempt you specify, at 0.01 second intervals (to
- preserve ordering of the locks).
- You can also introduce longer intervals by setting an entry
- as a number of seconds, rather than the lock dictionary.
- The config is a list of dictionaries. For each entry in the list, you
- must name the "client" to run on, the "file" to lock, and
- the "holdtime" to hold the lock.
- Optional entries are the "offset" and "length" of the lock. You can also specify a
- "maxwait" timeout period which fails if the executable takes longer
- to complete, and an "expectfail".
- An example:
- tasks:
- - ceph:
- - ceph-fuse: [client.0, client.1]
- - lockfile:
- [{client:client.0, file:testfile, holdtime:10},
- {client:client.1, file:testfile, holdtime:0, maxwait:0, expectfail:true},
- {client:client.1, file:testfile, holdtime:0, maxwait:15, expectfail:false},
- 10,
- {client: client.1, lockfile: testfile, holdtime: 5},
- {client: client.2, lockfile: testfile, holdtime: 5, maxwait: 1, expectfail: True}]
-
-
- In the past this test would have failed; there was a bug where waitlocks weren't
- cleaned up if the process failed. More involved scenarios are also possible.
- """
- log.info('Starting lockfile')
- try:
- assert isinstance(config, list), \
- "task lockfile got invalid config"
-
- log.info("building executable on each host")
- buildprocs = list()
- # build the locker executable on each client
- clients = list()
- files = list()
- for op in config:
- if not isinstance(op, dict):
- continue
- log.info("got an op")
- log.info("op['client'] = %s", op['client'])
- clients.append(op['client'])
- files.append(op['lockfile'])
- if not "expectfail" in op:
- op["expectfail"] = False
- badconfig = False
- if not "client" in op:
- badconfig = True
- if not "lockfile" in op:
- badconfig = True
- if not "holdtime" in op:
- badconfig = True
- if badconfig:
- raise KeyError("bad config {op_}".format(op_=op))
-
- testdir = teuthology.get_testdir(ctx)
- clients = set(clients)
- files = set(files)
- lock_procs = list()
- for client in clients:
- (client_remote,) = ctx.cluster.only(client).remotes.iterkeys()
- log.info("got a client remote")
- (_, _, client_id) = client.partition('.')
- filepath = os.path.join(testdir, 'mnt.{id}'.format(id=client_id), op["lockfile"])
-
- proc = client_remote.run(
- args=[
- 'mkdir', '-p', '{tdir}/archive/lockfile'.format(tdir=testdir),
- run.Raw('&&'),
- 'mkdir', '-p', '{tdir}/lockfile'.format(tdir=testdir),
- run.Raw('&&'),
- 'wget',
- '-nv',
- '--no-check-certificate',
- 'https://raw.github.com/gregsfortytwo/FileLocker/master/sclockandhold.cpp',
- '-O', '{tdir}/lockfile/sclockandhold.cpp'.format(tdir=testdir),
- run.Raw('&&'),
- 'g++', '{tdir}/lockfile/sclockandhold.cpp'.format(tdir=testdir),
- '-o', '{tdir}/lockfile/sclockandhold'.format(tdir=testdir)
- ],
- logger=log.getChild('lockfile_client.{id}'.format(id=client_id)),
- wait=False
- )
- log.info('building sclockandhold on client{id}'.format(id=client_id))
- buildprocs.append(proc)
-
- # wait for builds to finish
- run.wait(buildprocs)
- log.info('finished building sclockandhold on all clients')
-
- # create the files to run these locks on
- client = clients.pop()
- clients.add(client)
- (client_remote,) = ctx.cluster.only(client).remotes.iterkeys()
- (_, _, client_id) = client.partition('.')
- file_procs = list()
- for lockfile in files:
- filepath = os.path.join(testdir, 'mnt.{id}'.format(id=client_id), lockfile)
- proc = client_remote.run(
- args=[
- 'sudo',
- 'touch',
- filepath,
- ],
- logger=log.getChild('lockfile_createfile'),
- wait=False
- )
- file_procs.append(proc)
- run.wait(file_procs)
- file_procs = list()
- for lockfile in files:
- filepath = os.path.join(testdir, 'mnt.{id}'.format(id=client_id), lockfile)
- proc = client_remote.run(
- args=[
- 'sudo', 'chown', 'ubuntu.ubuntu', filepath
- ],
- logger=log.getChild('lockfile_createfile'),
- wait=False
- )
- file_procs.append(proc)
- run.wait(file_procs)
- log.debug('created files to lock')
-
- # now actually run the locktests
- for op in config:
- if not isinstance(op, dict):
- assert isinstance(op, int) or isinstance(op, float)
- log.info("sleeping for {sleep} seconds".format(sleep=op))
- time.sleep(op)
- continue
- greenlet = gevent.spawn(lock_one, op, ctx)
- lock_procs.append((greenlet, op))
- time.sleep(0.1) # to provide proper ordering
- #for op in config
-
- for (greenlet, op) in lock_procs:
- log.debug('checking lock for op {op_}'.format(op_=op))
- result = greenlet.get()
- if not result:
- raise Exception("Got wrong result for op {op_}".format(op_=op))
- # for (greenlet, op) in lock_procs
-
- finally:
- #cleanup!
- if lock_procs:
- for (greenlet, op) in lock_procs:
- log.debug('closing proc for op {op_}'.format(op_=op))
- greenlet.kill(block=True)
-
- for client in clients:
- (client_remote,) = ctx.cluster.only(client).remotes.iterkeys()
- (_, _, client_id) = client.partition('.')
- filepath = os.path.join(testdir, 'mnt.{id}'.format(id=client_id), op["lockfile"])
- proc = client_remote.run(
- args=[
- 'rm', '-rf', '{tdir}/lockfile'.format(tdir=testdir),
- run.Raw(';'),
- 'sudo', 'rm', '-rf', filepath
- ],
- wait=True
- ) #proc
- #done!
-# task
-
-def lock_one(op, ctx):
- log.debug('spinning up locker with op={op_}'.format(op_=op))
- timeout = None
- proc = None
- result = None
- (client_remote,) = ctx.cluster.only(op['client']).remotes.iterkeys()
- (_, _, client_id) = op['client'].partition('.')
- testdir = teuthology.get_testdir(ctx)
- filepath = os.path.join(testdir, 'mnt.{id}'.format(id=client_id), op["lockfile"])
-
- if "maxwait" in op:
- timeout = gevent.Timeout(seconds=float(op["maxwait"]))
- timeout.start()
- try:
- proc = client_remote.run(
- args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
- 'ceph-coverage',
- '{tdir}/archive/coverage'.format(tdir=testdir),
- '{tdir}/daemon-helper'.format(tdir=testdir),
- 'kill',
- '{tdir}/lockfile/sclockandhold'.format(tdir=testdir),
- filepath,
- '{holdtime}'.format(holdtime=op["holdtime"]),
- '{offset}'.format(offset=op.get("offset", '0')),
- '{length}'.format(length=op.get("length", '1')),
- ],
- logger=log.getChild('lockfile_client.{id}'.format(id=client_id)),
- wait=False,
- stdin=run.PIPE,
- check_status=False
- )
- result = proc.exitstatus.get()
- except gevent.Timeout as tout:
- if tout is not timeout:
- raise
- if bool(op["expectfail"]):
- result = 1
- if result is 1:
- if bool(op["expectfail"]):
- log.info("failed as expected for op {op_}".format(op_=op))
- else:
- raise Exception("Unexpectedly failed to lock {op_} within given timeout!".format(op_=op))
- finally: #clean up proc
- if timeout is not None:
- timeout.cancel()
- if proc is not None:
- proc.stdin.close()
-
- ret = (result == 0 and not bool(op["expectfail"])) or (result == 1 and bool(op["expectfail"]))
-
- return ret #we made it through
diff --git a/teuthology/task/mpi.py b/teuthology/task/mpi.py
deleted file mode 100644
index 773ab7645..000000000
--- a/teuthology/task/mpi.py
+++ /dev/null
@@ -1,106 +0,0 @@
-import logging
-
-from teuthology import misc as teuthology
-
-log = logging.getLogger(__name__)
-
-def task(ctx, config):
- """
- Setup MPI and execute commands
-
- Example that starts an MPI process on specific clients::
-
- tasks:
- - ceph:
- - ceph-fuse: [client.0, client.1]
- - ssh_keys:
- - mpi:
- nodes: [client.0, client.1]
- exec: ior ...
-
- Example that starts MPI processes on all clients::
-
- tasks:
- - ceph:
- - ceph-fuse:
- - ssh_keys:
- - mpi:
- exec: ior ...
-
- Example that starts MPI processes on all roles::
-
- tasks:
- - ceph:
- - ssh_keys:
- - mpi:
- nodes: all
- exec: ...
-
- Example that specifies a working directory for MPI processes:
-
- tasks:
- - ceph:
- - ceph-fuse:
- - pexec:
- clients:
- - ln -s {testdir}/mnt.* {testdir}/gmnt
- - ssh_keys:
- - mpi:
- exec: fsx-mpi
- workdir: {testdir}/gmnt
- - pexec:
- clients:
- - rm -f {testdir}/gmnt
-
- """
- assert isinstance(config, dict), 'task mpi got invalid config'
- assert 'exec' in config, 'task mpi got invalid config, missing exec'
-
- testdir = teuthology.get_testdir(ctx)
-
- mpiexec = config['exec'].replace('$TESTDIR', testdir)
- hosts = []
- remotes = []
- master_remote = None
- if 'nodes' in config:
- if isinstance(config['nodes'], basestring) and config['nodes'] == 'all':
- for role in teuthology.all_roles(ctx.cluster):
- (remote,) = ctx.cluster.only(role).remotes.iterkeys()
- ip,port = remote.ssh.get_transport().getpeername()
- hosts.append(ip)
- remotes.append(remote)
- (master_remote,) = ctx.cluster.only(config['nodes'][0]).remotes.iterkeys()
- elif isinstance(config['nodes'], list):
- for role in config['nodes']:
- (remote,) = ctx.cluster.only(role).remotes.iterkeys()
- ip,port = remote.ssh.get_transport().getpeername()
- hosts.append(ip)
- remotes.append(remote)
- (master_remote,) = ctx.cluster.only(config['nodes'][0]).remotes.iterkeys()
- else:
- roles = ['client.{id}'.format(id=id_) for id_ in teuthology.all_roles_of_type(ctx.cluster, 'client')]
- (master_remote,) = ctx.cluster.only(roles[0]).remotes.iterkeys()
- for role in roles:
- (remote,) = ctx.cluster.only(role).remotes.iterkeys()
- ip,port = remote.ssh.get_transport().getpeername()
- hosts.append(ip)
- remotes.append(remote)
-
- workdir = []
- if 'workdir' in config:
- workdir = ['-wdir', config['workdir'].replace('$TESTDIR', testdir) ]
-
- log.info('mpi rank 0 is: {name}'.format(name=master_remote.name))
-
- # write out the mpi hosts file
- log.info('mpi nodes: [%s]' % (', '.join(hosts)))
- teuthology.write_file(remote=master_remote,
- path='{tdir}/mpi-hosts'.format(tdir=testdir),
- data='\n'.join(hosts))
- log.info('mpiexec on {name}: {cmd}'.format(name=master_remote.name, cmd=mpiexec))
- args=['mpiexec', '-f', '{tdir}/mpi-hosts'.format(tdir=testdir)]
- args.extend(workdir)
- args.extend(mpiexec.split(' '))
- master_remote.run(args=args, )
- log.info('mpi task completed')
- master_remote.run(args=['rm', '{tdir}/mpi-hosts'.format(tdir=testdir)])
diff --git a/teuthology/task/nfs.py b/teuthology/task/nfs.py
deleted file mode 100644
index 52123f577..000000000
--- a/teuthology/task/nfs.py
+++ /dev/null
@@ -1,127 +0,0 @@
-import contextlib
-import logging
-import os
-
-from teuthology import misc as teuthology
-
-log = logging.getLogger(__name__)
-
-@contextlib.contextmanager
-def task(ctx, config):
- """
- Mount nfs client (requires nfs server export like knfsd or ganesh)
-
- Example that mounts a single nfs client::
-
- tasks:
- - ceph:
- - kclient: [client.0]
- - knfsd: [client.0]
- - nfs:
- client.1:
- server: client.0
- - interactive:
-
- Example that mounts multiple nfs clients with options::
-
- tasks:
- - ceph:
- - kclient: [client.0, client.1]
- - knfsd: [client.0, client.1]
- - nfs:
- client.2:
- server: client.0
- options: [rw,hard,intr,nfsvers=3]
- client.3:
- server: client.1
- options: [ro]
- - workunit:
- clients:
- client.2:
- - suites/dbench.sh
- client.3:
- - suites/blogbench.sh
-
- It is not recommended that the nfs client and nfs server reside on the same node. So in the example above client.0-3 should be on 4 distinct
- nodes. The client nfs testing would be using only client.2 and client.3.
- """
- log.info('Mounting nfs clients...')
- assert isinstance(config, dict)
-
- clients = list(teuthology.get_clients(ctx=ctx, roles=config.keys()))
-
- testdir = teuthology.get_testdir(ctx)
- for id_, remote in clients:
- mnt = os.path.join(testdir, 'mnt.{id}'.format(id=id_))
- client_config = config.get("client.%s" % id_)
- if client_config is None:
- client_config = {}
- log.debug("Client client.%s config is %s" % (id_, client_config))
-
- assert client_config.get('server') is not None
- server = client_config.get('server');
-
- svr_id = server[len('client.'):]
- svr_mnt = os.path.join(testdir, 'mnt.{id}'.format(id=svr_id))
-
- svr_remote = None
- all_config = ['client.{id}'.format(id=tmpid)
- for tmpid in teuthology.all_roles_of_type(ctx.cluster, 'client')]
- all_clients = list(teuthology.get_clients(ctx=ctx, roles=all_config))
- for tmpid, tmpremote in all_clients:
- if tmpid == svr_id:
- svr_remote = tmpremote
- break
-
- assert svr_remote is not None
- svr_remote = svr_remote.name.split('@', 2)[1]
-
- if client_config.get('options') is not None:
- opts = ','.join(client_config.get('options'))
- else:
- opts = 'rw'
-
- log.info('Mounting client.{id} from client.{sid}'.format(id=id_, sid=svr_id))
- log.debug('mount -o {opts} {remote}:{svr_mnt} {mnt}'.format(
- remote=svr_remote, svr_mnt=svr_mnt, opts=opts, mnt=mnt))
-
- remote.run(
- args=[
- 'mkdir',
- '--',
- mnt,
- ],
- )
-
- remote.run(
- args=[
- 'sudo',
- "mount",
- "-o",
- opts,
- '{remote}:{mnt}'.format(remote=svr_remote, mnt=svr_mnt),
- mnt
- ],
- )
-
- try:
- yield
- finally:
- log.info('Unmounting nfs clients...')
- for id_, remote in clients:
- log.debug('Unmounting nfs client client.{id}...'.format(id=id_))
- mnt = os.path.join(testdir, 'mnt.{id}'.format(id=id_))
- remote.run(
- args=[
- 'sudo',
- 'umount',
- mnt,
- ],
- )
- remote.run(
- args=[
- 'rmdir',
- '--',
- mnt,
- ],
- )
diff --git a/teuthology/task/nop.py b/teuthology/task/nop.py
deleted file mode 100644
index caa9deec2..000000000
--- a/teuthology/task/nop.py
+++ /dev/null
@@ -1,10 +0,0 @@
-def task(ctx, config):
- """
- This task does nothing.
-
- For example::
-
- tasks:
- - nop:
- """
- pass
diff --git a/teuthology/task/parallel.py b/teuthology/task/parallel.py
deleted file mode 100644
index 6127e07c7..000000000
--- a/teuthology/task/parallel.py
+++ /dev/null
@@ -1,54 +0,0 @@
-import sys
-import logging
-import contextlib
-
-from teuthology import run_tasks
-from teuthology import parallel
-from ..orchestra import run
-
-log = logging.getLogger(__name__)
-
-def task(ctx, config):
- """
- Run a group of tasks in parallel.
-
- example:
- - parallel:
- - tasktest:
- - tasktest:
-
- You can also reference the job from elsewhere:
-
- foo:
- tasktest:
- tasks:
- - parallel:
- - foo
- - tasktest:
-
- That is, if the entry is not a dict, we will look it up in the top-level
- config.
-
- Sequential task and Parallel tasks can be nested.
- """
-
- log.info('starting parallel...')
- with parallel.parallel() as p:
- for entry in config:
- if not isinstance(entry, dict):
- entry = ctx.config.get(entry, {})
- ((taskname, confg),) = entry.iteritems()
- p.spawn(_run_spawned, ctx, confg, taskname)
-
-def _run_spawned(ctx,config,taskname):
- mgr = {}
- try:
- log.info('In parallel, running task %s...' % taskname)
- mgr = run_tasks.run_one_task(taskname, ctx=ctx, config=config)
- if hasattr(mgr, '__enter__'):
- mgr.__enter__()
- finally:
- exc_info = sys.exc_info()
- if hasattr(mgr, '__exit__'):
- mgr.__exit__(*exc_info)
- del exc_info
diff --git a/teuthology/task/parallel_example.py b/teuthology/task/parallel_example.py
deleted file mode 100644
index 43fb187cb..000000000
--- a/teuthology/task/parallel_example.py
+++ /dev/null
@@ -1,55 +0,0 @@
-import contextlib
-import logging
-
-from teuthology import misc as teuthology
-from teuthology import contextutil
-from ..orchestra import run
-
-log = logging.getLogger(__name__)
-
-@contextlib.contextmanager
-def sequential_test(ctx, config):
- """Example contextmanager that executes a command on remote hosts sequentially."""
- for role in config:
- """Create a cluster composed of all hosts with the given role, and run the command on them sequentially."""
- log.info('Executing command on all hosts sequentially with role "%s"' % role)
- ctx.cluster.only(role).run(args=['sleep', '5', run.Raw(';'), 'date', run.Raw(';'), 'hostname'])
- yield
-
-@contextlib.contextmanager
-def parallel_test(ctx, config):
- """Example contextmanager that executes a command on remote hosts in parallel."""
- for role in config:
- """Create a cluster composed of all hosts with the given role, and run the command on them concurrently."""
- log.info('Executing command on all hosts concurrently with role "%s"' % role)
- cluster = ctx.cluster.only(role)
- nodes = {}
- for remote in cluster.remotes.iterkeys():
- """Call run for each remote host, but use 'wait=False' to have it return immediately."""
- proc = remote.run(args=['sleep', '5', run.Raw(';'), 'date', run.Raw(';'), 'hostname'], wait=False,)
- nodes[remote.name] = proc
- for name, proc in nodes.iteritems():
- """Wait for each process to finish before yielding and allowing other contextmanagers to run."""
- proc.exitstatus.get()
- yield
-
-@contextlib.contextmanager
-def task(ctx, config):
- """This is the main body of the task that gets run."""
-
- """Take car of some yaml parsing here"""
- if config is not None and not isinstance(config, list) and not isinstance(config, dict):
- assert(False), "task parallel_example only supports a list or dictionary for configuration"
- if config is None:
- config = ['client.{id}'.format(id=id_)
- for id_ in teuthology.all_roles_of_type(ctx.cluster, 'client')]
- if isinstance(config, list):
- config = dict.fromkeys(config)
- clients = config.keys()
-
- """Run Multiple contextmanagers sequentially by nesting them."""
- with contextutil.nested(
- lambda: parallel_test(ctx=ctx, config=clients),
- lambda: sequential_test(ctx=ctx, config=clients),
- ):
- yield
diff --git a/teuthology/task/pexec.py b/teuthology/task/pexec.py
deleted file mode 100644
index 9069ef74f..000000000
--- a/teuthology/task/pexec.py
+++ /dev/null
@@ -1,143 +0,0 @@
-import logging
-
-from teuthology import misc as teuthology
-from teuthology.parallel import parallel
-from teuthology.orchestra import run as tor
-
-log = logging.getLogger(__name__)
-
-from gevent import queue as queue
-from gevent import event as event
-
-def _init_barrier(barrier_queue, remote):
- barrier_queue.put(remote)
-
-def _do_barrier(barrier, barrier_queue, remote):
- # special case for barrier
- barrier_queue.get()
- if barrier_queue.empty():
- barrier.set()
- barrier.clear()
- else:
- barrier.wait()
-
- barrier_queue.put(remote)
- if barrier_queue.full():
- barrier.set()
- barrier.clear()
- else:
- barrier.wait()
-
-def _exec_host(barrier, barrier_queue, remote, sudo, testdir, ls):
- log.info('Running commands on host %s', remote.name)
- args = [
- 'TESTDIR={tdir}'.format(tdir=testdir),
- 'bash',
- '-s'
- ]
- if sudo:
- args.insert(0, 'sudo')
-
- r = remote.run( args=args, stdin=tor.PIPE, wait=False)
- r.stdin.writelines(['set -e\n'])
- r.stdin.flush()
- for l in ls:
- l.replace('$TESTDIR', testdir)
- if l == "barrier":
- _do_barrier(barrier, barrier_queue, remote)
- continue
-
- r.stdin.writelines([l, '\n'])
- r.stdin.flush()
- r.stdin.writelines(['\n'])
- r.stdin.flush()
- r.stdin.close()
- tor.wait([r])
-
-def _generate_remotes(ctx, config):
- if 'all' in config and len(config) == 1:
- ls = config['all']
- for remote in ctx.cluster.remotes.iterkeys():
- yield (remote, ls)
- elif 'clients' in config:
- ls = config['clients']
- for role in teuthology.all_roles_of_type(ctx.cluster, 'client'):
- (remote,) = ctx.cluster.only('client.{r}'.format(r=role)).remotes.iterkeys()
- yield (remote, ls)
- del config['clients']
- for role, ls in config.iteritems():
- (remote,) = ctx.cluster.only(role).remotes.iterkeys()
- yield (remote, ls)
- else:
- for role, ls in config.iteritems():
- (remote,) = ctx.cluster.only(role).remotes.iterkeys()
- yield (remote, ls)
-
-def task(ctx, config):
- """
- Execute commands on multiple hosts in parallel
-
- tasks:
- - ceph:
- - ceph-fuse: [client.0, client.1]
- - pexec:
- client.0:
- - while true; do echo foo >> bar; done
- client.1:
- - sleep 1
- - tail -f bar
- - interactive:
-
- Execute commands on all hosts in the cluster in parallel. This
- is useful if there are many hosts and you want to run the same
- command on all:
-
- tasks:
- - pexec:
- all:
- - grep FAIL /var/log/ceph/*
-
- Or if you want to run in parallel on all clients:
-
- tasks:
- - pexec:
- clients:
- - dd if=/dev/zero of={testdir}/mnt.* count=1024 bs=1024
-
- You can also ensure that parallel commands are synchronized with the
- special 'barrier' statement:
-
- tasks:
- - pexec:
- clients:
- - cd {testdir}/mnt.*
- - while true; do
- - barrier
- - dd if=/dev/zero of=./foo count=1024 bs=1024
- - done
-
- The above writes to the file foo on all clients over and over, but ensures that
- all clients perform each write command in sync. If one client takes longer to
- write, all the other clients will wait.
-
- """
- log.info('Executing custom commands...')
- assert isinstance(config, dict), "task pexec got invalid config"
-
- sudo = False
- if 'sudo' in config:
- sudo = config['sudo']
- del config['sudo']
-
- testdir = teuthology.get_testdir(ctx)
-
- remotes = list(_generate_remotes(ctx, config))
- count = len(remotes)
- barrier_queue = queue.Queue(count)
- barrier = event.Event()
-
- for remote in remotes:
- _init_barrier(barrier_queue, remote[0])
- with parallel() as p:
- for remote in remotes:
- p.spawn(_exec_host, barrier, barrier_queue, remote[0], sudo, testdir, remote[1])
diff --git a/teuthology/task/proc_thrasher.py b/teuthology/task/proc_thrasher.py
deleted file mode 100644
index 472b6ecbd..000000000
--- a/teuthology/task/proc_thrasher.py
+++ /dev/null
@@ -1,63 +0,0 @@
-import logging
-import gevent
-import random
-import time
-
-from ..orchestra import run
-
-log = logging.getLogger(__name__)
-
-class ProcThrasher:
- """ Kills and restarts some number of the specified process on the specified
- remote
- """
- def __init__(self, config, remote, *proc_args, **proc_kwargs):
- self.proc_kwargs = proc_kwargs
- self.proc_args = proc_args
- self.config = config
- self.greenlet = None
- self.logger = proc_kwargs.get("logger", log.getChild('proc_thrasher'))
- self.remote = remote
-
- # config:
- self.num_procs = self.config.get("num_procs", 5)
- self.rest_period = self.config.get("rest_period", 100) # seconds
- self.run_time = self.config.get("run_time", 1000) # seconds
-
- def log(self, msg):
- self.logger.info(msg)
-
- def start(self):
- if self.greenlet is not None:
- return
- self.greenlet = gevent.Greenlet(self.loop)
- self.greenlet.start()
-
- def join(self):
- self.greenlet.join()
-
- def loop(self):
- time_started = time.time()
- procs = []
- self.log("Starting")
- while time_started + self.run_time > time.time():
- if len(procs) > 0:
- self.log("Killing proc")
- proc = random.choice(procs)
- procs.remove(proc)
- proc.stdin.close()
- self.log("About to wait")
- run.wait([proc])
- self.log("Killed proc")
-
- while len(procs) < self.num_procs:
- self.log("Creating proc " + str(len(procs) + 1))
- self.log("args are " + str(self.proc_args) + " kwargs: " + str(self.proc_kwargs))
- procs.append(self.remote.run(
- *self.proc_args,
- ** self.proc_kwargs))
- self.log("About to sleep")
- time.sleep(self.rest_period)
- self.log("Just woke")
-
- run.wait(procs)
diff --git a/teuthology/task/sequential.py b/teuthology/task/sequential.py
deleted file mode 100644
index 4f74359c6..000000000
--- a/teuthology/task/sequential.py
+++ /dev/null
@@ -1,52 +0,0 @@
-import sys
-import logging
-import contextlib
-
-from teuthology import run_tasks
-from ..orchestra import run
-
-log = logging.getLogger(__name__)
-
-def task(ctx, config):
- """
- Sequentialize a group of tasks into one executable block
-
- example:
- - sequential:
- - tasktest:
- - tasktest:
-
- You can also reference the job from elsewhere:
-
- foo:
- tasktest:
- tasks:
- - sequential:
- - tasktest:
- - foo
- - tasktest:
-
- That is, if the entry is not a dict, we will look it up in the top-level
- config.
-
- Sequential task and Parallel tasks can be nested.
- """
- stack = []
- try:
- for entry in config:
- if not isinstance(entry, dict):
- entry = ctx.config.get(entry, {})
- ((taskname, confg),) = entry.iteritems()
- log.info('In sequential, running task %s...' % taskname)
- mgr = run_tasks.run_one_task(taskname, ctx=ctx, config=confg)
- if hasattr(mgr, '__enter__'):
- mgr.__enter__()
- stack.append(mgr)
- finally:
- try:
- exc_info = sys.exc_info()
- while stack:
- mgr = stack.pop()
- endr = mgr.__exit__(*exc_info)
- finally:
- del exc_info
diff --git a/teuthology/task/sleep.py b/teuthology/task/sleep.py
deleted file mode 100644
index 363634eaa..000000000
--- a/teuthology/task/sleep.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import logging
-import time
-
-from teuthology import misc as teuthology
-from ..orchestra import run
-
-log = logging.getLogger(__name__)
-
-def task(ctx, config):
- """
- Sleep for some number of seconds.
-
- Example::
-
-
- tasks:
- - install:
- - ceph:
- - sleep:
- duration: 10
- - interactive:
-
- """
- if not config:
- config = {}
- assert isinstance(config, dict)
- duration = int(config.get('duration', 5))
- log.info('Sleeping for %d', duration)
- time.sleep(duration)
diff --git a/teuthology/task/ssh_keys.py b/teuthology/task/ssh_keys.py
deleted file mode 100644
index 6cadd12fb..000000000
--- a/teuthology/task/ssh_keys.py
+++ /dev/null
@@ -1,163 +0,0 @@
-#!/usr/bin/python
-import contextlib
-import logging
-import paramiko
-import re
-
-from cStringIO import StringIO
-from teuthology import contextutil
-import teuthology.misc as misc
-from ..orchestra import run
-
-log = logging.getLogger(__name__)
-ssh_keys_user = 'ssh-keys-user'
-
-# generatees a public and private key
-def generate_keys():
- key = paramiko.RSAKey.generate(2048)
- privateString = StringIO()
- key.write_private_key(privateString)
- return key.get_base64(), privateString.getvalue()
-
-def particular_ssh_key_test(line_to_test, ssh_key):
- match = re.match('[\w-]+ {key} \S+@\S+'.format(key=re.escape(ssh_key)), line_to_test)
-
- if match:
- return False
- else:
- return True
-
-def ssh_keys_user_line_test(line_to_test, username ):
- match = re.match('[\w-]+ \S+ {username}@\S+'.format(username=username), line_to_test)
-
- if match:
- return False
- else:
- return True
-
-# deletes the keys and removes ~/.ssh/authorized_keys2 entries we added
-def cleanup_added_key(ctx):
- log.info('cleaning up keys added for testing')
-
- for remote in ctx.cluster.remotes:
- username, hostname = str(remote).split('@')
- if "" == username or "" == hostname:
- continue
- else:
- log.info(' cleaning up keys for user {user} on {host}'.format(host=hostname, user=username))
-
- misc.delete_file(remote, '/home/{user}/.ssh/id_rsa'.format(user=username))
- misc.delete_file(remote, '/home/{user}/.ssh/id_rsa.pub'.format(user=username))
- misc.delete_file(remote, '/home/{user}/.ssh/authorized_keys2'.format(user=username))
-
-@contextlib.contextmanager
-def tweak_ssh_config(ctx, config):
- run.wait(
- ctx.cluster.run(
- args=[
- 'echo',
- 'StrictHostKeyChecking no\n',
- run.Raw('>'),
- run.Raw('/home/ubuntu/.ssh/config'),
- run.Raw('&&'),
- 'echo',
- 'UserKnownHostsFile ',
- run.Raw('/dev/null'),
- run.Raw('>>'),
- run.Raw('/home/ubuntu/.ssh/config'),
- run.Raw('&&'),
- run.Raw('chmod 600 /home/ubuntu/.ssh/config'),
- ],
- wait=False,
- )
- )
-
- try:
- yield
-
- finally:
- run.wait(
- ctx.cluster.run(
- args=['rm',run.Raw('/home/ubuntu/.ssh/config')],
- wait=False
- ),
- )
-
-@contextlib.contextmanager
-def push_keys_to_host(ctx, config, public_key, private_key):
-
- log.info('generated public key {pub_key}'.format(pub_key=public_key))
-
- # add an entry for all hosts in ctx to auth_keys_data
- auth_keys_data = ''
-
- for inner_host in ctx.cluster.remotes.iterkeys():
- inner_username, inner_hostname = str(inner_host).split('@')
- # create a 'user@hostname' string using our fake hostname
- fake_hostname = '{user}@{host}'.format(user=ssh_keys_user,host=str(inner_hostname))
- auth_keys_data += '\nssh-rsa {pub_key} {user_host}\n'.format(pub_key=public_key,user_host=fake_hostname)
-
- # for each host in ctx, add keys for all other hosts
- for remote in ctx.cluster.remotes:
- username, hostname = str(remote).split('@')
- if "" == username or "" == hostname:
- continue
- else:
- log.info('pushing keys to {host} for {user}'.format(host=hostname, user=username))
-
- # adding a private key
- priv_key_file = '/home/{user}/.ssh/id_rsa'.format(user=username)
- priv_key_data = '{priv_key}'.format(priv_key=private_key)
- misc.delete_file(remote, priv_key_file, force=True)
- # Hadoop requires that .ssh/id_rsa have permissions of '500'
- misc.create_file(remote, priv_key_file, priv_key_data, str(500))
-
- # then a private key
- pub_key_file = '/home/{user}/.ssh/id_rsa.pub'.format(user=username)
- pub_key_data = 'ssh-rsa {pub_key} {user_host}'.format(pub_key=public_key,user_host=str(remote))
- misc.delete_file(remote, pub_key_file, force=True)
- misc.create_file(remote, pub_key_file, pub_key_data)
-
- # adding appropriate entries to the authorized_keys2 file for this host
- auth_keys_file = '/home/{user}/.ssh/authorized_keys2'.format(user=username)
-
- # now add the list of keys for hosts in ctx to ~/.ssh/authorized_keys2
- misc.create_file(remote, auth_keys_file, auth_keys_data, str(600))
-
- try:
- yield
-
- finally:
- # cleanup the keys
- log.info("Cleaning up SSH keys")
- cleanup_added_key(ctx)
-
-
-@contextlib.contextmanager
-def task(ctx, config):
- """
- Creates a set of RSA keys, distributes the same key pair
- to all hosts listed in ctx.cluster, and adds all hosts
- to all others authorized_keys list.
-
- During cleanup it will delete .ssh/id_rsa, .ssh/id_rsa.pub
- and remove the entries in .ssh/authorized_keys while leaving
- pre-existing entries in place.
- """
-
- if config is None:
- config = {}
- assert isinstance(config, dict), \
- "task hadoop only supports a dictionary for configuration"
-
- # this does not need to do cleanup and does not depend on
- # ctx, so I'm keeping it outside of the nested calls
- public_key_string, private_key_string = generate_keys()
-
- with contextutil.nested(
- lambda: tweak_ssh_config(ctx, config),
- lambda: push_keys_to_host(ctx, config, public_key_string, private_key_string),
- #lambda: tweak_ssh_config(ctx, config),
- ):
- yield
-
diff --git a/teuthology/task/swift.py b/teuthology/task/swift.py
deleted file mode 100644
index 8a0f34342..000000000
--- a/teuthology/task/swift.py
+++ /dev/null
@@ -1,235 +0,0 @@
-from cStringIO import StringIO
-from configobj import ConfigObj
-import base64
-import contextlib
-import logging
-import os
-
-from teuthology import misc as teuthology
-from teuthology import contextutil
-from ..orchestra import run
-from ..orchestra.connection import split_user
-
-log = logging.getLogger(__name__)
-
-
-@contextlib.contextmanager
-def download(ctx, config):
- testdir = teuthology.get_testdir(ctx)
- assert isinstance(config, list)
- log.info('Downloading swift...')
- for client in config:
- ctx.cluster.only(client).run(
- args=[
- 'git', 'clone',
- 'git://ceph.com/git/swift.git',
- '{tdir}/swift'.format(tdir=testdir),
- ],
- )
- try:
- yield
- finally:
- log.info('Removing swift...')
- testdir = teuthology.get_testdir(ctx)
- for client in config:
- ctx.cluster.only(client).run(
- args=[
- 'rm',
- '-rf',
- '{tdir}/swift'.format(tdir=testdir),
- ],
- )
-
-def _config_user(testswift_conf, account, user, suffix):
- testswift_conf['func_test'].setdefault('account{s}'.format(s=suffix), account);
- testswift_conf['func_test'].setdefault('username{s}'.format(s=suffix), user);
- testswift_conf['func_test'].setdefault('email{s}'.format(s=suffix), '{account}+test@test.test'.format(account=account))
- testswift_conf['func_test'].setdefault('display_name{s}'.format(s=suffix), 'Mr. {account} {user}'.format(account=account, user=user))
- testswift_conf['func_test'].setdefault('password{s}'.format(s=suffix), base64.b64encode(os.urandom(40)))
-
-@contextlib.contextmanager
-def create_users(ctx, config):
- assert isinstance(config, dict)
- log.info('Creating rgw users...')
- testdir = teuthology.get_testdir(ctx)
- users = {'': 'foo', '2': 'bar'}
- for client in config['clients']:
- testswift_conf = config['testswift_conf'][client]
- for suffix, user in users.iteritems():
- _config_user(testswift_conf, '{user}.{client}'.format(user=user, client=client), user, suffix)
- ctx.cluster.only(client).run(
- args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
- 'ceph-coverage',
- '{tdir}/archive/coverage'.format(tdir=testdir),
- 'radosgw-admin',
- '-n', client,
- 'user', 'create',
- '--subuser', '{account}:{user}'.format(account=testswift_conf['func_test']['account{s}'.format(s=suffix)],user=user),
- '--display-name', testswift_conf['func_test']['display_name{s}'.format(s=suffix)],
- '--secret', testswift_conf['func_test']['password{s}'.format(s=suffix)],
- '--email', testswift_conf['func_test']['email{s}'.format(s=suffix)],
- '--key-type', 'swift',
- ],
- )
- try:
- yield
- finally:
- for client in config['clients']:
- for user in users.itervalues():
- uid = '{user}.{client}'.format(user=user, client=client)
- ctx.cluster.only(client).run(
- args=[
- '{tdir}/adjust-ulimits'.format(tdir=testdir),
- 'ceph-coverage',
- '{tdir}/archive/coverage'.format(tdir=testdir),
- 'radosgw-admin',
- '-n', client,
- 'user', 'rm',
- '--uid', uid,
- '--purge-data',
- ],
- )
-
-@contextlib.contextmanager
-def configure(ctx, config):
- assert isinstance(config, dict)
- log.info('Configuring testswift...')
- testdir = teuthology.get_testdir(ctx)
- for client, properties in config['clients'].iteritems():
- log.info('client={c}'.format(c=client))
- log.info('config={c}'.format(c=config))
- testswift_conf = config['testswift_conf'][client]
- if properties is not None and 'rgw_server' in properties:
- host = None
- for target, roles in zip(ctx.config['targets'].iterkeys(), ctx.config['roles']):
- log.info('roles: ' + str(roles))
- log.info('target: ' + str(target))
- if properties['rgw_server'] in roles:
- _, host = split_user(target)
- assert host is not None, "Invalid client specified as the rgw_server"
- testswift_conf['func_test']['auth_host'] = host
- else:
- testswift_conf['func_test']['auth_host'] = 'localhost'
-
- log.info(client)
- (remote,) = ctx.cluster.only(client).remotes.keys()
- remote.run(
- args=[
- 'cd',
- '{tdir}/swift'.format(tdir=testdir),
- run.Raw('&&'),
- './bootstrap',
- ],
- )
- conf_fp = StringIO()
- testswift_conf.write(conf_fp)
- teuthology.write_file(
- remote=remote,
- path='{tdir}/archive/testswift.{client}.conf'.format(tdir=testdir, client=client),
- data=conf_fp.getvalue(),
- )
- yield
-
-
-@contextlib.contextmanager
-def run_tests(ctx, config):
- assert isinstance(config, dict)
- testdir = teuthology.get_testdir(ctx)
- for client, client_config in config.iteritems():
- args = [
- 'SWIFT_TEST_CONFIG_FILE={tdir}/archive/testswift.{client}.conf'.format(tdir=testdir, client=client),
- '{tdir}/swift/virtualenv/bin/nosetests'.format(tdir=testdir),
- '-w',
- '{tdir}/swift/test/functional'.format(tdir=testdir),
- '-v',
- '-a', '!fails_on_rgw',
- ]
- if client_config is not None and 'extra_args' in client_config:
- args.extend(client_config['extra_args'])
-
- ctx.cluster.only(client).run(
- args=args,
- )
- yield
-
-@contextlib.contextmanager
-def task(ctx, config):
- """
- Run the testswift suite against rgw.
-
- To run all tests on all clients::
-
- tasks:
- - ceph:
- - rgw:
- - testswift:
-
- To restrict testing to particular clients::
-
- tasks:
- - ceph:
- - rgw: [client.0]
- - testswift: [client.0]
-
- To run against a server on client.1::
-
- tasks:
- - ceph:
- - rgw: [client.1]
- - testswift:
- client.0:
- rgw_server: client.1
-
- To pass extra arguments to nose (e.g. to run a certain test)::
-
- tasks:
- - ceph:
- - rgw: [client.0]
- - testswift:
- client.0:
- extra_args: ['test.functional.tests:TestFileUTF8', '-m', 'testCopy']
- client.1:
- extra_args: ['--exclude', 'TestFile']
- """
- assert config is None or isinstance(config, list) \
- or isinstance(config, dict), \
- "task testswift only supports a list or dictionary for configuration"
- all_clients = ['client.{id}'.format(id=id_)
- for id_ in teuthology.all_roles_of_type(ctx.cluster, 'client')]
- if config is None:
- config = all_clients
- if isinstance(config, list):
- config = dict.fromkeys(config)
- clients = config.keys()
-
- log.info('clients={c}'.format(c=clients))
-
- testswift_conf = {}
- for client in clients:
- testswift_conf[client] = ConfigObj(
- indent_type='',
- infile={
- 'func_test':
- {
- 'auth_port' : 7280,
- 'auth_ssl' : 'no',
- 'auth_prefix' : '/auth/',
- },
- }
- )
-
- with contextutil.nested(
- lambda: download(ctx=ctx, config=clients),
- lambda: create_users(ctx=ctx, config=dict(
- clients=clients,
- testswift_conf=testswift_conf,
- )),
- lambda: configure(ctx=ctx, config=dict(
- clients=config,
- testswift_conf=testswift_conf,
- )),
- lambda: run_tests(ctx=ctx, config=config),
- ):
- pass
- yield
diff --git a/teuthology/task/tasktest.py b/teuthology/task/tasktest.py
deleted file mode 100644
index abfb5415e..000000000
--- a/teuthology/task/tasktest.py
+++ /dev/null
@@ -1,48 +0,0 @@
-import logging
-import contextlib
-import time
-
-from ..orchestra import run
-
-log = logging.getLogger(__name__)
-
-@contextlib.contextmanager
-def task(ctx, config):
- """
- Task that just displays information when it is create and when it is
- destroyed/cleaned up. This task was used to test parallel and
- sequential task options.
-
- example:
-
- tasks:
- - sequential:
- - tasktest:
- - id: 'foo'
- - tasktest:
- - id: 'bar'
- - delay:5
- - tasktest:
-
- The above yaml will sequentially start a test task named foo and a test
- task named bar. Bar will take 5 seconds to complete. After foo and bar
- have finished, an unidentified tasktest task will run.
- """
- try:
- delay = config.get('delay', 0)
- id = config.get('id', 'UNKNOWN')
- except AttributeError:
- delay = 0
- id = 'UNKNOWN'
- try:
- log.info('**************************************************')
- log.info('Started task test -- %s' % id)
- log.info('**************************************************')
- time.sleep(delay)
- yield
-
- finally:
- log.info('**************************************************')
- log.info('Task test is being cleaned up -- %s' % id)
- log.info('**************************************************')
-
diff --git a/teuthology/task/timer.py b/teuthology/task/timer.py
deleted file mode 100644
index 2a78bba0c..000000000
--- a/teuthology/task/timer.py
+++ /dev/null
@@ -1,43 +0,0 @@
-import logging
-import contextlib
-import datetime
-
-log = logging.getLogger(__name__)
-
-@contextlib.contextmanager
-def task(ctx, config):
- """
- Timer
-
- Measure the time that this set of tasks takes and save that value in the summary file.
- Config is a description of what we are timing.
-
- example:
-
- tasks:
- - ceph:
- - foo:
- - timer: "fsx run"
- - fsx:
-
- """
- start = datetime.datetime.now()
- log.debug("got here in timer")
- try:
- yield
- finally:
- nowinfo = datetime.datetime.now()
- elapsed = nowinfo - start
- datesaved = nowinfo.isoformat(' ')
- hourz, remainder = divmod(elapsed.seconds, 3600)
- minutez, secondz = divmod(remainder, 60)
- elapsedtime = "%02d:%02d:%02d.%06d" % (hourz,minutez,secondz, elapsed.microseconds)
- dateinfo = (datesaved, elapsedtime)
- if not 'timer' in ctx.summary:
- ctx.summary['timer'] = {config : [dateinfo]}
- else:
- if config in ctx.summary['timer']:
- ctx.summary['timer'][config].append(dateinfo)
- else:
- ctx.summary['timer'][config] = [dateinfo]
- log.info('Elapsed time for %s -- %s' % (config,elapsedtime))
diff --git a/teuthology/task/valgrind.supp b/teuthology/task/valgrind.supp
deleted file mode 100644
index c10c2d471..000000000
--- a/teuthology/task/valgrind.supp
+++ /dev/null
@@ -1,93 +0,0 @@
-{
- ceph global: deliberate onexit leak
- Memcheck:Leak
- ...
- fun:*set_flush_on_exit*
- ...
-}
-{
- ignore all leveldb leaks
- Memcheck:Leak
- ...
- fun:*leveldb*
- ...
-}
-{
- ignore libcurl leaks
- Memcheck:Leak
- ...
- fun:*curl_global_init
-}
-{
- ignore gnutls leaks
- Memcheck:Leak
- ...
- fun:gnutls_global_init
-}
-{
- ignore libfcgi leak; OS_LibShutdown has no callers!
- Memcheck:Leak
- ...
- fun:OS_LibInit
- fun:FCGX_Init
-}
-{
- strptime suckage
- Memcheck:Cond
- fun:__GI___strncasecmp_l
- fun:__strptime_internal
- ...
-}
-{
- strptime suckage 2
- Memcheck:Value8
- fun:__GI___strncasecmp_l
- fun:__strptime_internal
- ...
-}
-{
- strptime suckage 3
- Memcheck:Addr8
- fun:__GI___strncasecmp_l
- fun:__strptime_internal
- ...
-}
-{
- dl-lookup.c thing .. Invalid write of size 8
- Memcheck:Value8
- fun:do_lookup_x
- ...
- fun:_dl_lookup_symbol_x
- ...
-}
-{
- dl-lookup.c thing .. Invalid write of size 8
- Memcheck:Addr8
- fun:do_lookup_x
- ...
- fun:_dl_lookup_symbol_x
- ...
-}
-{
- weird thing from libc
- Memcheck:Leak
- ...
- fun:*sub_I_comparator*
- fun:__libc_csu_init
- ...
-}
-{
- libfuse leak
- Memcheck:Leak
- ...
- fun:fuse_parse_cmdline
- ...
-}
-{
- boost thread leaks on exit
- Memcheck:Leak
- ...
- fun:*boost*detail*
- ...
- fun:exit
-}
diff --git a/teuthology/test/test_get_distro.py b/teuthology/test/test_get_distro.py
deleted file mode 100644
index 3ade547e0..000000000
--- a/teuthology/test/test_get_distro.py
+++ /dev/null
@@ -1,29 +0,0 @@
-from .. import misc as teuthology
-
-class Mock: pass
-
-class TestGetDistro(object):
-
- def setup(self):
- self.fake_ctx = Mock()
- self.fake_ctx.config = {}
- self.fake_ctx.os_type = 'ubuntu'
-
- def test_default_distro(self):
- distro = teuthology.get_distro(self.fake_ctx)
- assert distro == 'ubuntu'
-
- def test_argument(self):
- self.fake_ctx.os_type = 'centos'
- distro = teuthology.get_distro(self.fake_ctx)
- assert distro == 'centos'
-
- def test_teuth_config(self):
- self.fake_ctx.config = {'os_type': 'fedora'}
- distro = teuthology.get_distro(self.fake_ctx)
- assert distro == 'fedora'
-
- def test_teuth_config_downburst(self):
- self.fake_ctx.config = {'downburst' : {'distro': 'sles'}}
- distro = teuthology.get_distro(self.fake_ctx)
- assert distro == 'sles'
diff --git a/teuthology/test/test_misc.py b/teuthology/test/test_misc.py
deleted file mode 100644
index 36031b03b..000000000
--- a/teuthology/test/test_misc.py
+++ /dev/null
@@ -1,29 +0,0 @@
-import argparse
-from ..orchestra import cluster
-
-from nose.tools import (
- eq_ as eq,
- assert_raises,
- )
-
-from .. import misc
-
-
-class FakeRemote(object):
- pass
-
-
-def test_get_clients_simple():
- ctx = argparse.Namespace()
- remote = FakeRemote()
- ctx.cluster = cluster.Cluster(
- remotes=[
- (remote, ['client.0', 'client.1'])
- ],
- )
- g = misc.get_clients(ctx=ctx, roles=['client.1'])
- got = next(g)
- eq(len(got), 2)
- eq(got[0], ('1'))
- assert got[1] is remote
- assert_raises(StopIteration, next, g)
diff --git a/teuthology/test/test_safepath.py b/teuthology/test/test_safepath.py
deleted file mode 100644
index 4f05f10d2..000000000
--- a/teuthology/test/test_safepath.py
+++ /dev/null
@@ -1,56 +0,0 @@
-from nose.tools import eq_ as eq
-
-from .. import safepath
-
-def test_simple():
- got = safepath.munge('foo')
- eq(got, 'foo')
-
-def test_empty():
- # really odd corner case
- got = safepath.munge('')
- eq(got, '_')
-
-def test_slash():
- got = safepath.munge('/')
- eq(got, '_')
-
-def test_slashslash():
- got = safepath.munge('//')
- eq(got, '_')
-
-def test_absolute():
- got = safepath.munge('/evil')
- eq(got, 'evil')
-
-def test_absolute_subdir():
- got = safepath.munge('/evil/here')
- eq(got, 'evil/here')
-
-def test_dot_leading():
- got = safepath.munge('./foo')
- eq(got, 'foo')
-
-def test_dot_middle():
- got = safepath.munge('evil/./foo')
- eq(got, 'evil/foo')
-
-def test_dot_trailing():
- got = safepath.munge('evil/foo/.')
- eq(got, 'evil/foo')
-
-def test_dotdot():
- got = safepath.munge('../evil/foo')
- eq(got, '_./evil/foo')
-
-def test_dotdot_subdir():
- got = safepath.munge('evil/../foo')
- eq(got, 'evil/_./foo')
-
-def test_hidden():
- got = safepath.munge('.evil')
- eq(got, '_evil')
-
-def test_hidden_subdir():
- got = safepath.munge('foo/.evil')
- eq(got, 'foo/_evil')
diff --git a/watch-suite.sh b/watch-suite.sh
deleted file mode 100755
index 03d73e3d4..000000000
--- a/watch-suite.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh
-
-watch "pwd ; echo \`teuthology-ls --archive-dir . | grep -c pass\` passes ; teuthology-ls --archive-dir . | grep -v pass"
-