Enable support for beast frontend
Introduce support for the beast web frontend for the Ceph RADOS Gateway which brings improvements to speed and scalability. Default behaviour is changed in that for Octopus and later (aside from some unsupported architectures) beast is enabled by default; for older releases civetweb is still used. This may be overridden using the 'http-frontend' configuration option which accepts either 'beast' or 'civetweb' as valid values. 'beast' is only supported with Ceph Mimic or later. Closes-Bug: 1865396 Change-Id: Ib73e58e21219eca611cd4293da69bf80040f5803
This commit is contained in:
parent
eccbd7e772
commit
c634aba6fd
@ -509,3 +509,10 @@ options:
|
||||
NOTE: X-Versions-Location is the only versioning-related header that
|
||||
radosgw interprets. X-History-Location, supported by native OpenStack
|
||||
Swift, is currently not supported by radosgw.
|
||||
http-frontend:
|
||||
type: string
|
||||
default:
|
||||
description: |
|
||||
Frontend HTTP engine to use for the Ceph RADOS Gateway; For Octopus and
|
||||
later this defaults to 'beast' and for older releases (and on architectures
|
||||
where beast is not supported) 'civetweb'.
|
||||
|
@ -23,10 +23,14 @@ from charmhelpers.contrib.hahelpers.cluster import (
|
||||
determine_api_port,
|
||||
determine_apache_port,
|
||||
)
|
||||
from charmhelpers.core.host import cmp_pkgrevno
|
||||
from charmhelpers.core.host import (
|
||||
cmp_pkgrevno,
|
||||
arch,
|
||||
)
|
||||
from charmhelpers.core.hookenv import (
|
||||
DEBUG,
|
||||
WARNING,
|
||||
ERROR,
|
||||
config,
|
||||
log,
|
||||
related_units,
|
||||
@ -44,6 +48,12 @@ from charmhelpers.contrib.storage.linux.ceph import CephConfContext
|
||||
import utils
|
||||
|
||||
|
||||
BEAST_FRONTEND = 'beast'
|
||||
CIVETWEB_FRONTEND = 'civetweb'
|
||||
SUPPORTED_FRONTENDS = (BEAST_FRONTEND, CIVETWEB_FRONTEND)
|
||||
UNSUPPORTED_BEAST_ARCHS = ('s390x', 'riscv64')
|
||||
|
||||
|
||||
class ApacheSSLContext(context.ApacheSSLContext):
|
||||
interfaces = ['https']
|
||||
service_namespace = 'ceph-radosgw'
|
||||
@ -142,6 +152,55 @@ def ensure_host_resolvable_v6(hostname):
|
||||
shutil.rmtree(dtmp)
|
||||
|
||||
|
||||
def resolve_http_frontend():
|
||||
"""Automatically determine the HTTP frontend configuration
|
||||
|
||||
Determines the best HTTP frontend configuration based
|
||||
on the Ceph release in use and the architecture of the
|
||||
machine being used.
|
||||
|
||||
:returns http frontend configuration to use.
|
||||
:rtype: str
|
||||
"""
|
||||
octopus_or_later = cmp_pkgrevno('radosgw', '15.2.0') >= 0
|
||||
pacific_or_later = cmp_pkgrevno('radosgw', '16.2.0') >= 0
|
||||
if octopus_or_later:
|
||||
# Pacific or later supports beast on all architectures
|
||||
# but octopus does not support s390x or riscv64
|
||||
if not pacific_or_later and arch() in UNSUPPORTED_BEAST_ARCHS:
|
||||
return CIVETWEB_FRONTEND
|
||||
else:
|
||||
return BEAST_FRONTEND
|
||||
return CIVETWEB_FRONTEND
|
||||
|
||||
|
||||
def validate_http_frontend(frontend_config):
|
||||
"""Validate HTTP frontend configuration
|
||||
|
||||
:param frontend_config: user provided config value
|
||||
:type: str
|
||||
:raises: ValueError if the provided config is not valid
|
||||
"""
|
||||
mimic_or_later = cmp_pkgrevno('radosgw', '13.2.0') >= 0
|
||||
pacific_or_later = cmp_pkgrevno('radosgw', '16.2.0') >= 0
|
||||
if frontend_config not in SUPPORTED_FRONTENDS:
|
||||
e = ('Please provide either civetweb or beast for '
|
||||
'http-frontend configuration')
|
||||
log(e, level=ERROR)
|
||||
raise ValueError(e)
|
||||
if frontend_config == BEAST_FRONTEND:
|
||||
if not mimic_or_later:
|
||||
e = ('Use of the beast HTTP frontend requires Ceph '
|
||||
'mimic or later.')
|
||||
log(e, level=ERROR)
|
||||
raise ValueError(e)
|
||||
if not pacific_or_later and arch() in UNSUPPORTED_BEAST_ARCHS:
|
||||
e = ('Use of the beast HTTP frontend on {} requires Ceph '
|
||||
'pacific or later.'.format(arch()))
|
||||
log(e, level=ERROR)
|
||||
raise ValueError(e)
|
||||
|
||||
|
||||
class MonContext(context.CephContext):
|
||||
interfaces = ['mon']
|
||||
|
||||
@ -191,6 +250,12 @@ class MonContext(context.CephContext):
|
||||
if config('prefer-ipv6'):
|
||||
port = "[::]:%s" % (port)
|
||||
|
||||
http_frontend = config('http-frontend')
|
||||
if not http_frontend:
|
||||
http_frontend = resolve_http_frontend()
|
||||
else:
|
||||
validate_http_frontend(http_frontend)
|
||||
|
||||
mon_hosts.sort()
|
||||
ctxt = {
|
||||
'auth_supported': auth,
|
||||
@ -210,6 +275,7 @@ class MonContext(context.CephContext):
|
||||
'unit_public_ip': unit_public_ip(),
|
||||
'fsid': fsid,
|
||||
'rgw_swift_versioning': config('rgw-swift-versioning-enabled'),
|
||||
'frontend': http_frontend,
|
||||
}
|
||||
|
||||
# NOTE(dosaboy): these sections must correspond to what is supported in
|
||||
|
@ -42,6 +42,7 @@ from charmhelpers.core.hookenv import (
|
||||
is_leader,
|
||||
leader_set,
|
||||
leader_get,
|
||||
WORKLOAD_STATES,
|
||||
)
|
||||
from charmhelpers.fetch import (
|
||||
apt_update,
|
||||
@ -747,4 +748,8 @@ if __name__ == '__main__':
|
||||
hooks.execute(sys.argv)
|
||||
except UnregisteredHookError as e:
|
||||
log('Unknown hook {} - skipping.'.format(e))
|
||||
assess_status(CONFIGS)
|
||||
except ValueError as e:
|
||||
# Handle any invalid configuration values
|
||||
status_set(WORKLOAD_STATES.BLOCKED, str(e))
|
||||
else:
|
||||
assess_status(CONFIGS)
|
||||
|
@ -39,7 +39,7 @@ rgw_zone = {{ rgw_zone }}
|
||||
{% endif %}
|
||||
|
||||
rgw init timeout = 1200
|
||||
rgw frontends = civetweb port={{ port }}
|
||||
rgw frontends = {{ frontend }} port={{ port }}
|
||||
{% if auth_type == 'keystone' %}
|
||||
rgw keystone url = {{ auth_protocol }}://{{ auth_host }}:{{ auth_port }}/
|
||||
rgw keystone admin user = {{ admin_user }}
|
||||
|
@ -17,6 +17,7 @@ from mock import patch
|
||||
import ceph_radosgw_context as context
|
||||
import charmhelpers
|
||||
import charmhelpers.contrib.storage.linux.ceph as ceph
|
||||
import charmhelpers.fetch as fetch
|
||||
|
||||
from test_utils import CharmTestCase
|
||||
|
||||
@ -27,6 +28,7 @@ TO_PATCH = [
|
||||
'relation_ids',
|
||||
'related_units',
|
||||
'cmp_pkgrevno',
|
||||
'arch',
|
||||
'socket',
|
||||
'unit_public_ip',
|
||||
'determine_api_port',
|
||||
@ -42,6 +44,7 @@ class HAProxyContextTests(CharmTestCase):
|
||||
self.relation_get.side_effect = self.test_relation.get
|
||||
self.config.side_effect = self.test_config.get
|
||||
self.cmp_pkgrevno.return_value = 1
|
||||
self.arch.return_value = 'amd64'
|
||||
|
||||
@patch('charmhelpers.contrib.openstack.context.get_relation_ip')
|
||||
@patch('charmhelpers.contrib.openstack.context.mkdir')
|
||||
@ -356,7 +359,8 @@ class MonContextTest(CharmTestCase):
|
||||
super(MonContextTest, self).setUp(context, TO_PATCH)
|
||||
self.config.side_effect = self.test_config.get
|
||||
self.unit_public_ip.return_value = '10.255.255.255'
|
||||
self.cmp_pkgrevno.return_value = 1
|
||||
self.cmp_pkgrevno.side_effect = lambda *args: 1
|
||||
self.arch.return_value = 'amd64'
|
||||
|
||||
@patch.object(ceph, 'config', lambda *args:
|
||||
'{"client.radosgw.gateway": {"rgw init timeout": 60}}')
|
||||
@ -395,6 +399,7 @@ class MonContextTest(CharmTestCase):
|
||||
'rgw_zone': 'default',
|
||||
'fsid': 'testfsid',
|
||||
'rgw_swift_versioning': False,
|
||||
'frontend': 'beast',
|
||||
}
|
||||
self.assertEqual(expect, mon_ctxt())
|
||||
self.assertFalse(mock_ensure_rsv_v6.called)
|
||||
@ -444,6 +449,7 @@ class MonContextTest(CharmTestCase):
|
||||
'rgw_zone': 'default',
|
||||
'fsid': 'testfsid',
|
||||
'rgw_swift_versioning': False,
|
||||
'frontend': 'beast',
|
||||
}
|
||||
self.assertEqual(expect, mon_ctxt())
|
||||
self.assertFalse(mock_ensure_rsv_v6.called)
|
||||
@ -502,6 +508,7 @@ class MonContextTest(CharmTestCase):
|
||||
'rgw_zone': 'default',
|
||||
'fsid': 'testfsid',
|
||||
'rgw_swift_versioning': False,
|
||||
'frontend': 'beast',
|
||||
}
|
||||
self.assertEqual(expect, mon_ctxt())
|
||||
|
||||
@ -542,9 +549,68 @@ class MonContextTest(CharmTestCase):
|
||||
'rgw_zone': 'default',
|
||||
'fsid': 'testfsid',
|
||||
'rgw_swift_versioning': False,
|
||||
'frontend': 'beast',
|
||||
}
|
||||
self.assertEqual(expect, mon_ctxt())
|
||||
|
||||
def test_resolve_http_frontend(self):
|
||||
_test_version = '12.2.0'
|
||||
|
||||
def _compare_version(package, version):
|
||||
return fetch.apt_pkg.version_compare(
|
||||
_test_version, version
|
||||
)
|
||||
|
||||
# Older releases, default and invalid configuration
|
||||
self.cmp_pkgrevno.side_effect = _compare_version
|
||||
self.assertEqual('civetweb', context.resolve_http_frontend())
|
||||
|
||||
# Default for Octopus but not Pacific
|
||||
_test_version = '15.2.0'
|
||||
self.assertEqual('beast', context.resolve_http_frontend())
|
||||
|
||||
self.arch.return_value = 's390x'
|
||||
self.assertEqual('civetweb', context.resolve_http_frontend())
|
||||
|
||||
# Default for Pacific and later
|
||||
_test_version = '16.2.0'
|
||||
self.assertEqual('beast', context.resolve_http_frontend())
|
||||
self.arch.return_value = 'amd64'
|
||||
self.assertEqual('beast', context.resolve_http_frontend())
|
||||
|
||||
def test_validate_http_frontend(self):
|
||||
_test_version = '12.2.0'
|
||||
|
||||
def _compare_version(package, version):
|
||||
return fetch.apt_pkg.version_compare(
|
||||
_test_version, version
|
||||
)
|
||||
|
||||
self.cmp_pkgrevno.side_effect = _compare_version
|
||||
|
||||
# Invalid configuration option
|
||||
with self.assertRaises(ValueError):
|
||||
context.validate_http_frontend('foobar')
|
||||
|
||||
# beast config but ceph pre mimic
|
||||
with self.assertRaises(ValueError):
|
||||
context.validate_http_frontend('beast')
|
||||
|
||||
# Mimic with valid configuration
|
||||
_test_version = '13.2.0'
|
||||
context.validate_http_frontend('beast')
|
||||
context.validate_http_frontend('civetweb')
|
||||
|
||||
# beast config on unsupported s390x/octopus
|
||||
_test_version = '15.2.0'
|
||||
self.arch.return_value = 's390x'
|
||||
with self.assertRaises(ValueError):
|
||||
context.validate_http_frontend('beast')
|
||||
|
||||
# beast config on s390x/pacific
|
||||
_test_version = '16.2.0'
|
||||
context.validate_http_frontend('beast')
|
||||
|
||||
|
||||
class ApacheContextTest(CharmTestCase):
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user