Build standalone ceph_spec with Ansible

Instead of calling the ceph_spec library directly from
the python-tripleoclient call an ansible wrapper to it
instead so that the library does not need to live in
tripleo-common and bug 1961325 can be avoided.

Closes-Bug: 1961325
Depends-On: I90f9e16476f5a986a87c9e678e455846b1d02bf9
Change-Id: I7514c95b5c3c24a82e8703556d4205b272270511
This commit is contained in:
John Fulton 2022-02-25 19:10:34 +00:00
parent 1d9c463947
commit ec411b9329
3 changed files with 32 additions and 147 deletions

View File

@ -18,7 +18,6 @@ import ansible_runner
import argparse import argparse
import datetime import datetime
import fixtures import fixtures
import io
import logging import logging
import openstack import openstack
import os import os
@ -2732,67 +2731,6 @@ class TestGetHostsFromCephSpec(TestCase):
self.assertEqual(expected, hosts) self.assertEqual(expected, hosts)
class TestCephSpecStandalone(TestCase):
def test_ceph_spec_standalone(self):
hostname = utils.get_hostname()
expected = []
expected.append(yaml.safe_load('''
addr: 192.168.122.252
hostname: %s
labels:
- mon
- _admin
- osd
- mgr
service_type: host
''' % hostname))
expected.append(yaml.safe_load('''
placement:
hosts:
- %s
service_id: mon
service_name: mon
service_type: mon
''' % hostname))
expected.append(yaml.safe_load('''
placement:
hosts:
- %s
service_id: mgr
service_name: mgr
service_type: mgr
''' % hostname))
expected.append(yaml.safe_load('''
data_devices:
all: true
placement:
hosts:
- %s
service_id: default_drive_group
service_name: osd.default_drive_group
service_type: osd
''' % hostname))
expected_spec = tempfile.NamedTemporaryFile()
for spec in expected:
with open(expected_spec.name, 'a') as f:
f.write('---\n')
f.write(yaml.safe_dump(spec))
my_spec = tempfile.NamedTemporaryFile()
utils.ceph_spec_standalone(my_spec.name,
mon_ip='192.168.122.252')
self.assertCountEqual(
list(io.open(expected_spec.name)),
list(io.open(my_spec.name)))
expected_spec.close()
my_spec.close()
class TestProcessCephDaemons(TestCase): class TestProcessCephDaemons(TestCase):
def test_process_ceph_daemons(self): def test_process_ceph_daemons(self):

View File

