X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=PVE%2FCephConfig.pm;h=5c94a04a3bd0491de7c8ad98ba1f44bec0ef2f25;hb=e4d56f096ed28761d6b9a9e348be0fc682928040;hp=b420fcc3ca83cb61e4d58cf772595f561f502a57;hpb=5b5534a9d726972fad0186d1bdc1519cd90b5f2e;p=pve-storage.git diff --git a/PVE/CephConfig.pm b/PVE/CephConfig.pm index b420fcc..5c94a04 100644 --- a/PVE/CephConfig.pm +++ b/PVE/CephConfig.pm @@ -21,8 +21,9 @@ sub parse_ceph_config { my $section; foreach my $line (@lines) { - $line =~ s/[;#].*$//; + $line =~ s/#.*$//; $line =~ s/^\s+//; + $line =~ s/^;.*$//; $line =~ s/\s+$//; next if !$line; @@ -33,7 +34,10 @@ sub parse_ceph_config { } if ($line =~ m/^(.*?\S)\s*=\s*(\S.*)$/) { - $cfg->{$section}->{$1} = $2; + my ($key, $val) = ($1, $2); + # ceph treats ' ', '_' and '-' in keys the same, so lets do too + $key =~ s/[-\ ]/_/g; + $cfg->{$section}->{$key} = $val; } } @@ -61,7 +65,7 @@ sub write_ceph_config { my $cond_write_sec = sub { my $re = shift; - foreach my $section (keys %$cfg) { + foreach my $section (sort keys %$cfg) { next if $section !~ m/^$re$/; $out .= "[$section]\n"; foreach my $key (sort keys %{$cfg->{$section}}) { @@ -96,32 +100,58 @@ my $ceph_get_key = sub { return $secret; }; +my $get_host = sub { + my ($hostport) = @_; + my ($host, $port) = PVE::Tools::parse_host_and_port($hostport); + if (!defined($host)) { + return ""; + } + $port = defined($port) ? ":$port" : ''; + $host = "[$host]" if Net::IP::ip_is_ipv6($host); + return "${host}${port}"; +}; + sub get_monaddr_list { my ($configfile) = shift; - my $server; - if (!defined($configfile)) { warn "No ceph config specified\n"; return; } my $config = $parse_ceph_file->($configfile); - @$server = sort map { $config->{$_}->{'mon addr'} } grep {/mon/} %{$config}; - return join(',', @$server); -}; + my $monhostlist = {}; + + # get all ip addresses from mon_host + my $monhosts = [ split (/[ ,;]+/, $config->{global}->{mon_host} // "") ]; + + foreach my $monhost (@$monhosts) { + $monhost =~ s/^\[?v\d\://; # remove beginning of vector + $monhost =~ s|/\d+\]?||; # remove end of vector + my $host = $get_host->($monhost); + if ($host ne "") { + $monhostlist->{$host} = 1; + } + } + + # then get all addrs from mon. sections + for my $section ( keys %$config ) { + next if $section !~ m/^mon\./; + + if (my $addr = $config->{$section}->{mon_addr}) { + $monhostlist->{$addr} = 1; + } + } + + return join(',', sort keys %$monhostlist); +} sub hostlist { my ($list_text, $separator) = @_; my @monhostlist = PVE::Tools::split_list($list_text); - return join($separator, map { - my ($host, $port) = PVE::Tools::parse_host_and_port($_); - $port = defined($port) ? ":$port" : ''; - $host = "[$host]" if Net::IP::ip_is_ipv6($host); - "${host}${port}" - } @monhostlist); + return join($separator, map { $get_host->($_) } @monhostlist); } my $ceph_check_keyfile = sub { @@ -182,7 +212,7 @@ sub ceph_connect_option { } sub ceph_create_keyfile { - my ($type, $storeid) = @_; + my ($type, $storeid, $secret) = @_; my $extension = 'keyring'; $extension = 'secret' if ($type eq 'cephfs'); @@ -191,17 +221,20 @@ sub ceph_create_keyfile { my $ceph_storage_keyring = "/etc/pve/priv/ceph/${storeid}.$extension"; die "ceph authx keyring file for storage '$storeid' already exists!\n" - if -e $ceph_storage_keyring; + if -e $ceph_storage_keyring && !defined($secret); - if (-e $ceph_admin_keyring) { + if (-e $ceph_admin_keyring || defined($secret)) { eval { - if ($type eq 'rbd') { + if (defined($secret)) { + mkdir '/etc/pve/priv/ceph'; + PVE::Tools::file_set_contents($ceph_storage_keyring, $secret, 0400); + } elsif ($type eq 'rbd') { mkdir '/etc/pve/priv/ceph'; PVE::Tools::file_copy($ceph_admin_keyring, $ceph_storage_keyring); } elsif ($type eq 'cephfs') { - my $secret = $ceph_get_key->($ceph_admin_keyring, 'admin'); + my $cephfs_secret = $ceph_get_key->($ceph_admin_keyring, 'admin'); mkdir '/etc/pve/priv/ceph'; - PVE::Tools::file_set_contents($ceph_storage_keyring, $secret, 0400); + PVE::Tools::file_set_contents($ceph_storage_keyring, $cephfs_secret, 0400); } }; if (my $err = $@) { @@ -225,4 +258,33 @@ sub ceph_remove_keyfile { } } +my $ceph_version_parser = sub { + my $ceph_version = shift; + # FIXME this is the same as pve-manager PVE::Ceph::Tools get_local_version + if ($ceph_version =~ /^ceph.*\sv?(\d+(?:\.\d+)+(?:-pve\d+)?)\s+(?:\(([a-zA-Z0-9]+)\))?/) { + my ($version, $buildcommit) = ($1, $2); + my $subversions = [ split(/\.|-/, $version) ]; + + return ($subversions, $version, $buildcommit); + } + warn "Could not parse Ceph version: '$ceph_version'\n"; +}; + +sub local_ceph_version { + my ($cache) = @_; + + my $version_string = $cache; + if (!defined($version_string)) { + run_command('ceph --version', outfunc => sub { + $version_string = shift; + }); + } + return undef if !defined($version_string); + # subversion is an array ref. with the version parts from major to minor + # version is the filtered version string + my ($subversions, $version) = $ceph_version_parser->($version_string); + + return wantarray ? ($subversions, $version) : $version; +} + 1;