[pve-devel] [PATCH-SERIES] move jobs from pve-manager

2022-03-22 Thread Hannes Laimer
The VZDump plugin was moved to pve-guest-common because it is used by
both CTs and VMs. Since the Jobs.pm contains helpers that depend on the
VZDump plugin, it was also moved to pve-guest-common. The base jobs
plugin was moved to pve-cluster since it does not really depend on
anything and might be used in many places.

Version bumps are needed.

pve-cluster:

Hannes Laimer (1):
  jobs: move base plugin from pve-manager

 data/PVE/Jobs/Makefile |  11 
 data/PVE/Jobs/Plugin.pm| 101 +
 data/PVE/Makefile  |   2 +-
 debian/pve-cluster.install |   1 +
 4 files changed, 114 insertions(+), 1 deletion(-)
 create mode 100644 data/PVE/Jobs/Makefile
 create mode 100644 data/PVE/Jobs/Plugin.pm


pve-guest-common:

Hannes Laimer (1):
  jobs: move VZDump plugin from pve-manager

 src/Makefile   |   4 +
 src/PVE/Jobs.pm| 282 +
 src/PVE/Jobs/VZDump.pm |  87 +
 3 files changed, 373 insertions(+)
 create mode 100644 src/PVE/Jobs.pm
 create mode 100644 src/PVE/Jobs/VZDump.pm


pve-manager:

Hannes Laimer (1):
  jobs: move to pve-cluster and pve-guest-common

 PVE/Jobs.pm| 282 -
 PVE/Jobs/Makefile  |  16 ---
 PVE/Jobs/Plugin.pm | 101 
 PVE/Jobs/VZDump.pm |  87 --
 PVE/Makefile   |   3 +-
 5 files changed, 1 insertion(+), 488 deletions(-)
 delete mode 100644 PVE/Jobs.pm
 delete mode 100644 PVE/Jobs/Makefile
 delete mode 100644 PVE/Jobs/Plugin.pm
 delete mode 100644 PVE/Jobs/VZDump.pm

-- 
2.30.2



___
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel



[pve-devel] [PATCH pve-guest-common 2/3] jobs: move VZDump plugin from pve-manager

2022-03-22 Thread Hannes Laimer
Signed-off-by: Hannes Laimer 
---
 src/Makefile   |   4 +
 src/PVE/Jobs.pm| 282 +
 src/PVE/Jobs/VZDump.pm |  87 +
 3 files changed, 373 insertions(+)
 create mode 100644 src/PVE/Jobs.pm
 create mode 100644 src/PVE/Jobs/VZDump.pm

diff --git a/src/Makefile b/src/Makefile
index baa2688..853b562 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -9,6 +9,7 @@ install: PVE
install -m 0644 PVE/GuestHelpers.pm ${PERL5DIR}/PVE/
install -m 0644 PVE/AbstractConfig.pm ${PERL5DIR}/PVE/
install -m 0644 PVE/AbstractMigrate.pm ${PERL5DIR}/PVE/
+   install -m 0644 PVE/Jobs.pm ${PERL5DIR}/PVE/
install -m 0644 PVE/ReplicationConfig.pm ${PERL5DIR}/PVE/
install -m 0644 PVE/ReplicationState.pm ${PERL5DIR}/PVE/
install -m 0644 PVE/Replication.pm ${PERL5DIR}/PVE/
@@ -17,6 +18,9 @@ install: PVE
install -d ${PERL5DIR}/PVE/VZDump
install -m 0644 PVE/VZDump/Plugin.pm ${PERL5DIR}/PVE/VZDump/
install -m 0644 PVE/VZDump/Common.pm ${PERL5DIR}/PVE/VZDump/
+   install -d ${PERL5DIR}/PVE/Jobs
+   install -m 0644 PVE/Jobs/VZDump.pm ${PERL5DIR}/PVE/Jobs/
+
 
 .PHONY: check
 check:
