* [pve-devel] [PATCH storage/manager v2] allow upload & import of qcow2 in the web UI @ 2025-03-20 13:40 Dominik Csapak 2025-03-20 13:40 ` [pve-devel] [PATCH storage v2 1/1] import: allow upload of qcow2 files into import storage Dominik Csapak ` (4 more replies) 0 siblings, 5 replies; 7+ messages in thread From: Dominik Csapak @ 2025-03-20 13:40 UTC (permalink / raw) To: pve-devel most of the building blocks are already there: * we can have qcow2 files in an import storage * we can import qcow2 files via the api from such a storage this series fills in the missing bits & pieces: * allow uploading qcow2 files into an import storage via the webgui * adding the possibility to select such a file when creating a vm/disk We could maybe also allow this for raw/vmdk if we want to, but IMHO we can start out with qcow2 and add the others as necssary. (if wanted, I can of course also add the others in a next version or as a follow up) changes from v1: * fixed an issue where the file selector would be hidden but invalid pve-storage: Dominik Csapak (1): import: allow upload of qcow2 files into import storage src/PVE/API2/Storage/Status.pm | 17 ++++++++++++++++- src/PVE/Storage.pm | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) pve-manager: Dominik Csapak (3): ui: storage content: allow upload of qcow2 for import type ui: form: file selector: allow optional filter ui: qemu hd edit: allow importing a disk from the import storage www/manager6/form/FileSelector.js | 10 ++++ www/manager6/qemu/HDEdit.js | 72 +++++++++++++++++++++++++- www/manager6/window/UploadToStorage.js | 2 +- 3 files changed, 82 insertions(+), 2 deletions(-) -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 7+ messages in thread
* [pve-devel] [PATCH storage v2 1/1] import: allow upload of qcow2 files into import storage 2025-03-20 13:40 [pve-devel] [PATCH storage/manager v2] allow upload & import of qcow2 in the web UI Dominik Csapak @ 2025-03-20 13:40 ` Dominik Csapak 2025-03-20 13:40 ` [pve-devel] [PATCH manager v2 1/3] ui: storage content: allow upload of qcow2 for import type Dominik Csapak ` (3 subsequent siblings) 4 siblings, 0 replies; 7+ messages in thread From: Dominik Csapak @ 2025-03-20 13:40 UTC (permalink / raw) To: pve-devel so users can upload qcow2 files directly in the ui Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> --- no changes in v2: src/PVE/API2/Storage/Status.pm | 17 ++++++++++++++++- src/PVE/Storage.pm | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/PVE/API2/Storage/Status.pm b/src/PVE/API2/Storage/Status.pm index c854b53..b253392 100644 --- a/src/PVE/API2/Storage/Status.pm +++ b/src/PVE/API2/Storage/Status.pm @@ -456,6 +456,7 @@ __PACKAGE__->register_method ({ my $path; my $isOva = 0; + my $isQcow2 = 0; if ($content eq 'iso') { if ($filename !~ m![^/]+$PVE::Storage::ISO_EXT_RE_0$!) { @@ -472,7 +473,12 @@ __PACKAGE__->register_method ({ raise_param_exc({ filename => "invalid filename or wrong extension" }); } - $isOva = 1; + if ($filename =~ m/\.ova$/) { + $isOva = 1; + } elsif ($filename =~ m/\.qcow2$/) { + $isQcow2 = 1; + } + $path = PVE::Storage::get_import_dir($cfg, $storage); } else { raise_param_exc({ content => "upload content type '$content' not allowed" }); @@ -543,6 +549,9 @@ __PACKAGE__->register_method ({ if ($isOva) { assert_ova_contents($tmpfilename); + } elsif ($isQcow2) { + # checks untrusted image + PVE::Storage::file_size_info($tmpfilename, 10, 'qcow2', 1); } }; if (my $err = $@) { @@ -667,6 +676,7 @@ __PACKAGE__->register_method({ my $path; my $isOva = 0; + my $isQcow2 = 0; if ($content eq 'iso') { if ($filename !~ m![^/]+$PVE::Storage::ISO_EXT_RE_0$!) { @@ -685,6 +695,8 @@ __PACKAGE__->register_method({ if ($filename =~ m/\.ova$/) { $isOva = 1; + } elsif ($filename =~ m/\.qcow2$/) { + $isQcow2 = 1; } $path = PVE::Storage::get_import_dir($cfg, $storage); @@ -717,6 +729,9 @@ __PACKAGE__->register_method({ if ($isOva) { assert_ova_contents($tmp_path); + } elsif ($isQcow2) { + # checks untrusted image + PVE::Storage::file_size_info($tmp_path, 10, 'qcow2', 1); } }; diff --git a/src/PVE/Storage.pm b/src/PVE/Storage.pm index 3b4f041..deed73f 100755 --- a/src/PVE/Storage.pm +++ b/src/PVE/Storage.pm @@ -116,7 +116,7 @@ our $BACKUP_EXT_RE_2 = qr/\.(tgz|(?:tar|vma)(?:\.(${\PVE::Storage::Plugin::COMPR our $IMPORT_EXT_RE_1 = qr/\.(ova|ovf|qcow2|raw|vmdk)/; -our $UPLOAD_IMPORT_EXT_RE_1 = qr/\.(ova)/; +our $UPLOAD_IMPORT_EXT_RE_1 = qr/\.(ova|qcow2)/; our $SAFE_CHAR_CLASS_RE = qr/[a-zA-Z0-9\-\.\+\=\_]/; our $SAFE_CHAR_WITH_WHITESPACE_CLASS_RE = qr/[ a-zA-Z0-9\-\.\+\=\_]/; -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 7+ messages in thread
* [pve-devel] [PATCH manager v2 1/3] ui: storage content: allow upload of qcow2 for import type 2025-03-20 13:40 [pve-devel] [PATCH storage/manager v2] allow upload & import of qcow2 in the web UI Dominik Csapak 2025-03-20 13:40 ` [pve-devel] [PATCH storage v2 1/1] import: allow upload of qcow2 files into import storage Dominik Csapak @ 2025-03-20 13:40 ` Dominik Csapak 2025-03-20 13:40 ` [pve-devel] [PATCH manager v2 2/3] ui: form: file selector: allow optional filter Dominik Csapak ` (2 subsequent siblings) 4 siblings, 0 replies; 7+ messages in thread From: Dominik Csapak @ 2025-03-20 13:40 UTC (permalink / raw) To: pve-devel partially fixes #2424 Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> --- no changes in v2 www/manager6/window/UploadToStorage.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/www/manager6/window/UploadToStorage.js b/www/manager6/window/UploadToStorage.js index cdf548a8..3ce2d1f5 100644 --- a/www/manager6/window/UploadToStorage.js +++ b/www/manager6/window/UploadToStorage.js @@ -9,7 +9,7 @@ Ext.define('PVE.window.UploadToStorage', { title: gettext('Upload'), acceptedExtensions: { - 'import': ['.ova'], + 'import': ['.ova', '.qcow2'], iso: ['.img', '.iso'], vztmpl: ['.tar.gz', '.tar.xz', '.tar.zst'], }, -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 7+ messages in thread
* [pve-devel] [PATCH manager v2 2/3] ui: form: file selector: allow optional filter 2025-03-20 13:40 [pve-devel] [PATCH storage/manager v2] allow upload & import of qcow2 in the web UI Dominik Csapak 2025-03-20 13:40 ` [pve-devel] [PATCH storage v2 1/1] import: allow upload of qcow2 files into import storage Dominik Csapak 2025-03-20 13:40 ` [pve-devel] [PATCH manager v2 1/3] ui: storage content: allow upload of qcow2 for import type Dominik Csapak @ 2025-03-20 13:40 ` Dominik Csapak 2025-03-20 13:40 ` [pve-devel] [PATCH manager v2 3/3] ui: qemu hd edit: allow importing a disk from the import storage Dominik Csapak 2025-03-25 15:16 ` [pve-devel] [PATCH storage/manager v2] allow upload & import of qcow2 in the web UI Dominik Csapak 4 siblings, 0 replies; 7+ messages in thread From: Dominik Csapak @ 2025-03-20 13:40 UTC (permalink / raw) To: pve-devel this sometimes comes in handy when we only want to show specific files. Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> --- no changes in v2 www/manager6/form/FileSelector.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/www/manager6/form/FileSelector.js b/www/manager6/form/FileSelector.js index ef2bedf9..9db20711 100644 --- a/www/manager6/form/FileSelector.js +++ b/www/manager6/form/FileSelector.js @@ -43,6 +43,13 @@ Ext.define('PVE.form.FileSelector', { url: url, }); + if (Ext.isFunction(me.filter)) { + me.store.clearFilter(); + me.store.addFilter([me.filter]); + } else { + me.store.clearFilter(); + } + me.store.removeAll(); me.store.load(); }, @@ -60,6 +67,9 @@ Ext.define('PVE.form.FileSelector', { valueField: 'volid', displayField: 'text', + // An optional filter function + filter: undefined, + listConfig: { width: 600, columns: [ -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 7+ messages in thread
* [pve-devel] [PATCH manager v2 3/3] ui: qemu hd edit: allow importing a disk from the import storage 2025-03-20 13:40 [pve-devel] [PATCH storage/manager v2] allow upload & import of qcow2 in the web UI Dominik Csapak ` (2 preceding siblings ...) 2025-03-20 13:40 ` [pve-devel] [PATCH manager v2 2/3] ui: form: file selector: allow optional filter Dominik Csapak @ 2025-03-20 13:40 ` Dominik Csapak 2025-03-25 11:10 ` Filip Schauer 2025-03-25 15:16 ` [pve-devel] [PATCH storage/manager v2] allow upload & import of qcow2 in the web UI Dominik Csapak 4 siblings, 1 reply; 7+ messages in thread From: Dominik Csapak @ 2025-03-20 13:40 UTC (permalink / raw) To: pve-devel adds a checkbox 'import image' above the storage selector which: * hides the original storage selector * shows a 'source storage' selector * shows a 'import file' selector * shows a 'target storage' selector Since the wizard and the hd edit share this panel, this also works in the wizard. Signed-off-by: Dominik Csapak <d.csapak@proxmox.com> --- changes from v1: * only enable the file selector if the storage selector is enabled -> fixes an issue where it would be invalid but hidden, preventing continuing www/manager6/qemu/HDEdit.js | 72 ++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-) diff --git a/www/manager6/qemu/HDEdit.js b/www/manager6/qemu/HDEdit.js index b78647ec..aec23885 100644 --- a/www/manager6/qemu/HDEdit.js +++ b/www/manager6/qemu/HDEdit.js @@ -78,11 +78,17 @@ Ext.define('PVE.qemu.HDInputPanel', { if (values.hdimage) { me.drive.file = values.hdimage; } else { - me.drive.file = values.hdstorage + ":" + values.disksize; + let disksize = values.disksize; + if (values['import-from']) { + PVE.Utils.propertyStringSet(me.drive, values['import-from'], 'import-from'); + disksize = 0; + } + me.drive.file = `${values.hdstorage}:${disksize}`; } me.drive.format = values.diskformat; } + PVE.Utils.propertyStringSet(me.drive, !values.backup, 'backup', '0'); PVE.Utils.propertyStringSet(me.drive, values.noreplicate, 'replicate', 'no'); PVE.Utils.propertyStringSet(me.drive, values.discard, 'discard', 'on'); @@ -168,6 +174,11 @@ Ext.define('PVE.qemu.HDInputPanel', { var me = this; me.down('#hdstorage').setNodename(nodename); me.down('#hdimage').setStorage(undefined, nodename); + + me.lookup('new-disk').setNodename(nodename); + me.lookup('import-source').setNodename(nodename); + me.lookup('import-source-file').setNodename(nodename); + me.lookup('import-target').setNodename(nodename); }, hasAdvanced: true, @@ -221,12 +232,71 @@ Ext.define('PVE.qemu.HDInputPanel', { column1.push(me.unusedDisks); } else if (me.isCreate) { column1.push({ + xtype: 'proxmoxcheckbox', + isFormField: false, + fieldLabel: gettext("Import Image"), + listeners: { + change: function(_cb, value) { + me.lookup('new-disk').setVisible(!value); + me.lookup('new-disk').setDisabled(!!value); + + me.lookup('import-source').setVisible(!!value); + me.lookup('import-source').setDisabled(!value); + me.lookup('import-source-file').setVisible(!!value); + + me.lookup('import-target').setVisible(!!value); + me.lookup('import-target').setDisabled(!value); + }, + }, + }); + column1.push({ + reference: 'new-disk', xtype: 'pveDiskStorageSelector', storageContent: 'images', name: 'disk', nodename: me.nodename, autoSelect: me.insideWizard, }); + column1.push({ + xtype: 'pveStorageSelector', + reference: 'import-source', + fieldLabel: gettext('Import Storage'), + name: 'import-source-storage', + hidden: true, + disabled: true, + storageContent: 'import', + nodename: me.nodename, + autoSelect: me.insideWizard, + listeners: { + change: function(selector, storage) { + me.lookup('import-source-file').setStorage(storage); + me.lookup('import-source-file').setDisabled(!storage || selector.isDisabled()); + }, + }, + }); + column1.push({ + xtype: 'pveFileSelector', + reference: 'import-source-file', + fieldLabel: gettext("Select Image"), + hidden: true, + disabled: true, + storageContent: 'import', + name: 'import-from', + filter: (rec) => rec?.data?.format === 'qcow2', + nodename: me.nodename, + }); + column1.push({ + xtype: 'pveDiskStorageSelector', + reference: 'import-target', + storageLabel: gettext('Target Storage'), + hidden: true, + disabled: true, + hideSize: true, + storageContent: 'images', + name: 'target', + nodename: me.nodename, + autoSelect: me.insideWizard, + }); } else { column1.push({ xtype: 'textfield', -- 2.39.5 _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [pve-devel] [PATCH manager v2 3/3] ui: qemu hd edit: allow importing a disk from the import storage 2025-03-20 13:40 ` [pve-devel] [PATCH manager v2 3/3] ui: qemu hd edit: allow importing a disk from the import storage Dominik Csapak @ 2025-03-25 11:10 ` Filip Schauer 0 siblings, 0 replies; 7+ messages in thread From: Filip Schauer @ 2025-03-25 11:10 UTC (permalink / raw) To: pve-devel The bug from before is solved, but instead a different bug has appeared: When I enable the "Import Image" checkbox on the "Disks" tab of the virtual machine creation wizard, the "Select Image" selector is disabled by default. It can be enabled by switching the import storage. On 20/03/2025 14:40, Dominik Csapak wrote: > + fieldLabel: gettext("Import Image"), > + listeners: { > + change: function(_cb, value) { > + me.lookup('new-disk').setVisible(!value); > + me.lookup('new-disk').setDisabled(!!value); > + > + me.lookup('import-source').setVisible(!!value); > + me.lookup('import-source').setDisabled(!value); > + me.lookup('import-source-file').setVisible(!!value); > + > + me.lookup('import-target').setVisible(!!value); > + me.lookup('import-target').setDisabled(!value); > + }, It seems this can be fixed by adding: me.lookup('import-source-file').setDisabled(!value); _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [pve-devel] [PATCH storage/manager v2] allow upload & import of qcow2 in the web UI 2025-03-20 13:40 [pve-devel] [PATCH storage/manager v2] allow upload & import of qcow2 in the web UI Dominik Csapak ` (3 preceding siblings ...) 2025-03-20 13:40 ` [pve-devel] [PATCH manager v2 3/3] ui: qemu hd edit: allow importing a disk from the import storage Dominik Csapak @ 2025-03-25 15:16 ` Dominik Csapak 4 siblings, 0 replies; 7+ messages in thread From: Dominik Csapak @ 2025-03-25 15:16 UTC (permalink / raw) To: pve-devel sent a v3: https://lore.proxmox.com/pve-devel/20250325151421.3182493-1-d.csapak@proxmox.com/ _______________________________________________ pve-devel mailing list pve-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-03-25 15:16 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2025-03-20 13:40 [pve-devel] [PATCH storage/manager v2] allow upload & import of qcow2 in the web UI Dominik Csapak 2025-03-20 13:40 ` [pve-devel] [PATCH storage v2 1/1] import: allow upload of qcow2 files into import storage Dominik Csapak 2025-03-20 13:40 ` [pve-devel] [PATCH manager v2 1/3] ui: storage content: allow upload of qcow2 for import type Dominik Csapak 2025-03-20 13:40 ` [pve-devel] [PATCH manager v2 2/3] ui: form: file selector: allow optional filter Dominik Csapak 2025-03-20 13:40 ` [pve-devel] [PATCH manager v2 3/3] ui: qemu hd edit: allow importing a disk from the import storage Dominik Csapak 2025-03-25 11:10 ` Filip Schauer 2025-03-25 15:16 ` [pve-devel] [PATCH storage/manager v2] allow upload & import of qcow2 in the web UI Dominik Csapak
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inboxService provided by Proxmox Server Solutions GmbH | Privacy | Legal