diff options
-rw-r--r-- | doc/ceph-volume/drive-group.rst | 12 | ||||
-rw-r--r-- | doc/ceph-volume/index.rst | 1 | ||||
-rw-r--r-- | src/ceph-volume/ceph_volume/drive_group/__init__.py | 1 | ||||
-rw-r--r-- | src/ceph-volume/ceph_volume/drive_group/main.py | 99 | ||||
-rw-r--r-- | src/ceph-volume/ceph_volume/inventory/main.py | 6 | ||||
-rw-r--r-- | src/ceph-volume/ceph_volume/main.py | 3 | ||||
-rw-r--r-- | src/ceph-volume/setup.py | 4 | ||||
-rw-r--r-- | src/python-common/.gitignore | 1 | ||||
-rw-r--r-- | src/python-common/ceph/deployment/drive_group.py | 2 | ||||
-rw-r--r-- | src/python-common/ceph/deployment/translate.py | 1 |
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, |