my $ceph_cfgpath = "$ceph_cfgdir/$ccname.conf";
my $pve_ceph_cfgdir = "/etc/pve/ceph";
+my $pve_ceph_crash_key_path = "$pve_ceph_cfgdir/$ccname.client.crash.keyring";
my $pve_mon_key_path = "/etc/pve/priv/$ccname.mon.keyring";
my $pve_ckeyring_path = "/etc/pve/priv/$ccname.client.admin.keyring";
my $ckeyring_path = "/etc/ceph/ceph.client.admin.keyring";
my $config_files = {
pve_ceph_cfgpath => $pve_ceph_cfgpath,
+ pve_ceph_crash_key_path => $pve_ceph_crash_key_path,
pve_mon_key_path => $pve_mon_key_path,
pve_ckeyring_path => $pve_ckeyring_path,
ceph_bootstrap_osd_keyring => $ceph_bootstrap_osd_keyring,
return $pve_ckeyring_path;
}
+# is also used in `pve-init-ceph-crash` helper
+sub create_or_update_crash_keyring_file {
+ my ($rados) = @_;
+
+ if (!defined($rados)) {
+ $rados = PVE::RADOS->new();
+ }
+
+ my $output = $rados->mon_command({
+ prefix => 'auth get-or-create',
+ entity => 'client.crash',
+ caps => [
+ mon => 'profile crash',
+ mgr => 'profile crash',
+ ],
+ format => 'plain',
+ });
+
+ if (-f $pve_ceph_crash_key_path) {
+ my $contents = PVE::Tools::file_get_contents($pve_ceph_crash_key_path);
+
+ if ($contents ne $output) {
+ PVE::Tools::file_set_contents($pve_ceph_crash_key_path, $output);
+ return 1;
+ }
+ } else {
+ PVE::Tools::file_set_contents($pve_ceph_crash_key_path, $output);
+ return 1;
+ }
+
+ return 0;
+}
+
# get ceph-volume managed osds
sub ceph_volume_list {
my $result = {};
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+use List::Util qw(first);
+
+use PVE::Ceph::Tools;
+use PVE::Cluster;
+use PVE::RADOS;
+use PVE::RPCEnvironment;
+
+my $ceph_cfg_file = 'ceph.conf';
+my $keyring_value = '/etc/pve/ceph/$cluster.$name.keyring';
+
+
+sub try_adapt_cfg {
+ my ($cfg) = @_;
+
+ my $entity = 'client.crash';
+ my $removed_key = 0;
+
+ print("Checking whether the configuration for '$entity' needs to be updated.\n");
+
+ my $add_keyring = sub {
+ print("Setting keyring path to '$keyring_value'.\n");
+ $cfg->{$entity}->{keyring} = $keyring_value;
+ };
+
+ if (!exists($cfg->{$entity})) {
+ print("Adding missing section for '$entity'.\n");
+ $add_keyring->();
+ return 1;
+ }
+
+ if (exists($cfg->{$entity}->{key})) {
+ print("Removing existing usage of key.\n");
+ delete($cfg->{$entity}->{key});
+ $removed_key = 1;
+ }
+
+ if (!exists($cfg->{$entity}->{keyring})) {
+ print("Keyring path is missing from configuration.\n");
+ $add_keyring->();
+ return 1;
+ }
+
+ my $current_keyring_value = $cfg->{$entity}->{keyring};
+ if ($current_keyring_value ne $keyring_value) {
+ print("Current keyring path differs from expected path.\n");
+ $add_keyring->();
+ return 1;
+ }
+
+ return $removed_key;
+}
+
+
+sub main {
+ # PVE::RADOS expects an active RPC Environment because it forks itself
+ # and may want to clean up after
+ my $rpcenv = PVE::RPCEnvironment->setup_default_cli_env();
+
+ if (!PVE::Ceph::Tools::check_ceph_installed('ceph_bin', 1)) {
+ print("Ceph is not installed. No action required.\n");
+ exit 0;
+ }
+
+ eval {
+ PVE::Ceph::Tools::check_ceph_inited();
+ };
+ if ($@) {
+ print("Ceph is not initialized. No action required.\n");
+ exit 0;
+ }
+
+ my $rados = eval { PVE::RADOS->new() };
+ my $ceph_crash_key_path = PVE::Ceph::Tools::get_config('pve_ceph_crash_key_path');
+
+ my $inner_err = '';
+
+ my $rval = PVE::Cluster::cfs_lock_file($ceph_cfg_file, undef, sub {
+ eval {
+ my $cfg = PVE::Cluster::cfs_read_file($ceph_cfg_file);
+
+ if (!defined($rados)) {
+ my $has_mon_host = defined($cfg->{global}) && defined($cfg->{global}->{mon_host});
+ if ($has_mon_host && $cfg->{global}->{mon_host} ne '') {
+ die "Connection to RADOS failed even though a monitor is configured.\n" .
+ "Please verify whether your configuration in '$ceph_cfg_file' is correct.\n"
+ }
+
+ print(
+ "Connection to RADOS failed and no monitor is configured in '$ceph_cfg_file'.\n".
+ "Assuming that things are fine. No action required.\n"
+ );
+ return;
+ }
+
+ my $updated_keyring = PVE::Ceph::Tools::create_or_update_crash_keyring_file($rados);
+
+ if ($updated_keyring) {
+ print("Keyring file '$ceph_crash_key_path' was updated.\n");
+ }
+
+ my $changed = try_adapt_cfg($cfg);
+
+ if ($changed) {
+ print("Committing updated configuration to '$ceph_cfg_file'.\n");
+ PVE::Cluster::cfs_write_file($ceph_cfg_file, $cfg);
+ print("Successfully updated configuration for 'ceph-crash.service'.\n");
+ } else {
+ print("Configuration in '$ceph_cfg_file' does not need to be updated.\n");
+ }
+ };
+ $inner_err = $@;
+
+ return 1;
+ });
+
+ # cfs_lock_file sets $@ explicitly to undef
+ my $err = $@ // '';
+
+ my $has_err = !defined($rval) || $inner_err || $err;
+
+ if ($has_err) {
+ $err =~ s/\n*$//;
+ $inner_err =~ s/\n*$//;
+
+ if (!defined($rval)) {
+ warn("Error while acquiring or releasing lock for '$ceph_cfg_file'.\n");
+ warn("Error: $err\n") if $err ne '';
+ }
+
+ warn("Failed to configure keyring for 'ceph-crash.service'.\nError: $inner_err\n")
+ if $inner_err ne '';
+
+ exit 1;
+ }
+}
+
+main();
update_ceph_conf() {
CEPH_CONF_DIR='/etc/pve/ceph'
+ UNIT='ceph-crash.service'
+
+ echo ""
if test ! -d "${CEPH_CONF_DIR}"; then
mkdir -p "${CEPH_CONF_DIR}"
fi
+
+ # Don't fail in case user has "exotic" configuration where RADOS
+ # isn't available on all nodes for some reason
+ /usr/share/pve-manager/helpers/pve-init-ceph-crash || true
+
+ if systemctl -q is-enabled "$UNIT" 2> /dev/null; then
+ deb-systemd-invoke restart "$UNIT" || true
+ fi
+
+ echo ""
}
migrate_apt_auth_conf() {