From: Leo Nunner Date: Mon, 2 Jan 2023 16:04:37 +0000 (+0100) Subject: config: add overrides for default directory locations X-Git-Url: https://git.proxmox.com/?p=pve-storage.git;a=commitdiff_plain;h=3e7bd7dac3beb6d994eb5aee05865c210d2b00e3 config: add overrides for default directory locations Allowing overrides for the default directory locations seems to integrate rather well into the existing system. Custom locations are specified using the "dirs" parameter as a comma-separated list of "vtype:/location" values. For now, the option has been enabled for the Directory, CIFS and NFS backends. Signed-off-by: Leo Nunner --- diff --git a/PVE/Storage/CIFSPlugin.pm b/PVE/Storage/CIFSPlugin.pm index 982040a..4284c35 100644 --- a/PVE/Storage/CIFSPlugin.pm +++ b/PVE/Storage/CIFSPlugin.pm @@ -128,6 +128,7 @@ sub properties { sub options { return { path => { fixed => 1 }, + dirs => { optional => 1 }, server => { fixed => 1 }, share => { fixed => 1 }, nodes => { optional => 1 }, diff --git a/PVE/Storage/DirPlugin.pm b/PVE/Storage/DirPlugin.pm index 8715a9d..3c907ca 100644 --- a/PVE/Storage/DirPlugin.pm +++ b/PVE/Storage/DirPlugin.pm @@ -54,6 +54,7 @@ sub properties { sub options { return { path => { fixed => 1 }, + dirs => { optional => 1 }, nodes => { optional => 1 }, shared => { optional => 1 }, disable => { optional => 1 }, diff --git a/PVE/Storage/NFSPlugin.pm b/PVE/Storage/NFSPlugin.pm index 5bd7313..b7e8318 100644 --- a/PVE/Storage/NFSPlugin.pm +++ b/PVE/Storage/NFSPlugin.pm @@ -79,6 +79,7 @@ sub properties { sub options { return { path => { fixed => 1 }, + dirs => { optional => 1 }, server => { fixed => 1 }, export => { fixed => 1 }, nodes => { optional => 1 }, diff --git a/PVE/Storage/Plugin.pm b/PVE/Storage/Plugin.pm index 8a41df1..5cb3d90 100644 --- a/PVE/Storage/Plugin.pm +++ b/PVE/Storage/Plugin.pm @@ -181,6 +181,11 @@ my $defaultData = { default => 'metadata', optional => 1, }, + dirs => { + description => "Overrides for default directories", + type => "string", format => "pve-dir-override-list", + optional => 1, + }, }, }; @@ -205,6 +210,12 @@ sub valid_content_types { return $def->{content}->[0]; } +sub dirs_hash_to_string { + my $hash = shift; + + return join(',', map { "$_:$hash->{$_}" } sort keys %$hash); +} + sub default_format { my ($scfg) = @_; @@ -335,6 +346,18 @@ sub parse_volume_id { die "unable to parse volume ID '$volid'\n"; } +PVE::JSONSchema::register_format('pve-dir-override', \&verify_dir_override); +sub verify_dir_override { + my ($value, $noerr) = @_; + + if($value =~ m/^([a-z]+):(.+)$/ && + verify_content($1, $noerr) && verify_path($2, $noerr)) { + return $value; + } + + return undef if $noerr; + die "invalid override '$value'\n"; +} sub private { return $defaultData; @@ -405,6 +428,22 @@ sub decode_value { # die "storage '$storeid' does not allow node restrictions\n"; #} + return $res; + } elsif ($key eq 'dirs') { + my $valid_content = $def->{content}->[0]; + my $res = {}; + + foreach my $dir (PVE::Tools::split_list($value)) { + my ($content, $path) = split(/:/, $dir, 2); + + if (!$valid_content->{$content}) { + warn "storage does not support content type '$content'\n"; + next; + } + + $res->{$content} = $path; + } + return $res; } @@ -419,6 +458,9 @@ sub encode_value { } elsif ($key eq 'content') { my $res = content_hash_to_string($value) || 'none'; return $res; + } elsif ($key eq 'dirs') { + my $res = dirs_hash_to_string($value); + return $res; } return $value; @@ -610,12 +652,11 @@ sub get_subdir { my $path = $scfg->{path}; die "storage definition has no path\n" if !$path; + die "unknown vtype '$vtype'\n" if !exists($vtype_subdirs->{$vtype}); - my $subdir = $vtype_subdirs->{$vtype}; - - die "unknown vtype '$vtype'\n" if !defined($subdir); + my $subdir = $scfg->{dirs}->{$vtype} // "/".$vtype_subdirs->{$vtype}; - return "$path/$subdir"; + return $path.$subdir; } sub filesystem_path { diff --git a/test/get_subdir_test.pm b/test/get_subdir_test.pm index 1e58350..26c08d5 100644 --- a/test/get_subdir_test.pm +++ b/test/get_subdir_test.pm @@ -27,6 +27,13 @@ foreach my $type (keys %$vtype_subdirs) { push @$tests, [ $scfg_with_path, $type, $path ]; } +# creates additional tests for overrides +foreach my $type (keys %$vtype_subdirs) { + my $override = "/${type}_override"; + my $scfg_with_override = { path => '/some/path', dirs => { $type => $override } }; + push @$tests, [ $scfg_with_override, $type, "$scfg_with_override->{path}$scfg_with_override->{dirs}->{$type}" ]; +} + plan tests => scalar @$tests; foreach my $tt (@$tests) {