From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 259321FF13B for ; Wed, 22 Apr 2026 13:16:01 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 687DF17E79; Wed, 22 Apr 2026 13:14:30 +0200 (CEST) From: "Max R. Carrara" To: pve-devel@lists.proxmox.com Subject: [PATCH pve-storage v1 26/54] tree-wide: replace usages of inline regexes for snippets with parsers Date: Wed, 22 Apr 2026 13:12:52 +0200 Message-ID: <20260422111322.257380-27-m.carrara@proxmox.com> X-Mailer: git-send-email 2.47.3 In-Reply-To: <20260422111322.257380-1-m.carrara@proxmox.com> References: <20260422111322.257380-1-m.carrara@proxmox.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Bm-Milter-Handled: 55990f41-d878-4baa-be0a-ee34c49e34d2 X-Bm-Transport-Timestamp: 1776856343217 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.085 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Message-ID-Hash: 3OW2PZ5GLE7PR3BI7CIZM2UC765ZWDHO X-Message-ID-Hash: 3OW2PZ5GLE7PR3BI7CIZM2UC765ZWDHO X-MailFrom: m.carrara@proxmox.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Proxmox VE development discussion List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: Add support for the 'snippets' volume type in `PVE::Storage::Common::Parse`. Also add corresponding test cases. Use the module's parsing functions to replace parsing the a snippet file's name via regexes or the `basename()` function. Signed-off-by: Max R. Carrara --- src/PVE/Storage.pm | 4 +--- src/PVE/Storage/Common/Parse.pm | 8 +++++++ src/PVE/Storage/Common/test/parser_tests.pl | 25 +++++++++++++++++++++ src/PVE/Storage/Plugin.pm | 11 +++++---- 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/src/PVE/Storage.pm b/src/PVE/Storage.pm index ce6d2154..20b7bafa 100755 --- a/src/PVE/Storage.pm +++ b/src/PVE/Storage.pm @@ -769,9 +769,7 @@ sub path_to_volume_id { } if ($vtype eq 'snippets') { - return if $filename !~ m!/([^/]+)$!; - my $name = $1; - return "$sid:snippets/$name"; + return parse_path_as_volid($sid, $scfg, $path, $vtype); } if ($vtype eq 'import') { diff --git a/src/PVE/Storage/Common/Parse.pm b/src/PVE/Storage/Common/Parse.pm index 950f6b18..33220758 100644 --- a/src/PVE/Storage/Common/Parse.pm +++ b/src/PVE/Storage/Common/Parse.pm @@ -106,16 +106,24 @@ my $RE_BACKUP_FILE_PATH = qr! ) !xn; +my $RE_SNIPPETS_FILE_PATH = qr! + (? + (? [^/]+ ) + ) +!xn; + my $RE_FILE_PATH_FOR_VTYPE = { iso => qr/^$RE_ISO_FILE_PATH$/, vztmpl => qr/^$RE_VZTMPL_FILE_PATH$/, backup => qr/^$RE_BACKUP_FILE_PATH$/, + snippets => qr/^$RE_SNIPPETS_FILE_PATH$/, }; my $RE_VOLNAME_FOR_VTYPE = { iso => qr/^$RE_ISO_FILE_PATH$/, vztmpl => qr/^$RE_VZTMPL_FILE_PATH$/, backup => qr/^$RE_BACKUP_FILE_PATH$/, + snippets => qr/^$RE_SNIPPETS_FILE_PATH$/, }; my sub contains_parent_dir($path) { diff --git a/src/PVE/Storage/Common/test/parser_tests.pl b/src/PVE/Storage/Common/test/parser_tests.pl index 96159608..e0029fc6 100755 --- a/src/PVE/Storage/Common/test/parser_tests.pl +++ b/src/PVE/Storage/Common/test/parser_tests.pl @@ -372,10 +372,35 @@ my $volname_cases_backup_invalid = [ }, ]; +my $volname_cases_snippets_valid = [ + # plain files + { + path => 'hookscript.pl', + expected => { + file => 'hookscript.pl', + 'disk-path' => 'hookscript.pl', + path => 'hookscript.pl', + vtype => 'snippets', + volname => 'snippets/hookscript.pl', + }, + }, + { + path => 'userconfig.yaml', + expected => { + file => 'userconfig.yaml', + 'disk-path' => 'userconfig.yaml', + path => 'userconfig.yaml', + vtype => 'snippets', + volname => 'snippets/userconfig.yaml', + }, + }, +]; + my $cases_valid_all = [ $volname_cases_iso_valid, $volname_cases_vztmpl_valid, $volname_cases_backup_valid, + $volname_cases_snippets_valid, ]; my $cases_invalid_all = [ diff --git a/src/PVE/Storage/Plugin.pm b/src/PVE/Storage/Plugin.pm index 4d63e0a5..b08e038b 100644 --- a/src/PVE/Storage/Plugin.pm +++ b/src/PVE/Storage/Plugin.pm @@ -835,10 +835,10 @@ sub parse_volname { if ($vtype eq 'backup') { return ($vtype, $volume_path, $parts->{vmid}, undef, undef, undef, 'raw'); } - } - if ($volname =~ m!^snippets/([^/]+)$!) { - return ('snippets', $1, undef, undef, undef, undef, 'raw'); + if ($vtype eq 'snippets') { + return ($vtype, $volume_path, undef, undef, undef, undef, 'raw'); + } } if ($volname =~ @@ -1758,8 +1758,11 @@ my sub get_subdir_files { } if ($vtype eq 'snippets') { + my $parts = parse_path_as_volid_parts($storeid, $scfg, $path, $vtype); + return if !defined($parts); + return { - volid => "$storeid:snippets/" . basename($filename), + volid => $parts->{volid}, format => 'snippet', }; } -- 2.47.3