def mon_relation(): if leader_get('monitor-secret') is None: log('still waiting for leader to setup keys') status_set('waiting', 'Waiting for leader to setup keys') return emit_cephconf() moncount = int(config('monitor-count')) if len(get_mon_hosts()) >= moncount: if ceph.is_bootstrapped(): # The ceph-mon unit chosen for handling broker requests is based on # internal Ceph MON leadership and not Juju leadership. To update # the rbd-mirror relation on all ceph-mon units after pool creation # the unit handling the broker request will update a nonce on the # mon relation. notify_rbd_mirrors() else: status_set('maintenance', 'Bootstrapping MON cluster') # the following call raises an exception # if it can't add the keyring try: ceph.bootstrap_monitor_cluster(leader_get('monitor-secret')) except FileNotFoundError as e: # NOQA -- PEP8 is still PY2 log("Couldn't bootstrap the monitor yet: {}".format(str(e))) exit(0) ceph.wait_for_bootstrap() ceph.wait_for_quorum() ceph.create_keyrings() if cmp_pkgrevno('ceph', '12.0.0') >= 0: status_set('maintenance', 'Bootstrapping Ceph MGR') ceph.bootstrap_manager() if ceph.monitor_key_exists('admin', 'autotune'): autotune = ceph.monitor_key_get('admin', 'autotune') else: ceph.wait_for_manager() autotune = config('pg-autotune') if (cmp_pkgrevno('ceph', '14.2.0') >= 0 and (autotune == 'true' or autotune == 'auto')): ceph.monitor_key_set('admin', 'autotune', 'true') else: ceph.monitor_key_set('admin', 'autotune', 'false') if ceph.monitor_key_get('admin', 'autotune') == 'true': try: mgr_enable_module('pg_autoscaler') except subprocess.CalledProcessError: log( "Failed to initialize autoscaler, it must be " "initialized on the last monitor", level='info') # If we can and want to if is_leader() and config('customize-failure-domain'): # But only if the environment supports it if os.environ.get('JUJU_AVAILABILITY_ZONE'): cmds = [ "ceph osd getcrushmap -o /tmp/crush.map", "crushtool -d /tmp/crush.map| " "sed 's/step chooseleaf firstn 0 type host/step " "chooseleaf firstn 0 type rack/' > " "/tmp/crush.decompiled", "crushtool -c /tmp/crush.decompiled -o /tmp/crush.map", "crushtool -i /tmp/crush.map --test", "ceph osd setcrushmap -i /tmp/crush.map" ] for cmd in cmds: try: subprocess.check_call(cmd, shell=True) except subprocess.CalledProcessError as e: log("Failed to modify crush map:", level='error') log("Cmd: {}".format(cmd), level='error') log("Error: {}".format(e.output), level='error') break else: log("Your Juju environment doesn't" "have support for Availability Zones") notify_osds() notify_radosgws() notify_client() notify_rbd_mirrors() notify_prometheus() else: log('Not enough mons ({}), punting.'.format(len(get_mon_hosts())))
def config_changed(): # Get the cfg object so we can see if the no-bootstrap value has changed # and triggered this hook invocation cfg = config() if config('prefer-ipv6'): assert_charm_supports_ipv6() check_for_upgrade() log('Monitor hosts are ' + repr(get_mon_hosts())) sysctl_dict = config('sysctl') if sysctl_dict: create_sysctl(sysctl_dict, '/etc/sysctl.d/50-ceph-charm.conf') if relations_of_type('nrpe-external-master'): update_nrpe_config() if config('enable-dashboard') and cmp_pkgrevno('ceph', '14.2.0') >= 0: apt_install(packages=filter_installed_packages(['ceph-mgr-dashboard'])) if is_leader(): if not config('no-bootstrap'): if not leader_get('fsid') or not leader_get('monitor-secret'): if config('fsid'): fsid = config('fsid') else: fsid = "{}".format(uuid.uuid1()) if config('monitor-secret'): mon_secret = config('monitor-secret') else: mon_secret = "{}".format(ceph.generate_monitor_secret()) opts = { 'fsid': fsid, 'monitor-secret': mon_secret, } try: leader_set(opts) status_set('maintenance', 'Created FSID and Monitor Secret') log("Settings for the cluster are: {}".format(opts)) except Exception as e: # we're probably not the leader an exception occured # let's log it anyway. log("leader_set failed: {}".format(str(e))) elif (cfg.changed('no-bootstrap') and is_relation_made('bootstrap-source')): # User changed the no-bootstrap config option, we're the leader, # and the bootstrap-source relation has been made. The charm should # be in a blocked state indicating that the no-bootstrap option # must be set. This block is invoked when the user is trying to # get out of that scenario by enabling no-bootstrap. bootstrap_source_relation_changed() # This will only ensure that we are enabled if the 'pg-autotune' option # is explicitly set to 'true', and not if it is 'auto' or 'false' if (config('pg-autotune') == 'true' and cmp_pkgrevno('ceph', '14.2.0') >= 0): # The return value of the enable_module call will tell us if the # module was already enabled, in which case, we don't need to # re-configure the already configured pools if mgr_enable_module('pg_autoscaler'): ceph.monitor_key_set('admin', 'autotune', 'true') for pool in ceph.list_pools(): enable_pg_autoscale('admin', pool) if (config('enable-dashboard') and cmp_pkgrevno('ceph', '14.2.0') >= 0): log("enable-dashboard: {}".format(str(config('enable-dashboard')))) if mgr_enable_module('dashboard'): pass log("configure-dashboard") configure_dashboard() # unconditionally verify that the fsid and monitor-secret are set now # otherwise we exit until a leader does this. if leader_get('fsid') is None or leader_get('monitor-secret') is None: log('still waiting for leader to setup keys') status_set('waiting', 'Waiting for leader to setup keys') return emit_cephconf() # Support use of single node ceph if (not ceph.is_bootstrapped() and int(config('monitor-count')) == 1 and is_leader()): status_set('maintenance', 'Bootstrapping single Ceph MON') # the following call raises an exception if it can't add the keyring try: ceph.bootstrap_monitor_cluster(leader_get('monitor-secret')) except FileNotFoundError as e: # NOQA -- PEP8 is still PY2 log("Couldn't bootstrap the monitor yet: {}".format(str(e))) return ceph.wait_for_bootstrap() ceph.wait_for_quorum() ceph.create_keyrings() if cmp_pkgrevno('ceph', '12.0.0') >= 0: status_set('maintenance', 'Bootstrapping single Ceph MGR') ceph.bootstrap_manager() # Update client relations notify_client()