Re: [pve-devel] [RFC manager 2/5] add node configuration file and API

2018-04-13 Thread Wolfgang Bumiller
On Wed, Apr 11, 2018 at 10:08:48AM +0200, Fabian Grünbichler wrote:
> this currently only contains a description and the node-specific ACME
> configuration, but I am sure we can find other goodies to put there.
> 
> Signed-off-by: Fabian Grünbichler 
> ---
>  PVE/API2/Makefile  |   1 +
>  PVE/Makefile   |   1 +
>  PVE/API2/NodeConfig.pm |  99 
>  PVE/API2/Nodes.pm  |   7 ++
>  PVE/NodeConfig.pm  | 205 
> +
>  5 files changed, 313 insertions(+)
>  create mode 100644 PVE/API2/NodeConfig.pm
>  create mode 100644 PVE/NodeConfig.pm
> 
> diff --git a/PVE/API2/Makefile b/PVE/API2/Makefile
> index 86d75d36..51b8b30a 100644
> --- a/PVE/API2/Makefile
> +++ b/PVE/API2/Makefile
> @@ -14,6 +14,7 @@ PERLSOURCE =\
>   Pool.pm \
>   Tasks.pm\
>   Network.pm  \
> + NodeConfig.pm   \
>   Services.pm
>  
>  all:
> diff --git a/PVE/Makefile b/PVE/Makefile
> index 395faf8a..56d27d13 100644
> --- a/PVE/Makefile
> +++ b/PVE/Makefile
> @@ -11,6 +11,7 @@ PERLSOURCE =\
>   AutoBalloon.pm  \
>   CephTools.pm\
>   Report.pm   \
> + NodeConfig.pm   \
>   VZDump.pm
>  
>  all: pvecfg.pm ${SUBDIRS}
> diff --git a/PVE/API2/NodeConfig.pm b/PVE/API2/NodeConfig.pm
> new file mode 100644
> index ..8c976974
> --- /dev/null
> +++ b/PVE/API2/NodeConfig.pm
> @@ -0,0 +1,99 @@
> +package PVE::API2::NodeConfig;
> +
> +use strict;
> +use warnings;
> +
> +use PVE::JSONSchema qw(get_standard_option);
> +use PVE::NodeConfig;
> +use PVE::Tools qw(extract_param);
> +
> +use base qw(PVE::RESTHandler);
> +
> +my $node_config_schema = PVE::NodeConfig::get_nodeconfig_schema();
> +my $node_config_properties = {
> +delete => {
> + type => 'string', format => 'pve-configid-list',
> + description => "A list of settings you want to delete.",
> + optional => 1,
> +},
> +digest => {
> + type => 'string',
> + description => 'Prevent changes if current configuration file has 
> different SHA1 digest. This can be used to prevent concurrent modifications.',
> + maxLength => 40,
> + optional => 1,
> +},
> +node => get_standard_option('pve-node'),
> +};
> +
> +foreach my $opt (keys %{$node_config_schema}) {
> +$node_config_properties->{$opt} = $node_config_schema->{$opt};
> +}
> +
> +__PACKAGE__->register_method({
> +name => 'get_config',
> +path => '',
> +method => 'GET',
> +description => "Get node configuration options.",
> +permissions => {
> + check => ['perm', '/', [ 'Sys.Audit' ]],
> +},
> +parameters => {
> + additionalProperties => 0,
> + properties => {
> + node => get_standard_option('pve-node'),
> + },
> +},
> +returns => {
> + type => "object",
> + properties => {},
> +},
> +code => sub {
> + my ($param) = @_;
> +
> + return PVE::NodeConfig::load_config($param->{node});
> +}});
> +
> +__PACKAGE__->register_method({
> +name => 'set_options',
> +path => '',
> +method => 'PUT',
> +description => "Set node configuration options.",
> +permissions => {
> + check => ['perm', '/', [ 'Sys.Modify' ]],
> +},
> +protected => 1,
> +parameters => {
> + additionalProperties => 0,
> + properties => $node_config_properties,
> +},
> +returns => { type => "null" },
> +code => sub {
> + my ($param) = @_;
> +
> + my $delete = extract_param($param, 'delete');
> + my $node = extract_param($param, 'node');
> + my $digest = extract_param($param, 'digest');
> +
> + my $code = sub {
> + my $conf = PVE::NodeConfig::load_config($node);
> +
> + PVE::Tools::assert_if_modified($digest, $conf->{digest});
> +
> + foreach my $opt (keys %$param) {
> + $conf->{$opt} = $param->{$opt};
> + }
> +
> + foreach my $opt (PVE::Tools::split_list($delete)) {
> + delete $conf->{$opt};
> + };
> +
> + PVE::NodeConfig::write_config($node, $conf);
> + };
> +
> + PVE::NodeConfig::lock_config($node, $code);
> + die $@ if $@;
> +
> + return undef;
> +}});
> +
> +1;
> diff --git a/PVE/API2/Nodes.pm b/PVE/API2/Nodes.pm
> index 3eb38315..42b932cf 100644
> --- a/PVE/API2/Nodes.pm
> +++ b/PVE/API2/Nodes.pm
> @@ -41,6 +41,7 @@ use PVE::API2::APT;
>  use PVE::API2::Ceph;
>  use PVE::API2::Firewall::Host;
>  use PVE::API2::Replication;
> +use PVE::API2::NodeConfig;
>  use Digest::MD5;
>  use Digest::SHA;
>  use PVE::API2::Disks;
> @@ -118,6 +119,11 @@ __PACKAGE__->register_method ({
>  path => 'replication',
>  });
>  
> +__PACKAGE__->register_method ({
> +subclass => "PVE::API2::NodeConfig",
> +path => 'config',
> +});
> +
>  __PACKAGE__->register_method ({
>  name => 'index', 
>  path 

[pve-devel] [RFC manager 2/5] add node configuration file and API

2018-04-11 Thread Fabian Grünbichler
this currently only contains a description and the node-specific ACME
configuration, but I am sure we can find other goodies to put there.

Signed-off-by: Fabian Grünbichler 
---
 PVE/API2/Makefile  |   1 +
 PVE/Makefile   |   1 +
 PVE/API2/NodeConfig.pm |  99 
 PVE/API2/Nodes.pm  |   7 ++
 PVE/NodeConfig.pm  | 205 +
 5 files changed, 313 insertions(+)
 create mode 100644 PVE/API2/NodeConfig.pm
 create mode 100644 PVE/NodeConfig.pm

diff --git a/PVE/API2/Makefile b/PVE/API2/Makefile
index 86d75d36..51b8b30a 100644
--- a/PVE/API2/Makefile
+++ b/PVE/API2/Makefile
@@ -14,6 +14,7 @@ PERLSOURCE =  \
Pool.pm \
Tasks.pm\
Network.pm  \
+   NodeConfig.pm   \
Services.pm
 
 all:
diff --git a/PVE/Makefile b/PVE/Makefile
index 395faf8a..56d27d13 100644
--- a/PVE/Makefile
+++ b/PVE/Makefile
@@ -11,6 +11,7 @@ PERLSOURCE =  \
AutoBalloon.pm  \
CephTools.pm\
Report.pm   \
+   NodeConfig.pm   \
VZDump.pm
 
 all: pvecfg.pm ${SUBDIRS}
diff --git a/PVE/API2/NodeConfig.pm b/PVE/API2/NodeConfig.pm
new file mode 100644
index ..8c976974
--- /dev/null
+++ b/PVE/API2/NodeConfig.pm
@@ -0,0 +1,99 @@
+package PVE::API2::NodeConfig;
+
+use strict;
+use warnings;
+
+use PVE::JSONSchema qw(get_standard_option);
+use PVE::NodeConfig;
+use PVE::Tools qw(extract_param);
+
+use base qw(PVE::RESTHandler);
+
+my $node_config_schema = PVE::NodeConfig::get_nodeconfig_schema();
+my $node_config_properties = {
+delete => {
+   type => 'string', format => 'pve-configid-list',
+   description => "A list of settings you want to delete.",
+   optional => 1,
+},
+digest => {
+   type => 'string',
+   description => 'Prevent changes if current configuration file has 
different SHA1 digest. This can be used to prevent concurrent modifications.',
+   maxLength => 40,
+   optional => 1,
+},
+node => get_standard_option('pve-node'),
+};
+
+foreach my $opt (keys %{$node_config_schema}) {
+$node_config_properties->{$opt} = $node_config_schema->{$opt};
+}
+
+__PACKAGE__->register_method({
+name => 'get_config',
+path => '',
+method => 'GET',
+description => "Get node configuration options.",
+permissions => {
+   check => ['perm', '/', [ 'Sys.Audit' ]],
+},
+parameters => {
+   additionalProperties => 0,
+   properties => {
+   node => get_standard_option('pve-node'),
+   },
+},
+returns => {
+   type => "object",
+   properties => {},
+},
+code => sub {
+   my ($param) = @_;
+
+   return PVE::NodeConfig::load_config($param->{node});
+}});
+
+__PACKAGE__->register_method({
+name => 'set_options',
+path => '',
+method => 'PUT',
+description => "Set node configuration options.",
+permissions => {
+   check => ['perm', '/', [ 'Sys.Modify' ]],
+},
+protected => 1,
+parameters => {
+   additionalProperties => 0,
+   properties => $node_config_properties,
+},
+returns => { type => "null" },
+code => sub {
+   my ($param) = @_;
+
+   my $delete = extract_param($param, 'delete');
+   my $node = extract_param($param, 'node');
+   my $digest = extract_param($param, 'digest');
+
+   my $code = sub {
+   my $conf = PVE::NodeConfig::load_config($node);
+
+   PVE::Tools::assert_if_modified($digest, $conf->{digest});
+
+   foreach my $opt (keys %$param) {
+   $conf->{$opt} = $param->{$opt};
+   }
+
+   foreach my $opt (PVE::Tools::split_list($delete)) {
+   delete $conf->{$opt};
+   };
+
+   PVE::NodeConfig::write_config($node, $conf);
+   };
+
+   PVE::NodeConfig::lock_config($node, $code);
+   die $@ if $@;
+
+   return undef;
+}});
+
+1;
diff --git a/PVE/API2/Nodes.pm b/PVE/API2/Nodes.pm
index 3eb38315..42b932cf 100644
--- a/PVE/API2/Nodes.pm
+++ b/PVE/API2/Nodes.pm
@@ -41,6 +41,7 @@ use PVE::API2::APT;
 use PVE::API2::Ceph;
 use PVE::API2::Firewall::Host;
 use PVE::API2::Replication;
+use PVE::API2::NodeConfig;
 use Digest::MD5;
 use Digest::SHA;
 use PVE::API2::Disks;
@@ -118,6 +119,11 @@ __PACKAGE__->register_method ({
 path => 'replication',
 });
 
+__PACKAGE__->register_method ({
+subclass => "PVE::API2::NodeConfig",
+path => 'config',
+});
+
 __PACKAGE__->register_method ({
 name => 'index', 
 path => '', 
@@ -171,6 +177,7 @@ __PACKAGE__->register_method ({
{ name => 'stopall' },
{ name => 'netstat' },
{ name => 'firewall' },
+   { name => 'config' },
];
 
return $result;
diff --git a/PVE/NodeConfig.pm b/PVE/NodeConfig.pm
new file mode 100644
index