@ -65,7 +65,6 @@ from tenacity.wait import wait_fixed
from tripleo_common.image import image_uploader from tripleo_common.image import image_uploader
from tripleo_common.image import kolla_builder from tripleo_common.image import kolla_builder
from tripleo_common.utils import ceph_spec
from tripleo_common.utils import plan as plan_utils from tripleo_common.utils import plan as plan_utils
from tripleo_common.utils import heat as tc_heat_utils from tripleo_common.utils import heat as tc_heat_utils
from tripleo_common.utils import stack as stack_utils from tripleo_common.utils import stack as stack_utils
@ -3410,60 +3409,6 @@ def get_host_groups_from_ceph_spec(ceph_spec_path, prefix='',
return hosts return hosts
def ceph_spec_standalone(ceph_spec_path, mon_ip, osd_spec_path=None):
"""Write ceph_spec_path file for a standalone ceph host
:param ceph_spec_path: the path to a ceph_spec.yaml file
:param mon_ip: the ip address of the ceph monitor
:param (osd_spec_path): path to an OSD spec file
:return None (writes file)
"""
specs = []
labels = ['osd', '_admin', 'mon', 'mgr']
host = get_hostname()
if osd_spec_path:
with open(os.path.abspath(osd_spec_path), 'r') as f:
try:
osd_spec = yaml.safe_load(f)
except yaml.YAMLError as exc:
raise oscexc.CommandError(
"Unable to parse '%s': %s"
% (os.path.abspath(osd_spec_path), exc))
else:
osd_spec = {
'data_devices': {
'all': True
}
}
placement_pattern = ''
spec_dict = {}
# create host spec
spec = ceph_spec.CephHostSpec('host', mon_ip, host, labels)
specs.append(spec.make_daemon_spec())
# add mon and mgr daemon specs
for svc in ['mon', 'mgr']:
d = ceph_spec.CephDaemonSpec(svc, svc, svc, [host],
placement_pattern, None,
spec_dict, labels)
specs.append(d.make_daemon_spec())
# add osd daemon spec
d = ceph_spec.CephDaemonSpec('osd', 'default_drive_group',
'osd.default_drive_group',
[host], placement_pattern,
None, spec_dict, labels,
**osd_spec)
specs.append(d.make_daemon_spec())
# render
open(ceph_spec_path, 'w').close() # reset file
for spec in specs:
with open(ceph_spec_path, 'a') as f:
f.write('---\n')
f.write(yaml.dump(spec))
def standalone_ceph_inventory(working_dir): def standalone_ceph_inventory(working_dir):
"""return an ansible inventory for deployed ceph standalone """return an ansible inventory for deployed ceph standalone
:param working_dir: directory where inventory should be written :param working_dir: directory where inventory should be written

View File

@ -899,22 +899,24 @@ class OvercloudCephSpec(command.Command):
else: else:
overwrite = True overwrite = True
if not parsed_args.standalone: if not parsed_args.working_dir:
if not parsed_args.working_dir: working_dir = oooutils.get_default_working_dir(
working_dir = oooutils.get_default_working_dir( parsed_args.stack)
parsed_args.stack) else:
else: working_dir = os.path.abspath(parsed_args.working_dir)
working_dir = os.path.abspath(parsed_args.working_dir) oooutils.makedirs(working_dir)
oooutils.makedirs(working_dir)
if parsed_args.standalone:
inventory = oooutils.standalone_ceph_inventory(working_dir)
else:
inventory = os.path.join(working_dir, inventory = os.path.join(working_dir,
constants.TRIPLEO_STATIC_INVENTORY) constants.TRIPLEO_STATIC_INVENTORY)
if not os.path.exists(inventory): if not os.path.exists(inventory):
raise oscexc.CommandError( raise oscexc.CommandError(
"Inventory file not found in working directory: " "Inventory file not found in working directory: "
"%s. It should have been created by " "%s. It should have been created by "
"'openstack overcloud node provision'." "'openstack overcloud node provision'."
% inventory) % inventory)
# mandatory extra_vars are now set, add others conditionally # mandatory extra_vars are now set, add others conditionally
extra_vars = { extra_vars = {
@ -979,21 +981,21 @@ class OvercloudCephSpec(command.Command):
extra_vars['crush_hierarchy_path'] = \ extra_vars['crush_hierarchy_path'] = \
os.path.abspath(parsed_args.crush_hierarchy) os.path.abspath(parsed_args.crush_hierarchy)
# Call the playbook to create the spec from baremetal and roles files if parsed_args.standalone:
if not parsed_args.standalone: spec_playbook = 'cli-standalone-ceph-spec.yaml'
with oooutils.TempDirs() as tmp: tags = ''
oooutils.run_ansible_playbook(
playbook='cli-deployed-ceph.yaml',
inventory=inventory,
workdir=tmp,
playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
verbosity=oooutils.playbook_verbosity(self=self),
extra_vars=extra_vars,
reproduce_command=False,
tags='ceph_spec',
)
else: else:
# Create the spec directly spec_playbook = 'cli-deployed-ceph.yaml'
oooutils.ceph_spec_standalone(ceph_spec_path=output_path, tags = 'ceph_spec'
mon_ip=parsed_args.mon_ip,
osd_spec_path=parsed_args.osd_spec) with oooutils.TempDirs() as tmp:
oooutils.run_ansible_playbook(
playbook=spec_playbook,
inventory=inventory,
workdir=tmp,
playbook_dir=constants.ANSIBLE_TRIPLEO_PLAYBOOKS,
verbosity=oooutils.playbook_verbosity(self=self),
extra_vars=extra_vars,
reproduce_command=False,
tags=tags,
)