]> git.proxmox.com Git - pve-storage.git/blobdiff - PVE/CephConfig.pm
Fix #2705: cephfs: mount fails with bad option
[pve-storage.git] / PVE / CephConfig.pm
index ced8358f4186de91eb6213736a132cc8cbe4e272..1e95a90135ae2fced246392ff858ea3b24988add 100644 (file)
@@ -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;
 
@@ -34,8 +35,7 @@ sub parse_ceph_config {
 
        if ($line =~ m/^(.*?\S)\s*=\s*(\S.*)$/) {
            my ($key, $val) = ($1, $2);
-           # ceph treats ' ', '_' and '-' in keys the same, so we
-           # map it to '_' to get a consistent hash
+           # ceph treats ' ', '_' and '-' in keys the same, so lets do too
            $key =~ s/[-\ ]/_/g;
            $cfg->{$section}->{$key} = $val;
        }
@@ -65,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}}) {
@@ -100,6 +100,17 @@ 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;
 
@@ -110,21 +121,37 @@ sub get_monaddr_list {
 
     my $config = $parse_ceph_file->($configfile);
 
-    my @monids = grep { /mon\./ && defined($config->{$_}->{'mon addr'}) } %{$config};
+    my $monhostlist = {};
 
-    return join(',', sort map { $config->{$_}->{'mon addr'} } @monids);
-};
+    # get all ip adresses 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 {
@@ -228,4 +255,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.*\s(\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 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;