]> git.proxmox.com Git - pve-manager.git/commitdiff
ceph: mon create: refactor mon assertions
authorDominik Csapak <d.csapak@proxmox.com>
Wed, 19 Jun 2019 11:45:48 +0000 (13:45 +0200)
committerThomas Lamprecht <t.lamprecht@proxmox.com>
Wed, 19 Jun 2019 13:26:33 +0000 (15:26 +0200)
by using our new 'get_services_info'

this already checks for nautilus+ style 'mon_host' key in the ceph.conf
for the ip address

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
PVE/API2/Ceph/MON.pm

index fddfdb7131e31766450db2a9e28972dec6d8d4c6..11871e4f38b67d1b4f18ae90d9e40696201ad1f3 100644 (file)
@@ -56,6 +56,23 @@ my $find_mon_ip = sub {
     }
 };
 
+my $assert_mon_prerequisites = sub {
+    my ($cfg, $monhash, $monid, $monip) = @_;
+
+    my $ip_regex = '(?:^|[^\d])' . # start or nondigit
+              "\Q$monip\E" .  # the ip not interpreted as regex
+              '(?:[^\d]|$)';  # end or nondigit
+
+    if (($cfg->{global}->{mon_host} && $cfg->{global}->{mon_host} =~ m/$ip_regex/) ||
+       grep { $_->{addr} && $_->{addr}  =~ m/$ip_regex/ } values %$monhash) {
+       die "monitor address '$monip' already in use\n";
+    }
+
+    if (defined($monhash->{$monid})) {
+       die "monitor '$monid' already exists\n";
+    }
+};
+
 __PACKAGE__->register_method ({
     name => 'listmon',
     path => '',
@@ -163,32 +180,20 @@ __PACKAGE__->register_method ({
 
        my $cfg = cfs_read_file('ceph.conf');
        my $rados = eval { PVE::RADOS->new() }; # try a rados connection, fails for first monitor
+       my $monhash = PVE::Ceph::Services::get_services_info('mon', $cfg, $rados);
 
-       my $moncount = 0;
-       my $monaddrhash = {};
-       foreach my $section (keys %$cfg) {
-           next if $section eq 'global';
-
-           if ($section =~ m/^mon\./) {
-               my $d = $cfg->{$section};
-               $moncount++;
-               if ($d->{'mon addr'}) {
-                   $monaddrhash->{$d->{'mon addr'}} = $section;
-               }
-           }
+       if (!defined($rados) && (scalar(keys %$monhash) || $cfg->{global}->{mon_host})) {
+           die "Could not connect to ceph cluster despite configured monitors\n";
        }
 
        my $monid = $param->{monid} // $param->{node};
-
        my $monsection = "mon.$monid";
        my $ip = $find_mon_ip->($cfg, $rados, $param->{node}, $param->{'mon-address'});
 
        my $monaddr = Net::IP::ip_is_ipv6($ip) ? "[$ip]:6789" : "$ip:6789";
        my $monname = $param->{node};
 
-       die "monitor '$monsection' already exists\n" if $cfg->{$monsection};
-       die "monitor address '$monaddr' already in use by '$monaddrhash->{$monaddr}'\n"
-           if $monaddrhash->{$monaddr};
+       $assert_mon_prerequisites->($cfg, $monhash, $monid, $ip);
 
        my $worker = sub  {
            my $upid = shift;
@@ -213,11 +218,11 @@ __PACKAGE__->register_method ({
 
                run_command("chown ceph:ceph $mondir");
 
-               if ($moncount > 0) {
+               if (defined($rados)) { # we can only have a RADOS object if we have a monitor
                    my $rados = PVE::RADOS->new(timeout => PVE::Ceph::Tools::get_config('long_rados_timeout'));
                    my $mapdata = $rados->mon_command({ prefix => 'mon getmap', format => 'plain' });
                    file_set_contents($monmap, $mapdata);
-               } else {
+               } else { # we need to create a monmap for the first monitor
                    run_command("monmaptool --create --clobber --add $monid $monaddr --print $monmap");
                }