]>
git.proxmox.com Git - pmg-api.git/blob - src/PMG/ClusterConfig.pm
1 package PMG
::ClusterConfig
::Base
;
8 use PVE
::JSONSchema
qw(get_standard_option);
10 use PVE
::SectionConfig
;
12 use base
qw(PVE::SectionConfig);
16 type
=> { description
=> "Cluster node type." },
18 description
=> "Cluster Node ID.",
29 sub parse_section_header
{
30 my ($class, $line) = @_;
32 if ($line =~ m/^(node|master):\s*(\d+)\s*$/) {
33 my ($type, $sectionId) = ($1, $2);
34 my $errmsg = undef; # set if you want to skip whole section
35 my $config = {}; # to return additional attributes
36 return ($type, $sectionId, $errmsg, $config);
41 package PMG
::ClusterConfig
::Node
;
46 use base
qw(PMG::ClusterConfig::Base);
48 sub valid_ssh_pubkey_regex
{
49 return '^[A-Za-z0-9\.\/\+=]{200,}$';
58 description
=> "IP address.",
59 type
=> 'string', format
=> 'ip',
62 description
=> "Node name.",
63 type
=> 'string', format
=>'pve-node',
66 description
=> "Public SSH RSA key for the host.",
68 pattern
=> valid_ssh_pubkey_regex
(),
71 description
=> "Public SSH RSA key for the root user.",
73 pattern
=> valid_ssh_pubkey_regex
(),
76 description
=> "SSL certificate fingerprint.",
78 pattern
=> '^(:?[A-Z0-9][A-Z0-9]:){31}[A-Z0-9][A-Z0-9]$',
86 name
=> { fixed
=> 1 },
93 package PMG
::ClusterConfig
::Master
;
98 use base
qw(PMG::ClusterConfig::Base);
107 description
=> "Maximum used cluster node ID (used internally, do not modify).",
116 maxcid
=> { fixed
=> 1 },
117 ip
=> { fixed
=> 1 },
118 name
=> { fixed
=> 1 },
125 package PMG
::ClusterConfig
;
137 PMG
::ClusterConfig
::Node-
>register;
138 PMG
::ClusterConfig
::Master-
>register;
139 PMG
::ClusterConfig
::Base-
>init();
145 my $class = ref($type) || $type;
147 my $cfg = PVE
::INotify
::read_file
("cluster.conf");
149 return bless $cfg, $class;
155 PVE
::INotify
::write_file
("cluster.conf", $self);
158 my $lockfile = "/var/lock/pmgcluster.lck";
161 my ($code, $errmsg) = @_;
163 my $res = PVE
::Tools
::lock_file
($lockfile, undef, $code);
165 $errmsg ?
die "$errmsg: $err" : die $err;
170 sub read_cluster_conf
{
171 my ($filename, $fh) = @_;
173 my $raw = defined($fh) ?
do { local $/ = undef; <$fh> } : undef;
175 my $cinfo = PMG
::ClusterConfig
::Base-
>parse_config($filename, $raw);
177 my $localname = PVE
::INotify
::nodename
();
178 my $localip = PVE
::Network
::get_local_ip
(); # does gai with fallback to interfaces cfg. & ip-addr
180 $cinfo->{remnodes
} = [];
191 my $errprefix = "unable to parse $filename";
193 foreach my $cid (keys %{$cinfo->{ids
}}) {
194 my $d = $cinfo->{ids
}->{$cid};
196 die "$errprefix: duplicate use of name '$d->{name}'\n" if $names_hash->{$d->{name
}};
197 $names_hash->{$d->{name
}} = 1;
200 $maxcid = $cid > $maxcid ?
$cid : $maxcid;
201 $maxcid = $d->{maxcid
} if defined($d->{maxcid
}) && $d->{maxcid
} > $maxcid;
202 $cinfo->{master
} = $d if $d->{type
} eq 'master';
203 $cinfo->{'local'} = $d if $d->{name
} eq $localname;
207 die "$errprefix: cluster without master node\n"
208 if !defined($cinfo->{master
});
209 $cinfo->{master
}->{maxcid
} = $maxcid;
212 my $local_cid = $cinfo->{local}->{cid
};
213 foreach my $cid (sort keys %{$cinfo->{ids
}}) {
214 if ($local_cid != $cid) {
215 push @{$cinfo->{remnodes
}}, $cid;
222 sub write_cluster_conf
{
223 my ($filename, $fh, $cfg) = @_;
225 my $raw = PMG
::ClusterConfig
::Base-
>write_config($filename, $cfg);
227 PVE
::Tools
::safe_print
($filename, $fh, $raw);
230 PVE
::INotify
::register_file
('cluster.conf', "/etc/pmg/cluster.conf",
232 \
&write_cluster_conf
,
234 always_call_parser
=> 1);