use JSON;
use RRDs;
use Encode;
+use UUID;
use base 'Exporter';
our @EXPORT_OK = qw(
mkdir $authdir || $! == EEXIST || die "unable to create dir '$authdir' - $!\n";
- my $cmd = "openssl genrsa -out '$authprivkeyfn' 2048";
- run_silent_cmd($cmd);
+ run_silent_cmd(['openssl', 'genrsa', '-out', $authprivkeyfn, '2048']);
- $cmd = "openssl rsa -in '$authprivkeyfn' -pubout -out '$authpubkeyfn'";
- run_silent_cmd($cmd)
+ run_silent_cmd(['openssl', 'rsa', '-in', $authprivkeyfn, '-pubout', '-out', $authpubkeyfn]);
}
sub gen_pveca_key {
# we try to generate an unique 'subject' to avoid browser problems
# (reused serial numbers, ..)
- my $nid = (split (/\s/, `md5sum '$pveca_key_fn'`))[0] || time();
+ my $uuid;
+ UUID::generate($uuid);
+ my $uuid_str;
+ UUID::unparse($uuid, $uuid_str);
eval {
- run_silent_cmd(['openssl', 'req', '-batch', '-days', '3650', '-new',
- '-x509', '-nodes', '-key',
+ # wrap openssl with faketime to prevent bug #904
+ run_silent_cmd(['faketime', 'yesterday', 'openssl', 'req', '-batch',
+ '-days', '3650', '-new', '-x509', '-nodes', '-key',
$pveca_key_fn, '-out', $pveca_cert_fn, '-subj',
- "/CN=Proxmox Virtual Environment/OU=$nid/O=PVE Cluster Manager CA/"]);
+ "/CN=Proxmox Virtual Environment/OU=$uuid_str/O=PVE Cluster Manager CA/"]);
};
die "generating pve root certificate failed:\n$@" if $@;
[ v3_req ]
basicConstraints = CA:FALSE
-nsCertType = server
-keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+extendedKeyUsage = serverAuth
subjectAltName = $names
__EOD
update_serial("0000000000000000") if ! -f $pveca_srl_fn;
eval {
- run_silent_cmd(['openssl', 'x509', '-req', '-in', $reqfn, '-days', '3650',
- '-out', $pvessl_cert_fn, '-CAkey', $pveca_key_fn,
- '-CA', $pveca_cert_fn, '-CAserial', $pveca_srl_fn,
- '-extfile', $cfgfn]);
+ # wrap openssl with faketime to prevent bug #904
+ run_silent_cmd(['faketime', 'yesterday', 'openssl', 'x509', '-req',
+ '-in', $reqfn, '-days', '3650', '-out', $pvessl_cert_fn,
+ '-CAkey', $pveca_key_fn, '-CA', $pveca_cert_fn,
+ '-CAserial', $pveca_srl_fn, '-extfile', $cfgfn]);
};
if (my $err = $@) {
for my $line (@$data) {
my $entry = { 'time' => $start };
$start += $step;
- my $found_undefs;
for (my $i = 0; $i < $fields; $i++) {
my $name = $names->[$i];
if (defined(my $val = $line->[$i])) {
$entry->{$name} = $val;
} else {
- # we only add entryies with all data defined
- # extjs chart has problems with undefined values
- $found_undefs = 1;
+ # leave empty fields undefined
+ # maybe make this configurable?
}
}
- push @$res, $entry if !$found_undefs;
+ push @$res, $entry;
}
return $res;
"--width" => 800,
"--start" => - $reso*$count,
"--end" => 'now' ,
+ "--lower-limit" => 0,
);
my $socket = "/var/run/rrdcached.sock";
format => 'email-opt',
description => "Specify email address to send notification from (default is root@\$hostname)",
},
+ max_workers => {
+ optional => 1,
+ type => 'integer',
+ minimum => 1,
+ description => "Defines how many workers (per node) are maximal started ".
+ " on actions like 'stopall VMs' or task from the ha-manager.",
+ },
+ fencing => {
+ optional => 1,
+ type => 'string',
+ default => 'watchdog',
+ enum => [ 'watchdog', 'hardware', 'both' ],
+ description => "Set the fencing mode of the HA cluster. Hardware mode " .
+ "needs a valid configuration of fence devices in /etc/pve/ha/fence.cfg." .
+ " With both all two modes are used." .
+ "\n\nWARNING: 'hardware' and 'both' are EXPERIMENTAL & WIP",
+ },
+ mac_prefix => {
+ optional => 1,
+ type => 'string',
+ pattern => qr/[a-f0-9]{2}(?::[a-f0-9]{2}){0,2}:?/i,
+ description => 'Prefix for autogenerated MAC addresses.',
+ },
},
};
PVE::Cluster::cfs_register_file('corosync.conf.new', \&parse_corosync_conf,
\&write_corosync_conf);
+sub check_corosync_conf_exists {
+ my ($silent) = @_;
+
+ $silent = $silent // 0;
+
+ my $exists = -f "$basedir/corosync.conf";
+
+ warn "Corosync config '$basedir/corosync.conf' does not exist - is this node part of a cluster?\n"
+ if !$silent && !$exists;
+
+ return $exists;
+}
+
# bash completion helpers
sub complete_next_vmid {