charm-ceph-radosgw/hooks/ceph.py
James Page 2858f1b02d Switch to using systemd units for radosgw
Switch to using systemd configurations to manage radosgw instances;
the radosgw init script is obsolete and will be removed at some
point in time, and the newer style of managing radosgw daemons is
inline with current best-practice.

This changeset also changes the way cephx keys are issues; before
all rgw instances shared a key, now a key is issued per host.

The key is named 'rgw.`hostname`' to identify the application
and host using the key.

Existing deployments using the radosgw init script will be switched
to use the new systemd named units; this occurs once the new key
for the unit has been presented by the ceph-mon cluster over the
mon relation. A small period of outage will occur as the radosgw
init based daemon is stopped and disabled prior to the start of
the new systemd based radosgw unit.

This commit also includes a resync for charmhelpers to pickup
support for '@' in NRPE service check names.

Change-Id: Ic0d634e619185931633712cb3e3685051a28749d
Depends-On: I289b75a2935184817b424c5eceead16235c3f53b
Closes-Bug: 1808140
2019-01-24 13:04:52 +00:00

154 lines
4.8 KiB
Python

#
# Copyright 2016 Canonical Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import os
import subprocess
from utils import get_pkg_version
from charmhelpers.core.hookenv import (
config,
)
from charmhelpers.core.host import (
mkdir
)
from charmhelpers.contrib.storage.linux.ceph import (
CephBrokerRq,
)
CEPH_DIR = '/etc/ceph'
CEPH_RADOSGW_DIR = '/var/lib/ceph/radosgw'
_radosgw_keyring = "keyring.rados.gateway"
def import_radosgw_key(key, name=None):
if name:
keyring_path = os.path.join(CEPH_RADOSGW_DIR,
'ceph-{}'.format(name),
'keyring')
owner = group = 'ceph'
else:
keyring_path = os.path.join(CEPH_DIR, _radosgw_keyring)
owner = group = 'root'
if not os.path.exists(keyring_path):
mkdir(path=os.path.dirname(keyring_path),
owner=owner, group=group, perms=0o750)
cmd = [
'ceph-authtool',
keyring_path,
'--create-keyring',
'--name=client.{}'.format(
name or 'radosgw.gateway'
),
'--add-key={}'.format(key)
]
subprocess.check_call(cmd)
cmd = [
'chown',
'{}:{}'.format(owner, group),
keyring_path
]
subprocess.check_call(cmd)
return True
return False
def get_create_rgw_pools_rq(prefix=None):
"""Pre-create RGW pools so that they have the correct settings.
If a prefix is provided it will be prepended to each pool name.
When RGW creates its own pools it will create them with non-optimal
settings (LP: #1476749).
NOTE: see http://docs.ceph.com/docs/master/radosgw/config-ref/#pools and
http://docs.ceph.com/docs/master/radosgw/config/#create-pools for
list of supported/required pools.
"""
def _add_light_pool(rq, pool, pg_num, prefix=None):
# Per the Ceph PG Calculator, all of the lightweight pools get 0.10%
# of the data by default and only the .rgw.buckets.* get higher values
weights = {
'.rgw.buckets.index': 1.00,
'.rgw.buckets.extra': 1.00
}
w = weights.get(pool, 0.10)
if prefix:
pool = "{prefix}{pool}".format(prefix=prefix, pool=pool)
if pg_num > 0:
rq.add_op_create_pool(name=pool, replica_count=replicas,
pg_num=pg_num, group='objects')
else:
rq.add_op_create_pool(name=pool, replica_count=replicas,
weight=w, group='objects')
from apt import apt_pkg
apt_pkg.init()
rq = CephBrokerRq()
replicas = config('ceph-osd-replication-count')
# Jewel and above automatically always prefix pool names with zone when
# creating them (see LP: 1573549).
if prefix is None:
vc = apt_pkg.version_compare(get_pkg_version('radosgw'), '10.0.0')
if vc >= 0:
prefix = 'default'
else:
prefix = ''
# Buckets likely to contain the most data and therefore requiring the most
# PGs
heavy = ['.rgw.buckets']
bucket_weight = config('rgw-buckets-pool-weight')
for pool in heavy:
pool = "{prefix}{pool}".format(prefix=prefix, pool=pool)
rq.add_op_create_pool(name=pool, replica_count=replicas,
weight=bucket_weight, group='objects')
# NOTE: we want these pools to have a smaller pg_num/pgp_num than the
# others since they are not expected to contain as much data
light = ['.rgw',
'.rgw.root',
'.rgw.control',
'.rgw.gc',
'.rgw.buckets.index',
'.rgw.buckets.extra',
'.log',
'.intent-log',
'.usage',
'.users',
'.users.email',
'.users.swift',
'.users.uid']
pg_num = config('rgw-lightweight-pool-pg-num')
for pool in light:
_add_light_pool(rq, pool, pg_num, prefix)
if prefix:
light_unprefixed = ['.rgw.root']
for pool in light_unprefixed:
_add_light_pool(rq, pool, pg_num)
if config('restrict-ceph-pools'):
rq.add_op_request_access_to_group(name="objects",
permission='rwx',
key_name='radosgw.gateway')
return rq