summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/ceph-volume/drive-group.rst12
-rw-r--r--doc/ceph-volume/index.rst1
-rw-r--r--src/ceph-volume/ceph_volume/drive_group/__init__.py1
-rw-r--r--src/ceph-volume/ceph_volume/drive_group/main.py99
-rw-r--r--src/ceph-volume/ceph_volume/inventory/main.py6
-rw-r--r--src/ceph-volume/ceph_volume/main.py3
-rw-r--r--src/ceph-volume/setup.py4
-rw-r--r--src/python-common/.gitignore1
-rw-r--r--src/python-common/ceph/deployment/drive_group.py2
-rw-r--r--src/python-common/ceph/deployment/translate.py1
10 files changed, 128 insertions, 2 deletions
diff --git a/doc/ceph-volume/drive-group.rst b/doc/ceph-volume/drive-group.rst
new file mode 100644
index 00000000000..4b2b8ed9427
--- /dev/null
+++ b/doc/ceph-volume/drive-group.rst
@@ -0,0 +1,12 @@
+.. _ceph-volume-drive-group:
+
+``drive-group``
+===============
+The drive-group subcommand allows for passing :ref:'drivegroups' specifications
+straight to ceph-volume as json. ceph-volume will then attempt to deploy this
+drive groups via the batch subcommand.
+
+The specification can be passed via a file, string argument or on stdin.
+See the subcommand help for further details::
+
+ # ceph-volume drive-group --help
diff --git a/doc/ceph-volume/index.rst b/doc/ceph-volume/index.rst
index 36ce9cc8910..a9c18abb722 100644
--- a/doc/ceph-volume/index.rst
+++ b/doc/ceph-volume/index.rst
@@ -65,6 +65,7 @@ and ``ceph-disk`` is fully disabled. Encryption is fully supported.
intro
systemd
inventory
+ drive-group
lvm/index
lvm/activate
lvm/batch
diff --git a/src/ceph-volume/ceph_volume/drive_group/__init__.py b/src/ceph-volume/ceph_volume/drive_group/__init__.py
new file mode 100644
index 00000000000..14a0fd72183
--- /dev/null
+++ b/src/ceph-volume/ceph_volume/drive_group/__init__.py
@@ -0,0 +1 @@
+from .main import Deploy # noqa
diff --git a/src/ceph-volume/ceph_volume/drive_group/main.py b/src/ceph-volume/ceph_volume/drive_group/main.py
new file mode 100644
index 00000000000..684e89f366f
--- /dev/null
+++ b/src/ceph-volume/ceph_volume/drive_group/main.py
@@ -0,0 +1,99 @@
+# -*- coding: utf-8 -*-
+
+import argparse
+import json
+import logging
+import sys
+
+from ceph.deployment.drive_group import DriveGroupSpec
+from ceph.deployment.drive_selection.selector import DriveSelection
+from ceph.deployment.translate import to_ceph_volume
+from ceph.deployment.inventory import Device
+from ceph_volume.inventory import Inventory
+from ceph_volume.devices.lvm.batch import Batch
+
+logger = logging.getLogger(__name__)
+
+class Deploy(object):
+
+ help = '''
+ Deploy OSDs according to a drive groups specification.
+
+ The DriveGroup specification must be passed in json.
+ It can either be (preference in this order)
+ - in a file, path passed as a positional argument
+ - read from stdin, pass "-" as a positional argument
+ - a json string passed via the --spec argument
+
+ Either the path postional argument or --spec must be specifed.
+ '''
+
+ def __init__(self, argv):
+ logger.error(f'argv: {argv}')
+ self.argv = argv
+
+ def main(self):
+ parser = argparse.ArgumentParser(
+ prog='ceph-volume drive-group',
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ description=self.help,
+ )
+ parser.add_argument(
+ 'path',
+ nargs='?',
+ default=None,
+ help=('Path to file containing drive group spec or "-" to read from stdin'),
+ )
+ parser.add_argument(
+ '--spec',
+ default='',
+ nargs='?',
+ help=('drive-group json string')
+ )
+ parser.add_argument(
+ '--dry-run',
+ default=False,
+ action='store_true',
+ help=('dry run, only print the batch command that would be run'),
+ )
+ self.args = parser.parse_args(self.argv)
+ if self.args.path:
+ if self.args.path == "-":
+ commands = self.from_json(sys.stdin)
+ else:
+ with open(self.args.path, 'r') as f:
+ commands = self.from_json(f)
+ elif self.args.spec:
+ dg = json.loads(self.args.spec)
+ commands = self.get_dg_spec(dg)
+ else:
+ # either --spec or path arg must be specified
+ parser.print_help(sys.stderr)
+ sys.exit(0)
+ cmd = commands.run()
+ if not cmd:
+ logger.error('DriveGroup didn\'t produce any commands')
+ return
+ if self.args.dry_run:
+ logger.info('Returning ceph-volume command (--dry-run was passed): {}'.format(cmd))
+ print(cmd)
+ else:
+ logger.info('Running ceph-volume command: {}'.format(cmd))
+ batch_args = cmd.split(' ')[2:]
+ b = Batch(batch_args)
+ b.main()
+
+ def from_json(self, file_):
+ dg = {}
+ dg = json.load(file_)
+ return self.get_dg_spec(dg)
+
+ def get_dg_spec(self, dg):
+ dg_spec = DriveGroupSpec._from_json_impl(dg)
+ dg_spec.validate()
+ i = Inventory([])
+ i.main()
+ inventory = i.get_report()
+ devices = [Device.from_json(i) for i in inventory]
+ selection = DriveSelection(dg_spec, devices)
+ return to_ceph_volume(selection)
diff --git a/src/ceph-volume/ceph_volume/inventory/main.py b/src/ceph-volume/ceph_volume/inventory/main.py
index 1d821b602be..470be274f52 100644
--- a/src/ceph-volume/ceph_volume/inventory/main.py
+++ b/src/ceph-volume/ceph_volume/inventory/main.py
@@ -37,6 +37,12 @@ class Inventory(object):
else:
self.format_report(Devices())
+ def get_report(self):
+ if self.args.path:
+ return Device(self.args.path).json_report()
+ else:
+ return Devices().json_report()
+
def format_report(self, inventory):
if self.args.format == 'json':
print(json.dumps(inventory.json_report()))
diff --git a/src/ceph-volume/ceph_volume/main.py b/src/ceph-volume/ceph_volume/main.py
index 8c5801c5db5..461395ae5e3 100644
--- a/src/ceph-volume/ceph_volume/main.py
+++ b/src/ceph-volume/ceph_volume/main.py
@@ -6,7 +6,7 @@ import sys
import logging
from ceph_volume.decorators import catches
-from ceph_volume import log, devices, configuration, conf, exceptions, terminal, inventory
+from ceph_volume import log, devices, configuration, conf, exceptions, terminal, inventory, drive_group
class Volume(object):
@@ -29,6 +29,7 @@ Ceph Conf: {ceph_path}
'simple': devices.simple.Simple,
'raw': devices.raw.Raw,
'inventory': inventory.Inventory,
+ 'drive-group': drive_group.Deploy,
}
self.plugin_help = "No plugins found/loaded"
if argv is None:
diff --git a/src/ceph-volume/setup.py b/src/ceph-volume/setup.py
index 9bd48178cbf..a9fbdf8985b 100644
--- a/src/ceph-volume/setup.py
+++ b/src/ceph-volume/setup.py
@@ -1,4 +1,5 @@
from setuptools import setup, find_packages
+import os
setup(
@@ -13,6 +14,9 @@ setup(
keywords='ceph volume disk devices lvm',
url="https://github.com/ceph/ceph",
zip_safe = False,
+ install_requires='ceph',
+ dependency_links=[''.join(['file://', os.path.join(os.getcwd(), '../',
+ 'python-common#egg=ceph-1.0.0')])],
tests_require=[
'pytest >=2.1.3',
'tox',
diff --git a/src/python-common/.gitignore b/src/python-common/.gitignore
index 3e38dc9bf7d..c2de8195a1c 100644
--- a/src/python-common/.gitignore
+++ b/src/python-common/.gitignore
@@ -1,2 +1,3 @@
ceph.egg-info
build
+setup.cfg
diff --git a/src/python-common/ceph/deployment/drive_group.py b/src/python-common/ceph/deployment/drive_group.py
index a4307f6e73a..eed8fc2ef2b 100644
--- a/src/python-common/ceph/deployment/drive_group.py
+++ b/src/python-common/ceph/deployment/drive_group.py
@@ -191,7 +191,7 @@ class DriveGroupSpec(ServiceSpec):
#: Set (or override) the "bluestore_block_db_size" value, in bytes
self.block_db_size = block_db_size
- #: set journal_size is bytes
+ #: set journal_size in bytes
self.journal_size = journal_size
#: Number of osd daemons per "DATA" device.
diff --git a/src/python-common/ceph/deployment/translate.py b/src/python-common/ceph/deployment/translate.py
index 7eb0ec1d505..c2f030d2cb2 100644
--- a/src/python-common/ceph/deployment/translate.py
+++ b/src/python-common/ceph/deployment/translate.py
@@ -10,6 +10,7 @@ from ceph.deployment.drive_selection.selector import DriveSelection
logger = logging.getLogger(__name__)
+# TODO refactor this to a DriveSelection method
class to_ceph_volume(object):
def __init__(self,