]> git.proxmox.com Git - pve-storage.git/blobdiff - PVE/API2/Storage/Config.pm
disks: allow add_storage for already configured local storage
[pve-storage.git] / PVE / API2 / Storage / Config.pm
index ea655c5805256264b6c8d6a41b792947bf460bc8..821db2148efdf95771ad9aebd0b4451cfe518b71 100755 (executable)
@@ -38,6 +38,84 @@ my $api_storage_config = sub {
     return $scfg;
 };
 
+# For storages that $match->($scfg), update node restrictions to not include $node anymore and
+# in case no node remains, remove the storage altogether.
+sub cleanup_storages_for_node {
+    my ($self, $match, $node) = @_;
+
+    my $config = PVE::Storage::config();
+    my $cluster_nodes = PVE::Cluster::get_nodelist();
+
+    for my $storeid (keys $config->{ids}->%*) {
+       my $scfg = PVE::Storage::storage_config($config, $storeid);
+       next if !$match->($scfg);
+
+       my $nodes = $scfg->{nodes} || { map { $_ => 1 } $cluster_nodes->@* };
+       next if !$nodes->{$node}; # not configured on $node, so nothing to do
+       delete $nodes->{$node};
+
+       if (scalar(keys $nodes->%*) > 0) {
+           $self->update({
+               nodes => join(',', sort keys $nodes->%*),
+               storage => $storeid,
+           });
+       } else {
+           $self->delete({storage => $storeid});
+       }
+    }
+}
+
+# Decides if a storage needs to be created or updated. An update is needed, if
+# the storage has a node list configured, then the current node will be added.
+# The verify_params parameter is an array of parameter names that need to match
+# if there already is a storage config of the same name present.  This is
+# mainly intended for local storage types as certain parameters need to be the
+# same.  For exmaple 'pool' for ZFS, 'vg_name' for LVM, ...
+# Set the dryrun parameter, to only verify the parameters without updating or
+# creating the storage.
+sub create_or_update {
+    my ($self, $sid, $node, $storage_params, $verify_params, $dryrun) = @_;
+
+    my $cfg = PVE::Storage::config();
+    my $scfg = PVE::Storage::storage_config($cfg, $sid, 1);
+
+    if ($scfg) {
+       die "storage config for '${sid}' exists but no parameters to verify were provided\n"
+           if !$verify_params;
+
+       $node = PVE::INotify::nodename() if !$node || ($node eq 'localhost');
+       die "Storage ID '${sid}' already exists on node ${node}\n"
+           if !defined($scfg->{nodes}) || $scfg->{nodes}->{$node};
+
+       push @$verify_params, 'type';
+       for my $key (@$verify_params) {
+           if (!defined($scfg->{$key})) {
+               die "Option '${key}' is not configured for storage '$sid', "
+                   ."expected it to be '$storage_params->{$key}'";
+           }
+           if ($storage_params->{$key} ne $scfg->{$key}) {
+               die "Option '${key}' ($storage_params->{$key}) does not match "
+                   ."existing storage configuration '$scfg->{$key}'\n";
+           }
+       }
+    }
+
+    if (!$dryrun) {
+       if ($scfg) {
+           if ($scfg->{nodes}) {
+               $scfg->{nodes}->{$node} = 1;
+               $self->update({
+                   nodes => join(',', sort keys $scfg->{nodes}->%*),
+                   storage => $sid,
+               });
+               print "Added '${node}' to nodes for storage '${sid}'\n";
+           }
+       } else {
+           $self->create($storage_params);
+       }
+    }
+}
+
 __PACKAGE__->register_method ({
     name => 'index',
     path => '',
@@ -112,7 +190,7 @@ __PACKAGE__->register_method ({
        return &$api_storage_config($cfg, $param->{storage});
     }});
 
-my $sensitive_params = [qw(password encryption-key master-pubkey)];
+my $sensitive_params = [qw(password encryption-key master-pubkey keyring)];
 
 __PACKAGE__->register_method ({
     name => 'create',