[pve-devel] [RFC v2 manager] change permissions for non-network cloudinit settings
With the introduction of VM.Config.Cloudinit we can set the user, password and an SSH key without VM.Config.Network permission. Keep the fallback for VM.Config.Network so custom roles don't break. Signed-off-by: Mira Limbeck --- v2: - fallback to 'VM.Config.Network' requires both pve-access-control patch and qemu-server patch www/manager6/qemu/CloudInit.js | 8 +--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/www/manager6/qemu/CloudInit.js b/www/manager6/qemu/CloudInit.js index c6ff4626..1f7631f7 100644 --- a/www/manager6/qemu/CloudInit.js +++ b/www/manager6/qemu/CloudInit.js @@ -192,6 +192,8 @@ Ext.define('PVE.qemu.CloudInit', { me.editorConfig.url = me.baseurl + '/config'; me.editorConfig.pveSelNode = me.pveSelNode; + let caps_ci = caps.vms['VM.Config.Cloudinit']; + || caps.vms['VM.Config.Network']; /* editor is string and object */ me.rows = { ciuser: { @@ -199,7 +201,7 @@ Ext.define('PVE.qemu.CloudInit', { iconCls: 'fa fa-user', never_delete: true, defaultValue: '', - editor: caps.vms['VM.Config.Options'] ? { + editor: caps_ci ? { xtype: 'proxmoxWindowEdit', subject: gettext('User'), items: [ @@ -220,7 +222,7 @@ Ext.define('PVE.qemu.CloudInit', { header: gettext('Password'), iconCls: 'fa fa-unlock', defaultValue: '', - editor: caps.vms['VM.Config.Options'] ? { + editor: caps_ci ? { xtype: 'proxmoxWindowEdit', subject: gettext('Password'), items: [ @@ -255,7 +257,7 @@ Ext.define('PVE.qemu.CloudInit', { sshkeys: { header: gettext('SSH public key'), iconCls: 'fa fa-key', - editor: caps.vms['VM.Config.Network'] ? 'PVE.qemu.SSHKeyEdit' : undefined, + editor: caps_ci ? 'PVE.qemu.SSHKeyEdit' : undefined, never_delete: true, renderer: function(value) { value = decodeURIComponent(value); -- 2.20.1 ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] [RFC v2 qemu-server] close #2741: add VM.Config.Cloudinit permission
This allows setting ciuser, cipassword and all other cloudinit settings that are not part of the network without VM.Config.Network permissions. Keep VM.Config.Network still as fallback so custom roles that add VM.Config.Network but not VM.Config.Cloudinit don't break. Signed-off-by: Mira Limbeck --- v2: - fallback for 'VM.Config.Network' - addition to $vm_config_perm_list - removed unnecessary print statement This requires the pve-access-control patch. PVE/API2/Qemu.pm | 5 - 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/PVE/API2/Qemu.pm b/PVE/API2/Qemu.pm index 3965c26..b33359d 100644 --- a/PVE/API2/Qemu.pm +++ b/PVE/API2/Qemu.pm @@ -358,8 +358,10 @@ my $check_vm_modify_config_perm = sub { $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.PowerMgmt']); } elsif ($diskoptions->{$opt}) { $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.Disk']); - } elsif ($cloudinitoptions->{$opt} || ($opt =~ m/^(?:net|ipconfig)\d+$/)) { + } elsif ($opt =~ m/^(?:net|ipconfig)\d+$/) { $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.Network']); + } elsif ($cloudinitoptions->{$opt}) { + $rpcenv->check_vm_perm($authuser, $vmid, $pool, ['VM.Config.Cloudinit', 'VM.Config.Network'], 1); } elsif ($opt eq 'vmstate') { # the user needs Disk and PowerMgmt privileges to change the vmstate # also needs privileges on the storage, that will be checked later @@ -1354,6 +1356,7 @@ my $vm_config_perm_list = [ 'VM.Config.Network', 'VM.Config.HWType', 'VM.Config.Options', + 'VM.Config.Cloudinit', ]; __PACKAGE__->register_method({ -- 2.20.1 ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] [RFC v2 access-control] introduce VM.Config.Cloudinit permission
It is added to PVEVMUser by default. Signed-off-by: Mira Limbeck --- v2: - unchanged PVE/AccessControl.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/PVE/AccessControl.pm b/PVE/AccessControl.pm index f50a510..ae8eaae 100644 --- a/PVE/AccessControl.pm +++ b/PVE/AccessControl.pm @@ -741,6 +741,7 @@ my $privgroups = { ], user => [ 'VM.Config.CDROM', # change CDROM media + 'VM.Config.Cloudinit', 'VM.Console', 'VM.Backup', 'VM.PowerMgmt', -- 2.20.1 ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] [PATCH qemu-server] avoid backup command timeout with pbs
--- PVE/VZDump/QemuServer.pm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/PVE/VZDump/QemuServer.pm b/PVE/VZDump/QemuServer.pm index 1a0d437..147a3e6 100644 --- a/PVE/VZDump/QemuServer.pm +++ b/PVE/VZDump/QemuServer.pm @@ -403,6 +403,8 @@ sub archive_pbs { $params->{fingerprint} = $fingerprint if defined($fingerprint); $params->{'firewall-file'} = $firewall if -e $firewall; + $params->{timeout} = 60; # give some time to connect to the backup server + my $res = eval { mon_cmd($vmid, "backup", %$params) }; my $qmperr = $@; $backup_job_uuid = $res->{UUID} if $res; -- 2.20.1 ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] cloudinit: generate server ssh keys on proxmox side ?
Hi, I'm currently testing cloudinit, and I have notice that each time we are doing a change, as we generate a new instance each time (because they are no other easy way to get network configuration regenerate), The server ssh private keys are generate again and again. It's possible to put in cloudinit config the sshkeys like https://cloudinit.readthedocs.io/en/latest/topics/examples.html "ssh_keys: rsa_private: | -BEGIN RSA PRIVATE KEY- MIIBxwIBAAJhAKD0YSHy73nUgysO13XsJmd4fHiFyQ+00R7VVu2iV9Qcon2LZS/x 1cydPZ4pQpfjEha6WxZ6o8ci/Ea/w0n+0HGPwaxlEG2Z9inNtj3pgFrYcRztfECb 1j6HCibZbAzYtwIBIwJgO8h72WjcmvcpZ8OvHSvTwAguO2TkR6mPgHsgSaKy6GJo PUJnaZRWuba/HX0KGyhz19nPzLpzG5f0fYahlMJAyc13FV7K6kMBPXTRR6FxgHEg L0MPC7cdqAwOVNcPY6A7AjEA1bNaIjOzFN2sfZX0j7OMhQuc4zP7r80zaGc5oy6W p58hRAncFKEvnEq2CeL3vtuZAjEAwNBHpbNsBYTRPCHM7rZuG/iBtwp8Rxhc9I5w ixvzMgi+HpGLWzUIBS+P/XhekIjPAjA285rVmEP+DR255Ls65QbgYhJmTzIXQ2T9 luLvcmFBC6l35Uc4gTgg4ALsmXLn71MCMGMpSWspEvuGInayTCL+vEjmNBT+FAdO W7D4zCpI43jRS9U06JVOeSc9CDk2lwiA3wIwCTB/6uc8Cq85D9YqpM10FuHjKpnP REPPOyrAspdeOAV+6VKRavstea7+2DZmSUgE -END RSA PRIVATE KEY- " Maybe could we generate them once at proxmox side ? ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] applied: [PATCH node_config 1/1] node_config: Allow leading underscore in ACME aliases
applied with rename follow-up, thanks! On June 22, 2020 12:10 pm, Fabian Möller wrote: > --- > PVE/NodeConfig.pm | 12 +++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git a/PVE/NodeConfig.pm b/PVE/NodeConfig.pm > index ad49e288..017f6b30 100644 > --- a/PVE/NodeConfig.pm > +++ b/PVE/NodeConfig.pm > @@ -25,6 +25,16 @@ PVE::JSONSchema::register_format('pve-acme-domain', sub { > die "value '$domain' does not look like a valid domain name!\n"; > }); > > +PVE::JSONSchema::register_format('pve-acme-alias', sub { > +my ($domain, $noerr) = @_; > + > +my $label = qr/[a-z0-9_][a-z0-9_-]*/i; > + > +return $domain if $domain =~ /^$label(?:\.$label)+$/; > +return undef if $noerr; > +die "value '$domain' does not look like a valid domain name!\n"; > +}); > + > sub config_file { > my ($node) = @_; > > @@ -107,7 +117,7 @@ my $acme_domain_desc = { > }, > alias => { > type => 'string', > - format => 'pve-acme-domain', > + format => 'pve-acme-alias', > format_description => 'domain', > description => 'Alias for the Domain to verify ACME Challenge over DNS', > optional => 1, > -- > 2.27.0 > > ___ > pve-devel mailing list > pve-devel@pve.proxmox.com > https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel > > ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
Re: [pve-devel] cloudinit: generate server ssh keys on proxmox side ?
> Maybe could we generate them once at proxmox side ? -1 Copying private keys is bad ... ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] [PATCH v2 node_config 1/1] node_config: Allow leading underscore in ACME aliases
--- PVE/NodeConfig.pm | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/PVE/NodeConfig.pm b/PVE/NodeConfig.pm index ad49e288..c16e455f 100644 --- a/PVE/NodeConfig.pm +++ b/PVE/NodeConfig.pm @@ -25,6 +25,16 @@ PVE::JSONSchema::register_format('pve-acme-domain', sub { die "value '$domain' does not look like a valid domain name!\n"; }); +PVE::JSONSchema::register_format('pve-acme-alias', sub { +my ($alias, $noerr) = @_; + +my $label = qr/[a-z0-9_][a-z0-9_-]*/i; + +return $alias if $alias =~ /^$label(?:\.$label)+$/; +return undef if $noerr; +die "value '$alias' does not look like a valid domain alias!\n"; +}); + sub config_file { my ($node) = @_; @@ -107,7 +117,7 @@ my $acme_domain_desc = { }, alias => { type => 'string', - format => 'pve-acme-domain', + format => 'pve-acme-alias', format_description => 'domain', description => 'Alias for the Domain to verify ACME Challenge over DNS', optional => 1, -- 2.27.0 ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] [PATCH v2 node_config 0/1] node_config: Allow leading underscore in ACME aliases
CLA is signed. Created a v2 with the suggested changes. Fabian Möller (1): node_config: Allow leading underscore in ACME aliases PVE/NodeConfig.pm | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) -- 2.27.0 ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] [PATCH v3 common 1/3] JSONSchema: add format validator support and cleanup check_format
Adds a third, optional parameter to register_format that allows specifying a function that will be called after parsing and can validate the parsed data. A validator should die on failed validation, and can also change the parsed object by returning a modified version of it. This is useful so one can register a format with its hash, thus allowing documentation to be generated automatically, while still enforcing certain validation rules. The validator only needs to be called in parse_property_string, since check_format always calls parse_property_string if there is a possibility of a validator existing at all. parse_property_string should then be called with named formats for best effect, as only then can validators be used. Clean up 'check_format' as well (which pretty much amounts to a rewrite). No existing functionality is intentionally changed. Signed-off-by: Stefan Reiter --- src/PVE/JSONSchema.pm | 87 +++ 1 file changed, 55 insertions(+), 32 deletions(-) diff --git a/src/PVE/JSONSchema.pm b/src/PVE/JSONSchema.pm index 84fb694..f987006 100644 --- a/src/PVE/JSONSchema.pm +++ b/src/PVE/JSONSchema.pm @@ -121,19 +121,26 @@ register_standard_option('pve-snapshot-name', { }); my $format_list = {}; +my $format_validators = {}; sub register_format { -my ($format, $code) = @_; +my ($name, $format, $validator) = @_; -die "JSON schema format '$format' already registered\n" - if $format_list->{$format}; +die "JSON schema format '$name' already registered\n" + if $format_list->{$name}; -$format_list->{$format} = $code; +if ($validator) { + die "A \$validator function can only be specified for hash-based formats\n" + if ref($format) ne 'HASH'; + $format_validators->{$name} = $validator; +} + +$format_list->{$name} = $format; } sub get_format { -my ($format) = @_; -return $format_list->{$format}; +my ($name) = @_; +return $format_list->{$name}; } my $renderer_hash = {}; @@ -647,39 +654,47 @@ sub pve_verify_tfa_secret { sub check_format { my ($format, $value, $path) = @_; -return parse_property_string($format, $value, $path) if ref($format) eq 'HASH'; +if (ref($format) eq 'HASH') { + # hash ref cannot have validator/list/opt handling attached + return parse_property_string($format, $value, $path); +} + +if (ref($format) eq 'CODE') { + # we are the (sole, old-style) validator + return $format->($value); +} + return if $format eq 'regex'; -if ($format =~ m/^(.*)-a?list$/) { +my $parsed; +$format =~ m/^(.*?)(?:-a?(list|opt))?$/; +my ($format_name, $format_type) = ($1, $2 // 'none'); +my $registered = get_format($format_name); +die "undefined format '$format'\n" if !$registered; - my $code = $format_list->{$1}; - - die "undefined format '$format'\n" if !$code; +die "'-$format_type' format must have code ref, not hash\n" + if $format_type ne 'none' && ref($registered) ne 'CODE'; +if ($format_type eq 'list') { # Note: we allow empty lists foreach my $v (split_list($value)) { - &$code($v); + $parsed = $registered->($v); } - -} elsif ($format =~ m/^(.*)-opt$/) { - - my $code = $format_list->{$1}; - - die "undefined format '$format'\n" if !$code; - - return if !$value; # allow empty string - - &$code($value); - +} elsif ($format_type eq 'opt') { + $parsed = $registered->($value) if $value; } else { - - my $code = $format_list->{$format}; - - die "undefined format '$format'\n" if !$code; - - return parse_property_string($code, $value, $path) if ref($code) eq 'HASH'; - &$code($value); + if (ref($registered) eq 'HASH') { + # Note: this is the only case where a validator function could be + # attached, hence it's safe to handle that in parse_property_string. + # We do however have to call it with $format_name instead of + # $registered, so it knows about the name (and thus any validators). + $parsed = parse_property_string($format, $value, $path); + } else { + $parsed = $registered->($value); + } } + +return $parsed; } sub parse_size { @@ -735,9 +750,16 @@ sub parse_property_string { $additional_properties = 0 if !defined($additional_properties); # Support named formats here, too: +my $validator; if (!ref($format)) { - if (my $desc = $format_list->{$format}) { - $format = $desc; + if (my $reg = get_format($format)) { + die "parse_property_string only accepts hash based named formats\n" + if ref($reg) ne 'HASH'; + + # named formats can have validators attached + $validator = $format_validators->{$format}; + + $format = $reg; } else { die "unknown format:
[pve-devel] [PATCH v3 common 2/3] JSONSchema: use validator in print_property_string too
Suggested-by: Fabian Grünbichler Signed-off-by: Stefan Reiter --- src/PVE/JSONSchema.pm | 5 + 1 file changed, 5 insertions(+) diff --git a/src/PVE/JSONSchema.pm b/src/PVE/JSONSchema.pm index f987006..59a2b5a 100644 --- a/src/PVE/JSONSchema.pm +++ b/src/PVE/JSONSchema.pm @@ -1878,9 +1878,12 @@ sub generate_typetext { sub print_property_string { my ($data, $format, $skip, $path) = @_; +my $validator; if (ref($format) ne 'HASH') { my $schema = get_format($format); die "not a valid format: $format\n" if !$schema; + # named formats can have validators attached + $validator = $format_validators->{$format}; $format = $schema; } @@ -1890,6 +1893,8 @@ sub print_property_string { raise "format error", errors => $errors; } +$data = $validator->($data) if $validator; + my ($default_key, $keyAliasProps) = &$find_schema_default_key($format); my $res = ''; -- 2.20.1 ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] [PATCH v3 0/3] Add format validator support
Fixes "cpu" format documentation in man pages by introducing format validators, which allow custom validation functions to be used together with format hashes. The plan is to change occurances of hash based formats in parse_property_string to named formats, so that future validators would be called. Such validators would enable many formats which currently have no representation in the docs to be included there. v2 -> v3: * include fixed followup patch from Fabian v1 -> v2: * Do validation in parse_property_string * Re-refactor check_format based on Fabian's review * Validate "cputype" in "pve-cpu-conf", not "pve-vm-cpu-conf" * Use parse_property_string instead of check_format for parsing in CPUConfig common: Stefan Reiter (2): JSONSchema: add format validator support and cleanup check_format JSONSchema: use validator in print_property_string too src/PVE/JSONSchema.pm | 92 --- 1 file changed, 60 insertions(+), 32 deletions(-) qemu-server: Stefan Reiter (1): fix #2671: include CPU format in man page again PVE/QemuServer/CPUConfig.pm | 56 - 1 file changed, 18 insertions(+), 38 deletions(-) -- 2.20.1 ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] applied: Re: [PATCH pve-manager] sdn: fix zone icon in tree view
On 19.06.20 17:50, Alexandre Derumier wrote: > also add status icon: > -pending (yellow triangle) > -error (red cross) > > Signed-off-by: Alexandre Derumier > --- > www/css/ext6-pve.css | 4 > www/manager6/tree/ResourceTree.js | 4 ++-- > 2 files changed, 6 insertions(+), 2 deletions(-) > > applied, thanks! ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] [PATCH widget-toolkit/manager] move/refactor ZFS related gui components into widget-toolkit
to be used outside of pve includes some refactor/rewriting, but the components are not that big, so it should be rather straightforward manager patches depend on widget-toolkit, but they do not conflict so we could apply manager sometime later proxmox-widget-toolkit: Dominik Csapak (3): Utils: add render_zfs_health add form/MultiDiskSelector add window/ZFSDetail src/Makefile | 2 + src/Utils.js | 25 ++ src/form/MultiDiskSelector.js | 164 ++ src/window/ZFSDetail.js | 152 +++ 4 files changed, 343 insertions(+) create mode 100644 src/form/MultiDiskSelector.js create mode 100644 src/window/ZFSDetail.js pve-manager: Dominik Csapak (1): ui: use ZFS components and functions from widget-toolkit www/manager6/Utils.js| 26 www/manager6/node/ZFS.js | 255 +-- 2 files changed, 6 insertions(+), 275 deletions(-) -- 2.20.1 ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] [PATCH widget-toolkit 3/3] add window/ZFSDetail
inspired by pve's detail window, which used two sub components (ZFSStatus, ZFSDevices; which were never used elsewhere) combined into one self-contained window Signed-off-by: Dominik Csapak --- src/Makefile| 1 + src/window/ZFSDetail.js | 152 2 files changed, 153 insertions(+) create mode 100644 src/window/ZFSDetail.js diff --git a/src/Makefile b/src/Makefile index f4f8bf5..12dda30 100644 --- a/src/Makefile +++ b/src/Makefile @@ -46,6 +46,7 @@ JSSRC=\ window/TaskViewer.js\ window/LanguageEdit.js \ window/DiskSmart.js \ + window/ZFSDetail.js \ node/APT.js \ node/NetworkEdit.js \ node/NetworkView.js \ diff --git a/src/window/ZFSDetail.js b/src/window/ZFSDetail.js new file mode 100644 index 000..8eb6a87 --- /dev/null +++ b/src/window/ZFSDetail.js @@ -0,0 +1,152 @@ +Ext.define('Proxmox.window.ZFSDetail', { +extend: 'Ext.window.Window', +alias: 'widget.pmxZFSDetail', +mixins: ['Proxmox.Mixin.CBind'], + +cbindData: function(initialConfig) { + let me = this; + me.url = `/nodes/${me.nodename}/disks/zfs/${encodeURIComponent(me.zpool)}`; + return { + zpoolUri: `/api2/json/${me.url}`, + title: `${gettext('Status')}: ${me.zpool}`, + }; +}, + +controller: { + xclass: 'Ext.app.ViewController', + + reload: function() { + let me = this; + let view = me.getView(); + me.lookup('status').reload(); + + Proxmox.Utils.API2Request({ + url: `/api2/extjs/${view.url}`, + waitMsgTarget: view, + method: 'GET', + failure: function(response, opts) { + Proxmox.Utils.setErrorMask(view, response.htmlStatus); + }, + success: function(response, opts) { + let devices = me.lookup('devices'); + devices.getSelectionModel().deselectAll(); + devices.setRootNode(response.result.data); + devices.expandAll(); + }, + }); + }, + + init: function(view) { + let me = this; + Proxmox.Utils.monStoreErrors(me, me.lookup('status').getStore().rstore); + me.reload(); + }, +}, + +modal: true, +width: 800, +height: 400, +resizable: true, +cbind: { + title: '{title}', +}, + +layout: { + type: 'vbox', + align: 'stretch', +}, +defaults: { + layout: 'fit', + border: false, +}, + +tbar: [ + { + text: gettext('Reload'), + iconCls: 'fa fa-refresh', + handler: 'reload', + }, +], + +items: [ + { + xtype: 'proxmoxObjectGrid', + reference: 'status', + flex: 0, + cbind: { + url: '{zpoolUri}', + nodename: '{nodename}', + }, + rows: { + scan: { + header: gettext('Scan'), + }, + status: { + header: gettext('Status'), + }, + action: { + header: gettext('Action'), + }, + errors: { + header: gettext('Errors'), + }, + }, + }, + { + xtype: 'treepanel', + reference: 'devices', + title: gettext('Devices'), + stateful: true, + stateId: 'grid-node-zfsstatus', + rootVisible: true, + fields: ['name', 'status', + { + type: 'string', + name: 'iconCls', + calculate: function(data) { + var txt = 'fa x-fa-tree fa-'; + if (data.leaf) { + return txt + 'hdd-o'; + } + return undefined; + }, + }, + ], + sorters: 'name', + flex: 1, + cbind: { + zpool: '{zpoolUri}', + nodename: '{nodename}', + }, + columns: [ + { + xtype: 'treecolumn', + text: gettext('Name'), + dataIndex: 'name', + flex: 1, + }, + { + text: gettext('Health'), + renderer: Proxmox.Utils.render_zfs_health, + dataIndex: 'state', + }, + { + text: 'READ', + dataIndex: 'read', + }, + { + text: 'WRITE', + dataIndex: 'write', + }, +
[pve-devel] [PATCH widget-toolkit 2/3] add form/MultiDiskSelector
from pve's ZFSCreate window, refactored to be self-contained using field mixin, as well as be configureable enough to be used by pve as well as other products Signed-off-by: Dominik Csapak --- src/Makefile | 1 + src/form/MultiDiskSelector.js | 164 ++ 2 files changed, 165 insertions(+) create mode 100644 src/form/MultiDiskSelector.js diff --git a/src/Makefile b/src/Makefile index 3311bbe..f4f8bf5 100644 --- a/src/Makefile +++ b/src/Makefile @@ -30,6 +30,7 @@ JSSRC=\ form/RealmComboBox.js \ form/RoleSelector.js\ form/DiskSelector.js\ + form/MultiDiskSelector.js \ button/Button.js\ button/HelpButton.js\ grid/ObjectGrid.js \ diff --git a/src/form/MultiDiskSelector.js b/src/form/MultiDiskSelector.js new file mode 100644 index 000..9e989a4 --- /dev/null +++ b/src/form/MultiDiskSelector.js @@ -0,0 +1,164 @@ +Ext.define('Proxmox.form.MultiDiskSelector', { +extend: 'Ext.grid.Panel', +alias: 'widget.pmxMultiDiskSelector', + +mixins: { + field: 'Ext.form.field.Field', +}, + +selModel: 'checkboxmodel', + +store: { + data: [], + proxy: { + type: 'proxmox', + }, +}, + +// which field of the disklist is used for getValue +valueField: 'devpath', + +// which parameter is used for the type +typeParameter: 'type', + +// the type of disks to show +diskType: 'unused', + +disks: [], + +allowBlank: false, + +getValue: function() { + let me = this; + return me.disks; +}, + +setValue: function(value) { + let me = this; + + if (!Ext.isArray(value)) { + value = value.split(/;, /); + } + + let store = me.getStore(); + let selection = []; + + let keyField = me.valueField; + + value.forEach(item => { + let rec = store.findRecord(keyField, item, 0, false, true, true); + if (rec) { + selection.push(rec); + } + }); + + me.setSelection(selection); + + return me.mixins.field.setValue.call(me, value); +}, + +getErrors: function(value) { + let me = this; + if (me.allowBlank === false && + me.getSelectionModel().getCount() === 0) { + me.addBodyCls(['x-form-trigger-wrap-default', 'x-form-trigger-wrap-invalid']); + return [gettext('No Disk selected')]; + } + + me.removeBodyCls(['x-form-trigger-wrap-default', 'x-form-trigger-wrap-invalid']); + return []; +}, + +update_disklist: function() { + var me = this; + var disks = me.getSelection(); + + var val = []; + disks.sort(function(a, b) { + var aorder = a.get('order') || 0; + var border = b.get('order') || 0; + return aorder - border; + }); + + disks.forEach(function(disk) { + val.push(disk.get(me.valueField)); + }); + + me.validate(); + me.disks = val; +}, + +columns: [ + { + text: gettext('Device'), + dataIndex: 'devpath', + flex: 2, + }, + { + text: gettext('Model'), + dataIndex: 'model', + flex: 2, + }, + { + text: gettext('Serial'), + dataIndex: 'serial', + flex: 2, + }, + { + text: gettext('Size'), + dataIndex: 'size', + renderer: Proxmox.Utils.format_size, + flex: 1, + }, + { + header: gettext('Order'), + xtype: 'widgetcolumn', + dataIndex: 'order', + sortable: true, + flex: 1, + widget: { + xtype: 'proxmoxintegerfield', + minValue: 1, + isFormField: false, + listeners: { + change: function(numberfield, value, old_value) { + let grid = this.up('pmxMultiDiskSelector'); + var record = numberfield.getWidgetRecord(); + record.set('order', value); + grid.update_disklist(record); + }, + }, + }, + }, +], + +listeners: { + selectionchange: function() { + this.update_disklist(); + }, +}, + +initComponent: function() { + let me = this; + + if (!me.url) { + if (!me.nodename) { + throw "no url or nodename given"; + } + + let node = me.nodename; + let param = me.typeParameter; + let type = me.diskType; + me.url = `/api2/json/nodes/${node}/disks/list?${param}=${type}`; + } + + me.disks = []; + + me.callParent(); + let store = me.getStore(); +
[pve-devel] [PATCH manager 1/1] ui: use ZFS components and functions from widget-toolkit
render_zfs_health is now in widget-toolkit as well as the 'MultiDiskSelector' and the Detailwindow and drop the now unnecessary classes Signed-off-by: Dominik Csapak --- www/manager6/Utils.js| 26 www/manager6/node/ZFS.js | 255 +-- 2 files changed, 6 insertions(+), 275 deletions(-) diff --git a/www/manager6/Utils.js b/www/manager6/Utils.js index 1dae292e..37327ded 100644 --- a/www/manager6/Utils.js +++ b/www/manager6/Utils.js @@ -193,32 +193,6 @@ Ext.define('PVE.Utils', { utilities: { return state; }, -render_zfs_health: function(value) { - if (typeof value == 'undefined'){ - return ""; - } - var iconCls = 'question-circle'; - switch (value) { - case 'AVAIL': - case 'ONLINE': - iconCls = 'check-circle good'; - break; - case 'REMOVED': - case 'DEGRADED': - iconCls = 'exclamation-circle warning'; - break; - case 'UNAVAIL': - case 'FAULTED': - case 'OFFLINE': - iconCls = 'times-circle critical'; - break; - default: //unknown - } - - return ' ' + value; - -}, - get_kvm_osinfo: function(value) { var info = { base: 'Other' }; // default if (value) { diff --git a/www/manager6/node/ZFS.js b/www/manager6/node/ZFS.js index 0b63ccd7..3c83361f 100644 --- a/www/manager6/node/ZFS.js +++ b/www/manager6/node/ZFS.js @@ -19,24 +19,6 @@ Ext.define('PVE.node.CreateZFS', { me.isCreate = true; - var update_disklist = function() { - var grid = me.down('#disklist'); - var disks = grid.getSelection(); - - var val = []; - disks.sort(function(a,b) { - var aorder = a.get('order') || 0; - var border = b.get('order') || 0; - return (aorder - border); - }); - - disks.forEach(function(disk) { - val.push(disk.get('devpath')); - }); - - me.down('field[name=devices]').setValue(val.join(',')); - }; - Ext.apply(me, { url: '/nodes/' + me.nodename + '/disks/zfs', method: 'POST', @@ -47,12 +29,6 @@ Ext.define('PVE.node.CreateZFS', { return values; }, column1: [ - { - xtype: 'textfield', - hidden: true, - name: 'devices', - allowBlank: false - }, { xtype: 'proxmoxtextfield', name: 'name', @@ -106,62 +82,11 @@ Ext.define('PVE.node.CreateZFS', { ], columnB: [ { - xtype: 'grid', + xtype: 'pmxMultiDiskSelector', + name: 'devices', + nodename: me.nodename, height: 200, emptyText: gettext('No Disks unused'), - itemId: 'disklist', - selModel: 'checkboxmodel', - listeners: { - selectionchange: update_disklist - }, - store: { - proxy: { - type: 'proxmox', - url: '/api2/json/nodes/' + me.nodename + '/disks/list?type=unused' - } - }, - columns: [ - { - text: gettext('Device'), - dataIndex: 'devpath', - flex: 2, - }, - { - text: gettext('Model'), - dataIndex: 'model', - flex: 2, - }, - { - text: gettext('Serial'), - dataIndex: 'serial', - flex: 2, - }, - { - text: gettext('Size'), - dataIndex: 'size', - renderer: PVE.Utils.render_size, - flex: 1, - }, - { - header: gettext('Order'), - xtype: 'widgetcolumn', - dataIndex: 'order', -
[pve-devel] [PATCH widget-toolkit 1/3] Utils: add render_zfs_health
from pve-manager Signed-off-by: Dominik Csapak --- src/Utils.js | 25 + 1 file changed, 25 insertions(+) diff --git a/src/Utils.js b/src/Utils.js index b5b1acb..d959dee 100644 --- a/src/Utils.js +++ b/src/Utils.js @@ -740,6 +740,31 @@ utilities: { return Ext.Date.format(servertime, 'Y-m-d H:i:s'); }, +render_zfs_health: function(value) { + if (typeof value === 'undefined') { + return ""; + } + var iconCls = 'question-circle'; + switch (value) { + case 'AVAIL': + case 'ONLINE': + iconCls = 'check-circle good'; + break; + case 'REMOVED': + case 'DEGRADED': + iconCls = 'exclamation-circle warning'; + break; + case 'UNAVAIL': + case 'FAULTED': + case 'OFFLINE': + iconCls = 'times-circle critical'; + break; + default: //unknown + } + + return ' ' + value; +}, + get_help_info: function(section) { let helpMap; if (typeof proxmoxOnlineHelpInfo !== 'undefined') { -- 2.20.1 ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
Re: [pve-devel] [PATCH qemu-server 3/3] fix #2794: allow legacy IGD passthrough
On 6/24/20 9:46 AM, Thomas Lamprecht wrote: Am 6/22/20 um 10:17 AM schrieb Stefan Reiter: @@ -89,7 +97,8 @@ sub get_pci_addr_map { $pci_addr_map = { piix3 => { bus => 0, addr => 1, conflict_ok => qw(ehci) }, ehci => { bus => 0, addr => 1, conflict_ok => qw(piix3) }, # instead of piix3 on arm -vga => { bus => 0, addr => 2 }, +vga => { bus => 0, addr => 2, conflict_ok => qw(legacy-igd) }, sorry, but how do they conflict? the address differs so the check can't hit. Or is this just for documentation purpose? What do you mean the address differs? 'legacy-igd' and 'vga' both share bus 0 addr 2, so without the conflict_ok the 'run_pci_addr_checks.pl' test fails. This is only save because legacy-igd requires vga=none anyway, as documented by the comment below. +'legacy-igd' => { bus => 0, addr => 2, conflict_ok => qw(vga) }, # legacy-igd requires vga=none ignore me, confused with non legacy IGD, sorry. So the only thing left then is the description formatting. Should I send a v2 for that or do you want to do a followup? ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] applied: Re: [PATCH qemu 1/3] fix #2794: Include legacy-igd passthrough fix
On 18.06.20 16:36, Stefan Reiter wrote: > See https://bugs.launchpad.net/qemu/+bug/1882784 > > Signed-off-by: Stefan Reiter > --- > ...ks-Fix-broken-legacy-IGD-passthrough.patch | 34 +++ > debian/patches/series | 1 + > 2 files changed, 35 insertions(+) > create mode 100644 > debian/patches/extra/0001-hw-vfio-pci-quirks-Fix-broken-legacy-IGD-passthrough.patch > > applied, thanks! ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] applied: Re: [PATCH qemu-server 2/3] cfg2cmd: hostpci: move code to PCI.pm
On 18.06.20 16:36, Stefan Reiter wrote: > To avoid further cluttering config_to_command with subsequent changes. > > Signed-off-by: Stefan Reiter > --- > PVE/QemuServer.pm | 170 ++ > PVE/QemuServer/PCI.pm | 170 ++ > 2 files changed, 177 insertions(+), 163 deletions(-) > > applied, thanks! ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] [PATCH v3 qemu-server 3/3] fix #2671: include CPU format in man page again
Use the new register_format(3) call to use a validator (instead of a parser) for 'pve-(vm-)?cpu-conf'. This way the $cpu_fmt hash can be used for generating the documentation, while still applying the same verification rules as before. Since the function no longer parses but only verifies, the parsing in print_cpu_device/get_cpu_options has to go via JSONSchema directly. Signed-off-by: Stefan Reiter --- PVE/QemuServer/CPUConfig.pm | 56 - 1 file changed, 18 insertions(+), 38 deletions(-) diff --git a/PVE/QemuServer/CPUConfig.pm b/PVE/QemuServer/CPUConfig.pm index 6250591..8ed898c 100644 --- a/PVE/QemuServer/CPUConfig.pm +++ b/PVE/QemuServer/CPUConfig.pm @@ -153,6 +153,7 @@ my $cpu_fmt = { 'phys-bits' => { type => 'string', format => 'pve-phys-bits', + format_description => '8-64|host', description => "The physical memory address bits that are reported to" . " the guest OS. Should be smaller or equal to the host's." . " Set to 'host' to use value from host CPU, but note that" @@ -182,57 +183,36 @@ sub parse_phys_bits { # $cpu_fmt describes both the CPU config passed as part of a VM config, as well # as the definition of a custom CPU model. There are some slight differences -# though, which we catch in the custom verification function below. -PVE::JSONSchema::register_format('pve-cpu-conf', \_cpu_conf_basic); -sub parse_cpu_conf_basic { -my ($cpu_str, $noerr) = @_; - -my $cpu = eval { PVE::JSONSchema::parse_property_string($cpu_fmt, $cpu_str) }; -if ($@) { -die $@ if !$noerr; -return undef; -} +# though, which we catch in the custom validation functions below. +PVE::JSONSchema::register_format('pve-cpu-conf', $cpu_fmt, \_cpu_conf); +sub validate_cpu_conf { +my ($cpu) = @_; # required, but can't be forced in schema since it's encoded in section # header for custom models -if (!$cpu->{cputype}) { - die "CPU is missing cputype\n" if !$noerr; - return undef; -} - -return $cpu; +die "CPU is missing cputype\n" if !$cpu->{cputype}; } +PVE::JSONSchema::register_format('pve-vm-cpu-conf', $cpu_fmt, \_vm_cpu_conf); +sub validate_vm_cpu_conf { +my ($cpu) = @_; -PVE::JSONSchema::register_format('pve-vm-cpu-conf', \_vm_cpu_conf); -sub parse_vm_cpu_conf { -my ($cpu_str, $noerr) = @_; - -my $cpu = parse_cpu_conf_basic($cpu_str, $noerr); -return undef if !$cpu; +validate_cpu_conf($cpu); my $cputype = $cpu->{cputype}; # a VM-specific config is only valid if the cputype exists if (is_custom_model($cputype)) { - eval { get_custom_model($cputype); }; - if ($@) { - die $@ if !$noerr; - return undef; - } + # dies on unknown model + get_custom_model($cputype); } else { - if (!defined($cpu_vendor_list->{$cputype})) { - die "Built-in cputype '$cputype' is not defined (missing 'custom-' prefix?)\n" if !$noerr; - return undef; - } + die "Built-in cputype '$cputype' is not defined (missing 'custom-' prefix?)\n" + if !defined($cpu_vendor_list->{$cputype}); } # in a VM-specific config, certain properties are limited/forbidden -if ($cpu->{flags} && $cpu->{flags} !~ m/$cpu_flag_supported_re(;$cpu_flag_supported_re)*/) { - die "VM-specific CPU flags must be a subset of: @{[join(', ', @supported_cpu_flags)]}\n" - if !$noerr; - return undef; -} +die "VM-specific CPU flags must be a subset of: @{[join(', ', @supported_cpu_flags)]}\n" + if ($cpu->{flags} && $cpu->{flags} !~ m/$cpu_flag_supported_re(;$cpu_flag_supported_re)*/); die "Property 'reported-model' not allowed in VM-specific CPU config.\n" if defined($cpu->{'reported-model'}); @@ -369,7 +349,7 @@ sub print_cpu_device { my $kvm = $conf->{kvm} // 1; my $cpu = $kvm ? "kvm64" : "qemu64"; if (my $cputype = $conf->{cpu}) { - my $cpuconf = parse_cpu_conf_basic($cputype) + my $cpuconf = PVE::JSONSchema::parse_property_string('pve-vm-cpu-conf', $cputype) or die "Cannot parse cpu description: $cputype\n"; $cpu = $cpuconf->{cputype}; @@ -481,7 +461,7 @@ sub get_cpu_options { my $custom_cpu; my $hv_vendor_id; if (my $cpu_prop_str = $conf->{cpu}) { - $cpu = parse_vm_cpu_conf($cpu_prop_str) + $cpu = PVE::JSONSchema::parse_property_string('pve-vm-cpu-conf', $cpu_prop_str) or die "Cannot parse cpu description: $cpu_prop_str\n"; $cputype = $cpu->{cputype}; -- 2.20.1 ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] applied: Re: [PATCH qemu-server 3/3] fix #2794: allow legacy IGD passthrough
On 18.06.20 16:36, Stefan Reiter wrote: > Legacy IGD passthrough requires address 00:1f.0 to not be assigned to > anything on QEMU startup (currently it's assigned to bridge pci.2). > Changing this in general would break live-migration, so introduce a new > hostpci parameter "legacy-igd", which if set to 1 will move that bridge > to be nested under bridge 1. > > This is safe because: > * Bridge 1 is unconditionally created on i440fx, so nesting is ok > * Defaults are not changed, i.e. PCI layout only changes when the new > parameter is specified manually > * hostpci forbids migration anyway > > Additionally, the PT device has to be assigned address 00:02.0 in the > guest as well, which is usually used for VGA assignment. Luckily, IGD PT > requires vga=none, so that is not an issue either. > > See https://git.qemu.org/?p=qemu.git;a=blob;f=docs/igd-assign.txt > > Signed-off-by: Stefan Reiter > --- > PVE/QemuServer.pm | 10 -- > PVE/QemuServer/PCI.pm | 45 +-- > 2 files changed, 47 insertions(+), 8 deletions(-) > > applied, thanks! Fixed up some formatting and general indentation issues in that file. ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
Re: [pve-devel] cloudinit: generate server ssh keys on proxmox side ?
> Maybe could we generate them once at proxmox side ? >>-1 >> >>Copying private keys is bad ... I'll look if I can make sshkey gen occur only once, or simply chattr files it's possible to configure cloudinit modules, to launch only [once,instance,always]. by default, almost all modules run only 1 by instance, but as we recreate an instance each time, they are reapplying again. and the network configuration is not done in a module, so the only way is really a new instance each time. in /etc/cloud/cloud.cfg " cloud_init_modules: - ssh " -> " cloud_init_modules: - [ssh, once ] " Like this, it's creating a .sem file in /var/lib/cloud/sem/ instead /var/lib/cloud/instance/sem/ So, I think it'll not regenerate ssh config again again. BTW, I'm able to apply configuration change live, without need reboot, with a simple udev rule /etc/udev/rules.d/90-cloudinit.rules ACTION=="change", SUBSYSTEM=="block", KERNEL=="sr[0-9]*", ENV{ID_FS_LABEL}=="cidata", RUN+="/usr/local/bin/cloudinit-reload.sh" and /usr/local/bin/cloudinit-reload.sh -- rm /var/lib/cloud/instance systemctl restart cloud-init systemctl reload networking I think I'll write some tuning docs, it could be very helpfull for users. - Mail original - De: "dietmar" À: "pve-devel" Envoyé: Jeudi 25 Juin 2020 11:00:10 Objet: Re: [pve-devel] cloudinit: generate server ssh keys on proxmox side ? > Maybe could we generate them once at proxmox side ? -1 Copying private keys is bad ... ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] applied widget-toolkit: [PATCH widget-toolkit/manager] move/refactor ZFS related gui components into widget-toolkit
On 25.06.20 13:59, Dominik Csapak wrote: > to be used outside of pve > includes some refactor/rewriting, but the components are not that big, > so it should be rather straightforward > > manager patches depend on widget-toolkit, but they do not conflict > so we could apply manager sometime later > > proxmox-widget-toolkit: > > Dominik Csapak (3): > Utils: add render_zfs_health > add form/MultiDiskSelector > add window/ZFSDetail > > src/Makefile | 2 + > src/Utils.js | 25 ++ > src/form/MultiDiskSelector.js | 164 ++ > src/window/ZFSDetail.js | 152 +++ > 4 files changed, 343 insertions(+) > create mode 100644 src/form/MultiDiskSelector.js > create mode 100644 src/window/ZFSDetail.js > > pve-manager: > > Dominik Csapak (1): > ui: use ZFS components and functions from widget-toolkit > > www/manager6/Utils.js| 26 > www/manager6/node/ZFS.js | 255 +-- > 2 files changed, 6 insertions(+), 275 deletions(-) > applied the widget toolkit patches. ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
[pve-devel] applied: Re: [PATCH pve-network] improve status
On 19.06.20 13:47, Alexandre Derumier wrote: > check all plumbing interfaces needed for vnets > > Signed-off-by: Alexandre Derumier > --- > PVE/Network/SDN/Zones.pm| 29 +--- > PVE/Network/SDN/Zones/Plugin.pm | 35 > PVE/Network/SDN/Zones/QinQPlugin.pm | 51 + > PVE/Network/SDN/Zones/VlanPlugin.pm | 47 ++ > 4 files changed, 109 insertions(+), 53 deletions(-) > > applied, thanks! ___ pve-devel mailing list pve-devel@pve.proxmox.com https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel