]>
git.proxmox.com Git - pve-manager.git/blob - PVE/NodeConfig.pm
13c0465066a0156e436f3f9119baa9bd7f1365cf
1 package PVE
::NodeConfig
;
7 use PVE
::JSONSchema
qw(get_standard_option);
8 use PVE
::Tools
qw(file_get_contents file_set_contents lock_file);
10 my $node_config_lock = '/var/lock/pvenode.lock';
12 PVE
::JSONSchema
::register_format
('pve-acme-domain', sub {
13 my ($domain, $noerr) = @_;
15 my $label = qr/[a-z0-9][a-z0-9_-]*/i;
17 return $domain if $domain =~ /^$label(?:\.$label)+$/;
18 return undef if $noerr;
19 die "value does not look like a valid domain name";
25 return "/etc/pve/nodes/${node}/config";
31 my $filename = config_file
($node);
32 my $raw = eval { PVE
::Tools
::file_get_contents
($filename); };
35 return parse_node_config
($raw);
39 my ($node, $conf) = @_;
41 my $filename = config_file
($node);
43 my $raw = write_node_config
($conf);
45 PVE
::Tools
::file_set_contents
($filename, $raw);
49 my ($node, $code, @param) = @_;
51 my $res = lock_file
($node_config_lock, 10, $code, @param);
61 description
=> 'Node description/comment.',
66 description
=> 'MAC address for wake on LAN',
67 pattern
=> '^([0-9a-fA-F]{2}:){5}([0-9a-fA-F]{2})$',
73 account
=> get_standard_option
('pve-acme-account-name'),
76 format
=> 'pve-acme-domain-list',
77 format_description
=> 'domain[;domain;...]',
78 description
=> 'List of domains for this node\'s ACME certificate',
81 PVE
::JSONSchema
::register_format
('pve-acme-node-conf', $acmedesc);
85 description
=> 'Node specific ACME settings.',
91 my ($key, $value) = @_;
93 die "unknown setting '$key'\n" if !$confdesc->{$key};
95 my $type = $confdesc->{$key}->{type
};
97 if (!defined($value)) {
98 die "got undefined value\n";
101 if ($value =~ m/[\n\r]/) {
102 die "property contains a line feed\n";
105 if ($type eq 'boolean') {
106 return 1 if ($value eq '1') || ($value =~ m/^(on|yes|true)$/i);
107 return 0 if ($value eq '0') || ($value =~ m/^(off|no|false)$/i);
108 die "type check ('boolean') failed - got '$value'\n";
109 } elsif ($type eq 'integer') {
110 return int($1) if $value =~ m/^(\d+)$/;
111 die "type check ('integer') failed - got '$value'\n";
112 } elsif ($type eq 'number') {
113 return $value if $value =~ m/^(\d+)(\.\d+)?$/;
114 die "type check ('number') failed - got '$value'\n";
115 } elsif ($type eq 'string') {
116 if (my $fmt = $confdesc->{$key}->{format
}) {
117 PVE
::JSONSchema
::check_format
($fmt, $value);
119 } elsif (my $pattern = $confdesc->{$key}->{pattern
}) {
120 if ($value !~ m/^$pattern$/) {
121 die "value does not match the regex pattern\n";
130 sub parse_node_config
{
133 return undef if !defined($content);
136 digest
=> Digest
::SHA
::sha1_hex
($content),
140 my @lines = split(/\n/, $content);
141 foreach my $line (@lines) {
142 if ($line =~ /^\#(.*)\s*$/ || $line =~ /^description:\s*(.*\S)\s*$/) {
143 $descr .= PVE
::Tools
::decode_text
($1) . "\n";
146 if ($line =~ /^([a-z][a-z_]*\d*):\s*(\S.*)\s*$/) {
149 eval { $value = check_type
($key, $value); };
150 warn "cannot parse value of '$key' in node config: $@" if $@;
151 $conf->{$key} = $value;
153 warn "cannot parse line '$line' in node config\n";
157 $conf->{description
} = $descr if $descr;
162 sub write_node_config
{
166 # add description as comment to top of file
167 my $descr = $conf->{description
} || '';
168 foreach my $cl (split(/\n/, $descr)) {
169 $raw .= '#' . PVE
::Tools
::encode_text
($cl) . "\n";
172 for my $key (sort keys %$conf) {
173 next if ($key eq 'description');
174 next if ($key eq 'digest');
176 my $value = $conf->{$key};
177 die "detected invalid newline inside property '$key'\n"
179 $raw .= "$key: $value\n";
186 my ($data, $noerr) = @_;
190 my $res = eval { PVE
::JSONSchema
::parse_property_string
($acmedesc, $data); };
192 return undef if $noerr;
196 $res->{domains
} = [ PVE
::Tools
::split_list
($res->{domains
}) ];
204 $acme->{domains
} = join(';', $acme->{domains
}) if $acme->{domains
};
205 return PVE
::JSONSchema
::print_property_string
($acme, $acmedesc);
208 sub get_nodeconfig_schema
{