diff --git a/src/PVE/Jobs.pm b/src/PVE/Jobs.pm
new file mode 100644
index 000..ba3685e
--- /dev/null
+++ b/src/PVE/Jobs.pm
@@ -0,0 +1,282 @@
+package PVE::Jobs;
+
+use strict;
+use warnings;
+use JSON;
+
+use PVE::Cluster qw(cfs_read_file cfs_lock_file);
+use PVE::Jobs::Plugin;
+use PVE::Jobs::VZDump;
+use PVE::Tools;
+
+PVE::Jobs::VZDump->register();
+PVE::Jobs::Plugin->init();
+
+my $state_dir = "/var/lib/pve-manager/jobs";
+my $lock_dir = "/var/lock/pve-manager";
+
+my $get_state_file = sub {
+my ($jobid, $type) = @_;
+return "$state_dir/$type-$jobid.json";
+};
+
+my $default_state = {
+state => 'created',
+time => 0,
+};
+
+# lockless, since we use file_get_contents, which is atomic
+sub read_job_state {
+my ($jobid, $type) = @_;
+my $path = $get_state_file->($jobid, $type);
+return if ! -e $path;
+
+my $raw = PVE::Tools::file_get_contents($path);
+
+return $default_state if $raw eq '';
+
+# untaint $raw
+if ($raw =~ m/^(\{.*\})$/) {
+   return decode_json($1);
+}
+
+die "invalid json data in '$path'\n";
+}
+
+sub lock_job_state {
+my ($jobid, $type, $sub) = @_;
+
+my $filename = "$lock_dir/$type-$jobid.lck";
+
+my $res = PVE::Tools::lock_file($filename, 10, $sub);
+die $@ if $@;
+
+return $res;
+}
+
+my $get_job_task_status = sub {
+my ($state) = @_;
+
+if (!defined($state->{upid})) {
+   return; # not started
+}
+
+my ($task, $filename) = PVE::Tools::upid_decode($state->{upid}, 1);
+die "unable to parse worker upid - $state->{upid}\n" if !$task;
+die "no such task\n" if ! -f $filename;
+
+my $pstart = PVE::ProcFSTools::read_proc_starttime($task->{pid});
+if ($pstart && $pstart == $task->{pstart}) {
+   return; # still running
+}
+
+return PVE::Tools::upid_read_status($state->{upid});
+};
+
+# checks if the job is already finished if it was started before and
+# updates the statefile accordingly
+sub update_job_stopped {
+my ($jobid, $type) = @_;
+
+# first check unlocked to save time,
+my $state = read_job_state($jobid, $type);
+return if !defined($state) || $state->{state} ne 'started'; # removed or 
not started
+
+if (defined($get_job_task_status->($state))) {
+   lock_job_state($jobid, $type, sub {
+   my $state = read_job_state($jobid, $type);
+   return if !defined($state) || $state->{state} ne 'started'; # 
removed or not started
+
+   my $new_state = {
+   state => 'stopped',
+   msg => $get_job_task_status->($state) // 'internal error',
+   upid => $state->{upid},
+   };
+
+   if ($state->{updated}) { # save updated time stamp
+   $new_state->{updated} = $state->{updated};
+   }
+
+   my $path = $get_state_file->($jobid, $type);
+   PVE::Tools::file_set_contents($path, encode_json($new_state));
+   });
+}
+}
+
+# must be called when the job is first created
+sub create_job {
+my ($jobid, $type) = @_;
+
+lock_job_state($jobid, $type, sub {
+   my $state = read_job_state($jobid, $type) // $default_state;
+
+   if ($state->{state} ne 'created') {
+   die "job state already exists\n";
+   }
+
+   $state->{time} = time();
+
+   my $path = $get_state_file->($jobid, $type);
+   PVE::Tools::file_set_contents($path, encode_json($state));
+});
+}
+
+# to be called when the job is removed
+sub remove_job {
+my ($jobid, $type) = @_;
+my $path = $get_state_file->($jobid, $type);
+unlink $path;
+}
+
+# checks if the job can be started and sets the state to 'starting'
+# returns 1 if the job can be started, 0 otherwise
+sub starting_job {
+my ($jobid, $type) = @_;
+
+# first check unlocked 

[pve-devel] [PATCH pve-cluster 1/3] jobs: move base plugin from pve-manager

2022-03-22 Thread Hannes Laimer
Signed-off-by: Hannes Laimer 
---
 data/PVE/Jobs/Makefile |  11 
 data/PVE/Jobs/Plugin.pm| 101 +
 data/PVE/Makefile  |   2 +-
 debian/pve-cluster.install |   1 +
 4 files changed, 114 insertions(+), 1 deletion(-)
 create mode 100644 data/PVE/Jobs/Makefile
 create mode 100644 data/PVE/Jobs/Plugin.pm

diff --git a/data/PVE/Jobs/Makefile b/data/PVE/Jobs/Makefile
new file mode 100644
index 000..4320369
--- /dev/null
+++ b/data/PVE/Jobs/Makefile
@@ -0,0 +1,11 @@
+PVEDIR=${DESTDIR}/usr/share/perl5/PVE
+
+SOURCES=Plugin.pm
+
+.PHONY: install
+install: ${SOURCES}
+   install -d -m 0755 ${PVEDIR}/Jobs
+   for f in ${SOURCES}; do install -D -m 0644 $$f ${PVEDIR}/Jobs/$$f; done
+
+.PHONY: clean
+clean:
diff --git a/data/PVE/Jobs/Plugin.pm b/data/PVE/Jobs/Plugin.pm
new file mode 100644
index 000..6098360
--- /dev/null
+++ b/data/PVE/Jobs/Plugin.pm
@@ -0,0 +1,101 @@
+package PVE::Jobs::Plugin;
+
+use strict;
+use warnings;
+
+use PVE::Cluster qw(cfs_register_file);
+
+use base qw(PVE::SectionConfig);
+
+cfs_register_file(
+'jobs.cfg',
+ sub { __PACKAGE__->parse_config(@_); },
+ sub { __PACKAGE__->write_config(@_); }
+);
+
+my $defaultData = {
+propertyList => {
+   type => { description => "Section type." },
+   id => {
+   description => "The ID of the VZDump job.",
+   type => 'string',
+   format => 'pve-configid',
+   maxLength => 64,
+   },
+   enabled => {
+   description => "Determines if the job is enabled.",
+   type => 'boolean',
+   default => 1,
+   optional => 1,
+   },
+   schedule => {
+   description => "Backup schedule. The format is a subset of 
`systemd` calendar events.",
+   type => 'string', format => 'pve-calendar-event',
+   maxLength => 128,
+   },
+   comment => {
+   optional => 1,
+   type => 'string',
+   description => "Description for the Job.",
+   maxLength => 512,
+   },
+},
+};
+
+sub private {
+return $defaultData;
+}
+
+sub parse_config {
+my ($class, $filename, $raw) = @_;
+
+my $cfg = $class->SUPER::parse_config($filename, $raw);
+
+foreach my $id (sort keys %{$cfg->{ids}}) {
+   my $data = $cfg->{ids}->{$id};
+
+   $data->{id} = $id;
+   $data->{enabled}  //= 1;
+
+   if (defined($data->{comment})) {
+   $data->{comment} = PVE::Tools::decode_text($data->{comment});
+   }
+   }
+
+   return $cfg;
+}
+
+# call the plugin specific decode/encode code
+sub decode_value {
+my ($class, $type, $key, $value) = @_;
+
+my $plugin = __PACKAGE__->lookup($type);
+return $plugin->decode_value($type, $key, $value);
+}
+
+sub encode_value {
+my ($class, $type, $key, $value) = @_;
+
+my $plugin = __PACKAGE__->lookup($type);
+return $plugin->encode_value($type, $key, $value);
+}
+
+sub write_config {
+my ($class, $filename, $cfg) = @_;
+
+for my $job (values $cfg->{ids}->%*) {
+   if (defined($job->{comment})) {
+   $job->{comment} = PVE::Tools::encode_text($job->{comment});
+   }
+}
+
+$class->SUPER::write_config($filename, $cfg);
+}
+
+sub run {
+my ($class, $cfg) = @_;
+# implement in subclass
+die "not implemented";
+}
+
+1;
diff --git a/data/PVE/Makefile b/data/PVE/Makefile
index 8ea5383..eecf9f9 100644
--- a/data/PVE/Makefile
+++ b/data/PVE/Makefile
@@ -10,7 +10,7 @@ PVE_VENDORARCH=${DESTDIR}/${PERL_VENDORARCH}/auto/PVE/IPCC
 
 PERL_DOC_INC_DIRS:=..
 
-SUBDIRS=Cluster CLI API2
+SUBDIRS=Cluster CLI API2 Jobs
 SOURCES=IPCC.pm Cluster.pm Corosync.pm RRD.pm DataCenterConfig.pm SSHInfo.pm
 
 all:
diff --git a/debian/pve-cluster.install b/debian/pve-cluster.install
index f66cd06..eb15b55 100644
--- a/debian/pve-cluster.install
+++ b/debian/pve-cluster.install
@@ -3,6 +3,7 @@ usr/bin/create_pmxcfs_db
 usr/bin/pmxcfs
 usr/lib/
 usr/share/man/man8/pmxcfs.8
+usr/share/perl5/PVE/Jobs/Plugin.pm
 usr/share/perl5/PVE/Cluster.pm
 usr/share/perl5/PVE/Cluster/IPCConst.pm
 usr/share/perl5/PVE/IPCC.pm
-- 
2.30.2



___
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel



[pve-devel] [PATCH pve-manager 3/3] jobs: move to pve-cluster and pve-guest-common

2022-03-22 Thread Hannes Laimer
Signed-off-by: Hannes Laimer 
---
 PVE/Jobs.pm| 282 -
 PVE/Jobs/Makefile  |  16 ---
 PVE/Jobs/Plugin.pm | 101 
 PVE/Jobs/VZDump.pm |  87 --
 PVE/Makefile   |   3 +-
 5 files changed, 1 insertion(+), 488 deletions(-)
 delete mode 100644 PVE/Jobs.pm
 delete mode 100644 PVE/Jobs/Makefile
 delete mode 100644 PVE/Jobs/Plugin.pm
 delete mode 100644 PVE/Jobs/VZDump.pm

diff --git a/PVE/Jobs.pm b/PVE/Jobs.pm
deleted file mode 100644
index ba3685ec..
--- a/PVE/Jobs.pm
+++ /dev/null
@@ -1,282 +0,0 @@
-package PVE::Jobs;
-
-use strict;
-use warnings;
-use JSON;
-
-use PVE::Cluster qw(cfs_read_file cfs_lock_file);
-use PVE::Jobs::Plugin;
-use PVE::Jobs::VZDump;
-use PVE::Tools;
-
-PVE::Jobs::VZDump->register();
-PVE::Jobs::Plugin->init();
-
-my $state_dir = "/var/lib/pve-manager/jobs";
-my $lock_dir = "/var/lock/pve-manager";
-
-my $get_state_file = sub {
-my ($jobid, $type) = @_;
-return "$state_dir/$type-$jobid.json";
-};
-
-my $default_state = {
-state => 'created',
-time => 0,
-};
-
-# lockless, since we use file_get_contents, which is atomic
-sub read_job_state {
-my ($jobid, $type) = @_;
-my $path = $get_state_file->($jobid, $type);
-return if ! -e $path;
-
-my $raw = PVE::Tools::file_get_contents($path);
-
-return $default_state if $raw eq '';
-
-# untaint $raw
-if ($raw =~ m/^(\{.*\})$/) {
-   return decode_json($1);
-}
-
-die "invalid json data in '$path'\n";
-}
-
-sub lock_job_state {
-my ($jobid, $type, $sub) = @_;
-
-my $filename = "$lock_dir/$type-$jobid.lck";
-
-my $res = PVE::Tools::lock_file($filename, 10, $sub);
-die $@ if $@;
-
-return $res;
-}
-
-my $get_job_task_status = sub {
-my ($state) = @_;
-
-if (!defined($state->{upid})) {
-   return; # not started
-}
-
-my ($task, $filename) = PVE::Tools::upid_decode($state->{upid}, 1);
-die "unable to parse worker upid - $state->{upid}\n" if !$task;
-die "no such task\n" if ! -f $filename;
-
-my $pstart = PVE::ProcFSTools::read_proc_starttime($task->{pid});
-if ($pstart && $pstart == $task->{pstart}) {
-   return; # still running
-}
-
-return PVE::Tools::upid_read_status($state->{upid});
-};
-
-# checks if the job is already finished if it was started before and
-# updates the statefile accordingly
-sub update_job_stopped {
-my ($jobid, $type) = @_;
-
-# first check unlocked to save time,
-my $state = read_job_state($jobid, $type);
-return if !defined($state) || $state->{state} ne 'started'; # removed or 
not started
-
-if (defined($get_job_task_status->($state))) {
-   lock_job_state($jobid, $type, sub {
-   my $state = read_job_state($jobid, $type);
-   return if !defined($state) || $state->{state} ne 'started'; # 
removed or not started
-
-   my $new_state = {
-   state => 'stopped',
-   msg => $get_job_task_status->($state) // 'internal error',
-   upid => $state->{upid},
-   };
-
-   if ($state->{updated}) { # save updated time stamp
-   $new_state->{updated} = $state->{updated};
-   }
-
-   my $path = $get_state_file->($jobid, $type);
-   PVE::Tools::file_set_contents($path, encode_json($new_state));
-   });
-}
-}
-
-# must be called when the job is first created
-sub create_job {
-my ($jobid, $type) = @_;
-
-lock_job_state($jobid, $type, sub {
-   my $state = read_job_state($jobid, $type) // $default_state;
-
-   if ($state->{state} ne 'created') {
-   die "job state already exists\n";
-   }
-
-   $state->{time} = time();
-
-   my $path = $get_state_file->($jobid, $type);
-   PVE::Tools::file_set_contents($path, encode_json($state));
-});
-}
-
-# to be called when the job is removed
-sub remove_job {
-my ($jobid, $type) = @_;
-my $path = $get_state_file->($jobid, $type);
-unlink $path;
-}
-
-# checks if the job can be started and sets the state to 'starting'
-# returns 1 if the job can be started, 0 otherwise
-sub starting_job {
-my ($jobid, $type) = @_;
-
-# first check unlocked to save time
-my $state = read_job_state($jobid, $type);
-return 0 if !defined($state) || $state->{state} eq 'started'; # removed or 
already started
-
-lock_job_state($jobid, $type, sub {
-   my $state = read_job_state($jobid, $type);
-   return 0 if !defined($state) || $state->{state} eq 'started'; # removed 
or already started
-
-   my $new_state = {
-   state => 'starting',
-   time => time(),
-   };
-
-   my $path = $get_state_file->($jobid, $type);
-   PVE::Tools::file_set_contents($path, encode_json($new_state));
-});
-return 1;
-}
-
-sub started_job {
-my ($jobid, $type, $upid, $msg) = @_;
-
-lock_job_state($jobid, $type, sub {
-   my $state = read_job_state($jobid, $type);
-

Re: [pve-devel] [PATCH storage 1/4] check volume access: allow if user has VM.Config.Disk

2022-03-22 Thread Fabian Ebner
Am 21.03.22 um 14:06 schrieb Fabian Ebner:
> Listing guest images should not require Datastore.Allocate in this
> case. In preparation for adding disk import to the GUI.
> 
> Signed-off-by: Fabian Ebner 
> ---
>  PVE/Storage.pm | 2 ++
>  1 file changed, 2 insertions(+)
> 
> diff --git a/PVE/Storage.pm b/PVE/Storage.pm
> index 6112991..efa304a 100755
> --- a/PVE/Storage.pm
> +++ b/PVE/Storage.pm
> @@ -486,6 +486,8 @@ sub check_volume_access {
>   } elsif ($vtype eq 'backup' && $ownervm) {
>   $rpcenv->check($user, "/storage/$sid", ['Datastore.AllocateSpace']);
>   $rpcenv->check($user, "/vms/$ownervm", ['VM.Backup']);
> + } elsif (($vtype eq 'images' || $vtype eq 'rootdir') && $ownervm) {
> + $rpcenv->check($user, "/vms/$ownervm", ['VM.Config.Disk']);

Of course this needs to be or-ed with the Datastore.Allocate privilege.
Will fix it in v2.

>   } else {
>   # allow if we are Datastore administrator
>   $rpcenv->check($user, "/storage/$sid", ['Datastore.Allocate']);


___
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel



Re: [pve-devel] [PATCH manager 1/5 v2] Storage GUI: Rewrite backup content view as TreePanel.

2022-03-22 Thread Fabian Ebner
Nit: for the commit title, prefixing like "ui: storage:" is preferred.

I really think we should start with the tree fully expanded, or we will
get shouted at by users relying on notes to find their backups ;)

@Thomas: The backups are now ordered ascending by date again. In PBS
it's also like that. Should that be changed or do we switch back in PVE?

Am 18.03.22 um 14:52 schrieb Matthias Heiserer:
> +Ext.define('PVE.storage.BackupView', {
> +extend: 'Ext.tree.Panel',
>  alias: 'widget.pveStorageBackupView',
> +mixins: ['Proxmox.Mixin.CBind'],
> +rootVisible: false,
>  
> -showColumns: ['name', 'notes', 'protected', 'date', 'format', 'size'],
> +title: gettext('Content'),
>  
> -initComponent: function() {
> - var me = this;
> +cbindData: function(initialCfg) {
> + this.isPBS = initialCfg.pluginType === 'pbs';

That's part of what cbind should do for you if you return { isPBS: ...
}, and that's how it should be used to avoid breaking the abstraction.

But since the storage can change (in the guest backup view) this should
rather be a normal bind and be updated there.

> + return {};
> +},
> +isStorage: false,

Doesn't seem to be used.

>  
> - var nodename = me.nodename = me.pveSelNode.data.node;
> - if (!nodename) {
> - throw "no node name specified";
> - }
> +controller: {
> + xclass: 'Ext.app.ViewController',
>  
> - var storage = me.storage = me.pveSelNode.data.storage;
> - if (!storage) {
> - throw "no storage ID specified";
> - }
> + groupnameHelper: function(item) {

Nit: IMHO something like getGroupName() would be a bit more readable at
the call sites.

> + if (item.vmid) {
> + return PVE.Utils.get_backup_type(item.volid, item.format) + 
> `/${item.vmid}`;
> + } else {
> + return 'Other';
> + }
> + },
>  
> - me.content = 'backup';
> + init: function(view) {
> + let me = this;
> + me.storage = view?.pveSelNode?.data?.storage;

Nit: here you use ?., but below you assume it's set (which I suppose we
can).

> + me.nodename = view.nodename || view.pveSelNode.data.node;

Is there ever a case where it's not the selected node?

> + me.vmid = view.pveSelNode.data.vmid;
> + me.vmtype = view.pveSelNode.data.type;
>  
> - var sm = me.sm = Ext.create('Ext.selection.RowModel', {});
> + me.store = Ext.create('Ext.data.Store', {
> + model: 'PVE.storage.BackupModel',
> + });
> + me.store.on('load', me.onLoad, me);
> + view.getStore().setConfig('filterer', 'bottomup');
> + view.getStore().setSorters(['text']);
>  
> - var reload = function() {
> - me.store.load();
> - };
> + if (me.vmid) {
> + me.getView().getStore().filter({
> + property: 'vmid',
> + value: me.vmid,
> + exactMatch: true,
> + });
> + } else {
> + me.lookup('storagesel').setVisible(false);
> + me.lookup('backupNowButton').setVisible(false);
> + }
> + Proxmox.Utils.monStoreErrors(view, me.store);
> + },
>  
> - let pruneButton = Ext.create('Proxmox.button.Button', {
> - text: gettext('Prune group'),
> - disabled: true,
> - selModel: sm,
> - setBackupGroup: function(backup) {
> - if (backup) {
> - let name = backup.text;
> - let vmid = backup.vmid;
> - let format = backup.format;
> + onLoad: function(store, records, success, operation) {
> + let me = this;
> + let view = me.getView();
> + let selection = view.getSelection()?.[0];
> + selection = selection?.parentNode?.data?.text 
> +selection?.data?.volid;

Style nit: missing space after + and could use `${...}${...}` syntax
instead.

(...)

> + if (selection) {
> + let rootnode = view.getRootNode();
> + let selected;
> + rootnode.cascade(node => {
> + if (selected) {return false;} // skip if already found

Style nit: if body on the same line

> + let id = node.parentNode?.data?.text + node.data?.volid;
> + if (id === selection) {
> + selected = node;
> + return false;
> + }
> + return true;
>   });
> - win.show();
> - win.on('destroy', reload);
> - },
> - });
> + view.setSelection(selected);
> + view.getView().focusRow(selected);

After removing a backup I get a
  Uncaught TypeError: node is undefined
referencing this line.

> + }
> + Proxmox.Utils.setErrorMask(view, false);
> + },
>  

(...)

> +
> + removeHandler: function(button, event, rec) {
> + let me = this;
> + const volid = rec.data.volid;
>

Re: [pve-devel] [PATCH manager 3/5 v2] Backup GUI: Use the new storage/BackupView instead of grid/BackupView.

2022-03-22 Thread Fabian Ebner
There's certain things that need to be changed to not break existing
work flows:

* Restoring doesn't overwrite the existing guest anymore and can't be
used for that anymore.
* Should not only filter by ID, but by type + ID.
* Cannot get rid of the ID filtering anymore. Currently, it always
filters by type, so we might want to keep that behavior.

Nit: introducing the guest-view specific functionality to the BackupView
class could've been part of this patch (or its own preparatory one), but
not sure if it's worth the effort (anymore).

Am 18.03.22 um 14:52 schrieb Matthias Heiserer:
> Signed-off-by: Matthias Heiserer 
> ---
>  www/manager6/lxc/Config.js  | 2 +-
>  www/manager6/qemu/Config.js | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/www/manager6/lxc/Config.js b/www/manager6/lxc/Config.js
> index 89b59c9b..242780c8 100644
> --- a/www/manager6/lxc/Config.js
> +++ b/www/manager6/lxc/Config.js
> @@ -256,7 +256,7 @@ Ext.define('PVE.lxc.Config', {
>   me.items.push({
>   title: gettext('Backup'),
>   iconCls: 'fa fa-floppy-o',
> - xtype: 'pveBackupView',
> + xtype: 'pveStorageBackupView',
>   itemId: 'backup',
>   },
>   {
> diff --git a/www/manager6/qemu/Config.js b/www/manager6/qemu/Config.js
> index 9fe933df..3ed2427a 100644
> --- a/www/manager6/qemu/Config.js
> +++ b/www/manager6/qemu/Config.js
> @@ -291,7 +291,7 @@ Ext.define('PVE.qemu.Config', {
>   me.items.push({
>   title: gettext('Backup'),
>   iconCls: 'fa fa-floppy-o',
> - xtype: 'pveBackupView',
> + xtype: 'pveStorageBackupView',
>   itemId: 'backup',
>   },
>   {


___
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel



Re: [pve-devel] [PATCH manager 4/5 v2] Remove grid/backupview as it got replaced by storage/backupview

2022-03-22 Thread Fabian Ebner
Am 18.03.22 um 14:52 schrieb Matthias Heiserer:
> Signed-off-by: Matthias Heiserer 
> ---
>  www/manager6/grid/BackupView.js | 388 
>  1 file changed, 388 deletions(-)
>  delete mode 100644 www/manager6/grid/BackupView.js
> 

Also needs to remove it from the Makefile or the package won't build
anymore.


___
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel



Re: [pve-devel] [PATCH manager 5/5 v2] Storage ContentView: Remove dead code

2022-03-22 Thread Fabian Ebner
Am 18.03.22 um 14:52 schrieb Matthias Heiserer:
> These lines were only used by grid/BackupView, which gets deleted in
> this series.
>  
>  
> Signed-off-by: Matthias Heiserer 
> ---
>  www/manager6/storage/ContentView.js | 22 ++
>  1 file changed, 2 insertions(+), 20 deletions(-)
> 
> diff --git a/www/manager6/storage/ContentView.js 
> b/www/manager6/storage/ContentView.js
> index 2874b71e..cb22ab4d 100644
> --- a/www/manager6/storage/ContentView.js
> +++ b/www/manager6/storage/ContentView.js
> @@ -155,20 +155,6 @@ Ext.define('PVE.storage.ContentView', {
>   renderer: PVE.Utils.render_storage_content,
>   dataIndex: 'text',
>   },
> - 'notes': {
> - header: gettext('Notes'),
> - flex: 1,
> - renderer: Ext.htmlEncode,
> - dataIndex: 'notes',
> - },
> - 'protected': {
> - header: ``,
> - tooltip: gettext('Protected'),
> - width: 30,
> - renderer: v => v ? ` class="fa fa-shield">` : '',
> - sorter: (a, b) => (b.data.protected || 0) - (a.data.protected 
> || 0),
> - dataIndex: 'protected',
> - },
>   'date': {
>   header: gettext('Date'),
>   width: 150,
> @@ -194,10 +180,6 @@ Ext.define('PVE.storage.ContentView', {
>   delete availableColumns[key];
>   }

>From a quick look, the showColumns special casing right above here seems
to also be unnecessary now.

>   });
> -
> - if (me.extraColumns && typeof me.extraColumns === 'object') {
> - Object.assign(availableColumns, me.extraColumns);
> - }
>   const columns = Object.values(availableColumns);
>  
>   Ext.apply(me, {
> @@ -216,8 +198,8 @@ Ext.define('PVE.storage.ContentView', {
>  Ext.define('pve-storage-content', {
>   extend: 'Ext.data.Model',
>   fields: [
> - 'volid', 'content', 'format', 'size', 'used', 'vmid',
> - 'channel', 'id', 'lun', 'notes', 'verification',
> + 'volid', 'content', 'format', 'size', 'used',
> + 'channel', 'id', 'lun',
>   {
>   name: 'text',
>   convert: function(value, record) {


___
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel



Re: [pve-devel] [PATCH storage 1/4] check volume access: allow if user has VM.Config.Disk

2022-03-22 Thread Fabian Ebner
Am 22.03.22 um 09:31 schrieb Fabian Ebner:
> Am 21.03.22 um 14:06 schrieb Fabian Ebner:
>> Listing guest images should not require Datastore.Allocate in this
>> case. In preparation for adding disk import to the GUI.
>>
>> Signed-off-by: Fabian Ebner 
>> ---
>>  PVE/Storage.pm | 2 ++
>>  1 file changed, 2 insertions(+)
>>
>> diff --git a/PVE/Storage.pm b/PVE/Storage.pm
>> index 6112991..efa304a 100755
>> --- a/PVE/Storage.pm
>> +++ b/PVE/Storage.pm
>> @@ -486,6 +486,8 @@ sub check_volume_access {
>>  } elsif ($vtype eq 'backup' && $ownervm) {
>>  $rpcenv->check($user, "/storage/$sid", ['Datastore.AllocateSpace']);
>>  $rpcenv->check($user, "/vms/$ownervm", ['VM.Backup']);

@Fabian G. should access to backups also be allowed if the user /just/
has Datastore.Allocate?

Otherwise, backups cannot be listed or removed (there is a separate
check, but works similarly) and attributes cannot be changed by a
supposedly high-privileged user.

On the other hand, we also use this check for extractconfig, where it
makes sense to be limited to users with VM.Backup, but could be changed
at the call site of course.

>> +} elsif (($vtype eq 'images' || $vtype eq 'rootdir') && $ownervm) {
>> +$rpcenv->check($user, "/vms/$ownervm", ['VM.Config.Disk']);
> 
> Of course this needs to be or-ed with the Datastore.Allocate privilege.
> Will fix it in v2.
> 
>>  } else {
>>  # allow if we are Datastore administrator
>>  $rpcenv->check($user, "/storage/$sid", ['Datastore.Allocate']);
> 
> 
> ___
> pve-devel mailing list
> pve-devel@lists.proxmox.com
> https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel
> 
> 


___
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel



[pve-devel] [PATCH v2 proxmox-openid-rs] add http proxy support

2022-03-22 Thread Mira Limbeck
ureq has support for a HTTP proxy, but no support for HTTPS proxy yet.
ureq doesn't query `all_proxy` and `ALL_PROXY` environment variables by
itself, the way curl does. So set the proxy in code if any of the above
environment variables are set.

Signed-off-by: Mira Limbeck 
---
v2:
 - changed from multiple branches to 'or_else' as the body was the same
   in both cases

 src/http_client.rs | 12 +---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/src/http_client.rs b/src/http_client.rs
index 5cceafb..9f9e986 100644
--- a/src/http_client.rs
+++ b/src/http_client.rs
@@ -40,9 +40,15 @@ pub enum Error {
 }
 
 fn ureq_agent() -> Result {
-Ok(ureq::AgentBuilder::new()
-.tls_connector(Arc::new(native_tls::TlsConnector::new()?))
-.build())
+let mut agent = 
+
ureq::AgentBuilder::new().tls_connector(Arc::new(native_tls::TlsConnector::new()?));
+if let Ok(val) = std::env::var("all_proxy").or_else(|_| 
std::env::var("ALL_PROXY")) {
+let proxy = ureq::Proxy::new(val).map_err(Box::new)?;
+agent = agent.proxy(proxy);
+}
+
+
+Ok(agent.build())
 }
 
 ///
-- 
2.30.2



___
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel



[pve-devel] applied: [PATCH v2 proxmox-openid-rs] add http proxy support

2022-03-22 Thread Thomas Lamprecht
On 22.03.22 10:41, Mira Limbeck wrote:
> ureq has support for a HTTP proxy, but no support for HTTPS proxy yet.
> ureq doesn't query `all_proxy` and `ALL_PROXY` environment variables by
> itself, the way curl does. So set the proxy in code if any of the above
> environment variables are set.
> 
> Signed-off-by: Mira Limbeck 
> ---
> v2:
>  - changed from multiple branches to 'or_else' as the body was the same
>in both cases
> 
>  src/http_client.rs | 12 +---
>  1 file changed, 9 insertions(+), 3 deletions(-)
> 
>

applied, thanks!


___
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel



Re: [pve-devel] [PATCH v4 manager 2/6] ui: lxc/qemu: add disk reassign and action submenu

2022-03-22 Thread Fabian Ebner
Am 14.03.22 um 10:35 schrieb Aaron Lauterer:
> @@ -227,14 +246,34 @@ Ext.define('PVE.lxc.RessourceView', {
>   },
>   });
>  
> - var move_btn = new Proxmox.button.Button({
> + let reassign_menuitem = new Ext.menu.Item({
> + text: gettext('Reassign Volume'),
> + tooltip: gettext('Reassign volume to another CT'),


Nit: if there is a tooltip for reassign maybe there should also be one
for move? Otherwise, it feels inconsistent from the perspective of a new
user ;) Same for VMs.

> + handler: run_reassign,
> + reference: 'reassing_item',
> + disabled: true,
> + });
> +
> + let move_menuitem = new Ext.menu.Item({
>   text: gettext('Move Volume'),
>   selModel: me.selModel,
>   disabled: true,
> - dangerous: true,
>   handler: run_move,
>   });
>  

(...)

> @@ -265,9 +305,12 @@ Ext.define('PVE.lxc.RessourceView', {
>   }
>   edit_btn.setDisabled(noedit);
>  
> - remove_btn.setDisabled(!isDisk || rec.data.key === 'rootfs' || 
> !diskCap || pending);
> - resize_btn.setDisabled(!isDisk || !diskCap || isUnusedDisk);
> - move_btn.setDisabled(!isDisk || !diskCap);
> + volumeaction_btn.setDisabled(!isDisk);

Shouldn't this also check for diskCap?

> + reassign_menuitem.setDisabled(isRootFS);
> +
> + remove_btn.setDisabled(!isDisk || isRootFS || !diskCap || pending);
> + resize_menuitem.setDisabled(!isDisk || !diskCap || isUnusedDisk);
> + move_menuitem.setDisabled(!isDisk || !diskCap);

Nit: please group the menu and menuitems together. And since the whole
menu is disabled if !isDisk, you don't need to repeat that for the
menuitems (like you already don't for reassign ;)).

>   revert_btn.setDisabled(!pending);
>  
>   remove_btn.setText(isUsedDisk ? remove_btn.altText : 
> remove_btn.defaultText);

(...)

> diff --git a/www/manager6/qemu/HardwareView.js 
> b/www/manager6/qemu/HardwareView.js
> index 6cea4287..af84fb3f 100644
> --- a/www/manager6/qemu/HardwareView.js
> +++ b/www/manager6/qemu/HardwareView.js
> @@ -400,8 +400,8 @@ Ext.define('PVE.qemu.HardwareView', {
>   win.on('destroy', me.reload, me);
>   };
>  
> - var run_move = function() {
> - var rec = sm.getSelection()[0];
> + let run_move = function() {
> + let rec = sm.getSelection()[0];
>   if (!rec) {
>   return;
>   }

Nit: While it is an improvement, it doesn't actually interact with
anything else in the patch, and hence doesn't really belong here.

(...)

> @@ -611,9 +648,15 @@ Ext.define('PVE.qemu.HardwareView', {
>   (isDisk && !diskCap),
>   );
>  
> - resize_btn.setDisabled(pending || !isUsedDisk || !diskCap);
> + resize_menuitem.setDisabled(pending || !isUsedDisk || !diskCap);
> + reassign_menuitem.setDisabled(pending || (isEfi || tpmMoveable));
>  
> - move_btn.setDisabled(pending || !(isUsedDisk || isEfi || 
> tpmMoveable) || !diskCap);
> + diskaction_btn.setDisabled(
> + pending ||
> + isCloudInit ||
> + !(isDisk || isEfi || tpmMoveable) ||
> + !diskCap,
> + );

Here you are using the fact that "move action disabled" implies "resize
and reassign action disabled". Might be worth giving the following a
shot hoping it's cleaner:

if pending || !diskCap || other common criteria
  disable menu
else
  enable menu
  disable resize based on resize-specific criteria (here the common
criteria don't need to be repeated)
  disable reassign based on reassign-specific criteria
  disable move based on move-specific criteria

and if the common criteria are collected correctly, there should never
be a case where all entries are disabled but the menu isn't.

>  
>   revert_btn.setDisabled(!pending);
>   };


___
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel



Re: [pve-devel] [PATCH v4 manager 6/6] ui: util: refactor mps to mp

2022-03-22 Thread Fabian Ebner
Am 14.03.22 um 10:35 schrieb Aaron Lauterer:
> @@ -1805,9 +1805,7 @@ Ext.define('PVE.Utils', {
>  },
>  
>  nextFreeMP: function(type, config) {
> - let mptype = type === "mp" ? "mps" : type;
> -
> - for (let i = 0; i < PVE.Utils.mp_counts[mptype]; i++) {
> + for (let i = 0; i < PVE.Utils.mp_counts[type]; i++) {
>   let confid = `${type}${i}`;
>   if (!Ext.isDefined(config[confid])) {
>   return {

Nit: If this patch were ordered before the first one, we could start out
with the simpler version.


___
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel



Re: [pve-devel] [PATCH v4 manager 0/6] ui: lxc/qemu: add reassign for disks and volumes

2022-03-22 Thread Fabian Ebner
Am 14.03.22 um 10:35 schrieb Aaron Lauterer:
> This series adds the UI to reassign a disk / volume from one guest to another.
> 
> To avoid button clutter, the Move, Reassing and Resize buttons are moved
> into a new submenu called "Disk/Volume Action".
> 
> Patch 3 to 6 are optional. Patch 3 changes the labels for Move, Reassign
> and Resize to remove Volume & Disk as we already have this in the
> context of the submenu.
> 
> Patch 4 only changes a double negated option.
> Patch 5 happend in the process of working on an interface for the
> reassign functionality. Since the work of modernizing this componend is
> done, why not use it
> 
> Patch 6 changes how we store the max number of MPs possible because I
> ran into the issue, that I cannot easily match against the object key if
> it is 'mps' instead of 'mp'.
> 

Just nits, so
Reviewed-by: Fabian Ebner 


___
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel



Re: [pve-devel] [PATCH manager 1/5 v2] Storage GUI: Rewrite backup content view as TreePanel.

2022-03-22 Thread Thomas Lamprecht
On 22.03.22 09:42, Fabian Ebner wrote:
> Nit: for the commit title, prefixing like "ui: storage:" is preferred.
> 
> I really think we should start with the tree fully expanded, or we will
> get shouted at by users relying on notes to find their backups ;)

+1, additionally add a toggle for expand/collapse-all for quickly switching
but default should be all visible.

> 
> @Thomas: The backups are now ordered ascending by date again. In PBS
> it's also like that. Should that be changed or do we switch back in PVE?

As age vs. date order is exactly the reverse, and thus possibly confusing:
I'd like have the most recent first (at top).



___
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel



Re: [pve-devel] [PATCH access-control/manager v2] fix #3668: improving realm sync

2022-03-22 Thread Thomas Lamprecht
On 22.03.22 07:11, Thomas Lamprecht wrote:
> On 04.02.22 15:24, Dominik Csapak wrote:
>> this deprecates the 'full' sync option and replaces it with
>> a 'mode' option, where we add a third one that updates
>> the current users (while retaining their custom set attributes not
>> exisiting in the source) and removing users that don't exist anymore
>> in the source
>>
> I'm not yet 100% sure about the specific mode names, as sync normally means
> 100% sync, I'll see if I find some other tool (rsync?) with similar option 
> naming
> problems. Independent from the specific names, this really needs a docs patch,
> ideally with a table listing the modi as rows and having the various "user 
> added",
> "user removed", "properties added/updated", "properties removed" as columns, 
> for a
> better understanding of the effects..
> 
A thought (train): what we decide with this isn't what gets added/updated, 
that's
always the same, only what gets removed if vanished on the source, so maybe:

remove-vanished: < none | user | user-and-properties >

Or if we can actually also remove either user *or* group then: s/user/entity/ ?

ps. the web interface should probably do a s/Purge/Purge ACLs/ too; or with that
in mind we could actually drop that do and have:

remove-vanished: < none | user | user-and-properties | 
user-and-properties-and-acl >

And with that, we could go the separate semicolon-endcoded-flag-list like we do 
for
some CT features (or mount options) IIRC:

remove-vanished: [];[];[acls]

I.e., those three flags would replace your new mode + purge like:

+++-+
|  Mode  | Purge  | -> removed-vanished |
+++-+
| update |  0 | "" (none)   |
| sync   |  0 | user|
| full   |  0 | user;properties |
| update |  1 | acl |
| sync   |  1 | acl;user|
| full   |  1 | acl;user;properties |
+++-+

The selector for them could be either three check boxes on one line (similar to 
the
privilege level radio buttons from CT restore) or even a full blown combobox 
with all
the options spelled out.

It's only slightly weird for acl, as there the "remove-vanished" somewhat 
implies that
we import acl's in the first place, if we really don't want that we could keep
"Purge ACLs" as separate option that is only enabled if "remove-vanished" 
"user" flag
is set, put IMO not _that_ of a big problem to understand compared to the 
status quo.

Does (any of) this make sense to you?


___
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel



Re: [pve-devel] [PATCH access-control/manager v2] fix #3668: improving realm sync

2022-03-22 Thread Dominik Csapak

On 3/22/22 14:44, Thomas Lamprecht wrote:

On 22.03.22 07:11, Thomas Lamprecht wrote:

On 04.02.22 15:24, Dominik Csapak wrote:

this deprecates the 'full' sync option and replaces it with
a 'mode' option, where we add a third one that updates
the current users (while retaining their custom set attributes not
exisiting in the source) and removing users that don't exist anymore
in the source


I'm not yet 100% sure about the specific mode names, as sync normally means
100% sync, I'll see if I find some other tool (rsync?) with similar option 
naming
problems. Independent from the specific names, this really needs a docs patch,
ideally with a table listing the modi as rows and having the various "user 
added",
"user removed", "properties added/updated", "properties removed" as columns, 
for a
better understanding of the effects..


A thought (train): what we decide with this isn't what gets added/updated, 
that's
always the same, only what gets removed if vanished on the source, so maybe:

remove-vanished: < none | user | user-and-properties >

Or if we can actually also remove either user *or* group then: s/user/entity/ ?

ps. the web interface should probably do a s/Purge/Purge ACLs/ too; or with that
in mind we could actually drop that do and have:

remove-vanished: < none | user | user-and-properties | user-and-properties-and-acl 
>

And with that, we could go the separate semicolon-endcoded-flag-list like we do 
for
some CT features (or mount options) IIRC:

remove-vanished: [];[];[acls]

I.e., those three flags would replace your new mode + purge like:

+++-+
|  Mode  | Purge  | -> removed-vanished |
+++-+
| update |  0 | "" (none)   |
| sync   |  0 | user|
| full   |  0 | user;properties |
| update |  1 | acl |
| sync   |  1 | acl;user|
| full   |  1 | acl;user;properties |
+++-+

The selector for them could be either three check boxes on one line (similar to 
the
privilege level radio buttons from CT restore) or even a full blown combobox 
with all
the options spelled out.

It's only slightly weird for acl, as there the "remove-vanished" somewhat 
implies that
we import acl's in the first place, if we really don't want that we could keep
"Purge ACLs" as separate option that is only enabled if "remove-vanished" 
"user" flag
is set, put IMO not _that_ of a big problem to understand compared to the 
status quo.

Does (any of) this make sense to you?


yes this sounds sensible, but i agree about the possibly confusing 
'remove-vanished'
implication for acls. Maybe 'remove-on-vanish' ?
this would (semantically) decouple the 'vanished' thing from the 'removed' 
thing,
at least a little bit.
in either case the docs would have to be updated anyway (as you already said)

aside from that, i think line 4 in your table is not really practical,
since it would remove the acls but leave the users ?

we could enable the 'acl' checkbox only when the 'users' checkbox is active,
similar to what you suggested


___
pve-devel mailing list
pve-devel@lists.proxmox.com
https://lists.proxmox.com/cgi-bin/mailman/listinfo/pve-devel