--- /dev/null
+include defines.mk
+
+DESTDIR=
+
+#SUBDIRS = bin lib www aplinfo
+SUBDIRS = aplinfo PVE bin www
+
+DEB=${PACKAGE}_${VERSION}-${PACKAGERELEASE}_all.deb
+
+all: ${SUBDIRS}
+
+%:
+ set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i $@; done
+
+
+.PHONY: dinstall
+dinstall: ${DEB}
+ dpkg -i ${DEB}
+
+country.dat: country.pl
+ ./country.pl > country.dat
+
+.PHONY: ${DEB}
+${DEB} deb:
+ make clean
+ rm -rf dest
+ mkdir dest
+ make DESTDIR=`pwd`/dest install
+ mkdir dest/DEBIAN
+ sed -e s/@VERSION@/${VERSION}/ -e s/@PACKAGE@/${PACKAGE}/ -e s/@PACKAGERELEASE@/${PACKAGERELEASE}/ debian/control.in >dest/DEBIAN/control
+ install -m 0644 debian/conffiles dest/DEBIAN
+ install -m 0755 debian/config dest/DEBIAN
+ install -m 0644 debian/templates dest/DEBIAN
+ install -m 0755 debian/postinst dest/DEBIAN
+ install -m 0755 debian/prerm dest/DEBIAN
+ install -m 0755 debian/postrm dest/DEBIAN
+ install -m 0644 debian/triggers dest/DEBIAN
+ gzip --best dest/usr/share/man/*/*
+ gzip --best dest/usr/share/doc/${PACKAGE}/changelog.Debian
+ dpkg-deb --build dest
+ mv dest.deb ${DEB}
+ rm -rf dest
+ lintian ${DEB}
+
+.PHONY: upload
+upload: ${DEB}
+ umount /pve/${RELEASE}; mount /pve/${RELEASE} -o rw
+ mkdir -p /pve/${RELEASE}/extra
+ rm -f /pve/${RELEASE}/extra/${PACKAGE}_*.deb
+ rm -f /pve/${RELEASE}/extra/Packages*
+ cp ${DEB} /pve/${RELEASE}/extra
+ cd /pve/${RELEASE}/extra; dpkg-scanpackages . /dev/null > Packages; gzip -9c Packages > Packages.gz
+ umount /pve/${RELEASE}; mount /pve/${RELEASE} -o ro
+
+#.PHONY: poupload
+#poupload:
+# rsync po/*.po po/pve-manager.pot pve.proxmox.com:/home/ftp/sources/po-files/
+
+#.PHONY: aplupload
+#aplupload:
+# ./aplinfo/apltest.pl
+# gpg -bas -u support@proxmox.com aplinfo/aplinfo.dat
+# gzip -c aplinfo/aplinfo.dat > aplinfo.dat.gz
+# scp aplinfo/aplinfo.dat aplinfo.dat.gz aplinfo/aplinfo.dat.asc pve.proxmox.com:/home/ftp/appliances/
+
+.PHONY: install
+install: country.dat vznet.conf
+ install -d ${DESTDIR}/usr/share/${PACKAGE}
+ install -d ${DESTDIR}/usr/share/man/man1
+ install -d ${DESTDIR}/usr/share/doc/${PACKAGE}
+ install -d ${DESTDIR}/var/lib/${PACKAGE}
+ install -d ${DESTDIR}/var/lib/vz/images
+ install -d ${DESTDIR}/var/lib/vz/template/cache
+ install -d ${DESTDIR}/var/lib/vz/template/iso
+ install -d ${DESTDIR}/var/lib/vz/template/qemu
+ install -D -m 0755 vznet.conf ${DESTDIR}/etc/vz/vznet.conf
+ install -m 0644 copyright ${DESTDIR}/usr/share/doc/${PACKAGE}
+ install -m 0644 debian/changelog.Debian ${DESTDIR}/usr/share/doc/${PACKAGE}
+ install -m 0644 country.dat ${DESTDIR}/usr/share/${PACKAGE}
+ set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i $@; done
+
+.PHONY: distclean
+distclean: clean
+ set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i $@; done
+
+.PHONY: clean
+clean:
+ set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i $@; done
+ find . -name '*~' -exec rm {} ';'
+ rm -rf dest country.dat *.deb
+++ /dev/null
-AUTOMAKE_OPTIONS = foreign
-
-include $(top_builddir)/common.mk
-
-SUBDIRS = bin lib www aplinfo po
-
-DEB=${PACKAGE}_${VERSION}-${PACKAGERELEASE}_all.deb
-CDATE:=$(shell date +%F)
-SNAP=${PACKAGE}-${VERSION}-${CDATE}.tar.gz
-
-vzconf_SCRIPTS = vznet.conf
-vzconfdir = /etc/vz
-
-.PHONY: dinstall
-dinstall: ${DEB}
- dpkg -i ${DEB}
-
-country.dat: country.pl
- ./country.pl > country.dat
-
-.PHONY: ${DEB}
-${DEB} deb:
- ./autogen.sh
- ./configure
- make clean
- rm -rf dest
- mkdir dest
- make DESTDIR=`pwd`/dest install-strip
- mkdir dest/DEBIAN
- install -m 0644 debian/control dest/DEBIAN
- install -m 0644 debian/conffiles dest/DEBIAN
- install -m 0755 debian/config dest/DEBIAN
- install -m 0644 debian/templates dest/DEBIAN
- install -m 0755 debian/postinst dest/DEBIAN
- install -m 0755 debian/prerm dest/DEBIAN
- install -m 0755 debian/postrm dest/DEBIAN
- install -m 0644 debian/triggers dest/DEBIAN
- gzip --best dest/usr/share/man/*/*
- gzip --best dest/usr/share/doc/${PACKAGE}/changelog.Debian
- dpkg-deb --build dest
- mv dest.deb ${DEB}
- rm -rf dest
- lintian ${DEB}
-
-.PHONY: upload
-upload: ${DEB}
- umount /pve/${RELEASE}; mount /pve/${RELEASE} -o rw
- mkdir -p /pve/${RELEASE}/extra
- rm -f /pve/${RELEASE}/extra/${PACKAGE}_*.deb
- rm -f /pve/${RELEASE}/extra/Packages*
- cp ${DEB} /pve/${RELEASE}/extra
- cd /pve/${RELEASE}/extra; dpkg-scanpackages . /dev/null > Packages; gzip -9c Packages > Packages.gz
- umount /pve/${RELEASE}; mount /pve/${RELEASE} -o ro
-
-.PHONY: poupload
-poupload:
- rsync po/*.po po/pve-manager.pot pve.proxmox.com:/home/ftp/sources/po-files/
-
-.PHONY: aplupload
-aplupload:
- ./aplinfo/apltest.pl
- gpg -bas -u support@proxmox.com aplinfo/aplinfo.dat
- gzip -c aplinfo/aplinfo.dat > aplinfo.dat.gz
- scp aplinfo/aplinfo.dat aplinfo.dat.gz aplinfo/aplinfo.dat.asc pve.proxmox.com:/home/ftp/appliances/
-
-install-data-local: country.dat
- mkdir -p ${DESTDIR}/usr/share/${PACKAGE}
- mkdir -p ${DESTDIR}/usr/share/doc/${PACKAGE}
- mkdir -p ${DESTDIR}/var/lib/${PACKAGE}
- mkdir -p ${DESTDIR}/var/lib/vz/images
- mkdir -p ${DESTDIR}/var/lib/vz/template/cache
- mkdir -p ${DESTDIR}/var/lib/vz/template/iso
- mkdir -p ${DESTDIR}/var/lib/vz/template/qemu
- install -m 0644 copyright ${DESTDIR}/usr/share/doc/${PACKAGE}
- install -m 0644 debian/changelog.Debian ${DESTDIR}/usr/share/doc/${PACKAGE}
- install -m 0644 country.dat ${DESTDIR}/usr/share/${PACKAGE}
-
-
-CLEANFILES=*~ *.deb debian/*~ dest ${PACKAGE}-*.tar.gz ${SNAP} country.dat
-
-.PHONY: snap
-${SNAP} snap: clean
- rm -f ../${SNAP}
- cd ..; tar cvzf ${SNAP} --exclude .svn --exclude autom4te.cache ${PACKAGE}
- mv ../${SNAP} ${SNAP}
-
-.PHONY: uploadsnap
-uploadsnap: ${SNAP}
- scp ${SNAP} pve.proxmox.com:/home/ftp/sources/
-
-#ACLOCAL_AMFLAGS = -I m4
-#EXTRA_DIST = config.rpath m4/ChangeLog
--- /dev/null
+package PVE::API2;
+
+use strict;
+use warnings;
+
+use Apache2::Const qw(:http);
+use PVE::RESTHandler;
+
+use base qw(PVE::RESTHandler);
+
+# preload classes
+use PVE::API2::Cluster;
+use PVE::API2::Nodes;
+use PVE::API2::AccessControl;
+use PVE::API2::Storage::Config;
+
+__PACKAGE__->register_method ({
+ subclass => "PVE::API2::Cluster",
+ path => 'cluster',
+});
+
+__PACKAGE__->register_method ({
+ subclass => "PVE::API2::Nodes",
+ path => 'nodes',
+});
+
+__PACKAGE__->register_method ({
+ subclass => "PVE::API2::Storage::Config",
+ path => 'storage',
+});
+
+__PACKAGE__->register_method ({
+ subclass => "PVE::API2::AccessControl",
+ path => 'access',
+});
+
+__PACKAGE__->register_method ({
+ name => 'index',
+ path => '',
+ method => 'GET',
+ permissions => { user => 'all' },
+ description => "Directory index.",
+ parameters => {
+ additionalProperties => 0,
+ properties => {},
+ },
+ returns => {
+ type => 'array',
+ items => {
+ type => "object",
+ properties => {
+ subdir => { type => 'string' },
+ },
+ },
+ links => [ { rel => 'child', href => "{subdir}" } ],
+ },
+ code => sub {
+ my ($resp, $param) = @_;
+
+ my $res = [];
+
+ my $ma = PVE::API2->method_attributes();
+
+ foreach my $info (@$ma) {
+ next if !$info->{subclass};
+
+ my $subpath = $info->{match_re}->[0];
+
+ push @$res, { subdir => $subpath };
+ }
+
+ return $res;
+ }});
+
+1;
--- /dev/null
+package PVE::API2::Cluster;
+
+use strict;
+use warnings;
+
+use PVE::SafeSyslog;
+use PVE::Tools qw(extract_param);
+use PVE::Cluster qw(cfs_lock_file cfs_read_file cfs_write_file);
+use PVE::Storage;
+use JSON;
+
+use Data::Dumper; # fixme: remove
+
+use Apache2::Const qw(:http);
+
+use PVE::RESTHandler;
+use PVE::RPCEnvironment;
+
+use base qw(PVE::RESTHandler);
+
+my $dc_schema = PVE::Cluster::get_datacenter_schema();
+my $dc_properties = {
+ delete => {
+ type => 'string', format => 'pve-configid-list',
+ description => "A list of settings you want to delete.",
+ optional => 1,
+ }
+};
+foreach my $opt (keys %{$dc_schema->{properties}}) {
+ $dc_properties->{$opt} = $dc_schema->{properties}->{$opt};
+}
+
+__PACKAGE__->register_method ({
+ name => 'index',
+ path => '',
+ method => 'GET',
+ description => "Cluster index.",
+ permissions => { user => 'all' },
+ parameters => {
+ additionalProperties => 0,
+ properties => {},
+ },
+ returns => {
+ type => 'array',
+ items => {
+ type => "object",
+ properties => {},
+ },
+ links => [ { rel => 'child', href => "{name}" } ],
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $result = [
+ { name => 'log' },
+ { name => 'options' },
+ { name => 'resources' },
+ { name => 'tasks' },
+ ];
+
+ return $result;
+ }});
+
+__PACKAGE__->register_method({
+ name => 'log',
+ path => 'log',
+ method => 'GET',
+ description => "Read cluster log",
+ permissions => { user => 'all' },
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ max => {
+ type => 'integer',
+ description => "Maximum number of entries.",
+ optional => 1,
+ minimum => 1,
+ }
+ },
+ },
+ returns => {
+ type => 'array',
+ items => {
+ type => "object",
+ properties => {},
+ },
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $rpcenv = PVE::RPCEnvironment::get();
+
+ my $max = $param->{max} || 0;
+ my $user = $rpcenv->get_user();
+
+ my $admin = $rpcenv->check($user, "/", [ 'Sys.Syslog' ]);
+
+ my $loguser = $admin ? '' : $user;
+
+ my $res = decode_json(PVE::Cluster::get_cluster_log($loguser, $max));
+
+ return $res->{data};
+ }});
+
+__PACKAGE__->register_method({
+ name => 'resources',
+ path => 'resources',
+ method => 'GET',
+ description => "Resources index (cluster wide).",
+ permissions => { user => 'all' },
+ parameters => {
+ additionalProperties => 0,
+ properties => {},
+ },
+ returns => {
+ type => 'array',
+ items => {
+ type => "object",
+ properties => {
+ },
+ },
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $rpcenv = PVE::RPCEnvironment::get();
+ my $user = $rpcenv->get_user();
+
+ my $res = [];
+
+ my $nodes = PVE::Cluster::get_nodelist();
+
+ my $rrd = PVE::Cluster::rrd_dump();
+
+ my $vmlist = PVE::Cluster::get_vmlist() || {};
+ my $idlist = $vmlist->{ids} || {};
+
+
+ # we try to generate 'numbers' by using "$X + 0"
+ foreach my $vmid (keys %$idlist) {
+ my $data = $idlist->{$vmid};
+
+ next if !$rpcenv->check($user, "/vms/$vmid", [ 'VM.Audit' ]);
+
+ my $entry = {
+ id => "$data->{type}/$vmid",
+ vmid => $vmid + 0,
+ node => $data->{node},
+ type => $data->{type},
+ };
+
+ if (my $d = $rrd->{"pve2-vm/$vmid"}) {
+
+ $entry->{uptime} = $d->[0] + 0;
+ $entry->{name} = $d->[1];
+
+ $entry->{maxcpu} = $d->[3] + 0;
+ $entry->{cpu} = $d->[4] + 0;
+ $entry->{maxmem} = $d->[5] + 0;
+ $entry->{mem} = $d->[6] + 0;
+ $entry->{maxdisk} = $d->[7] + 0;
+ $entry->{disk} = $d->[8] + 0;
+ }
+
+ push @$res, $entry;
+ }
+
+ foreach my $node (@$nodes) {
+ my $entry = {
+ id => "node/$node",
+ node => $node,
+ type => "node",
+ };
+ if (my $d = $rrd->{"pve2-node/$node"}) {
+
+ $entry->{uptime} = $d->[0] + 0;
+ $entry->{maxcpu} = $d->[3] + 0;
+ $entry->{cpu} = $d->[4] + 0;
+ $entry->{maxmem} = $d->[6] + 0;
+ $entry->{mem} = $d->[7] + 0;
+ $entry->{maxdisk} = $d->[10] + 0;
+ $entry->{disk} = $d->[11] + 0;
+ }
+
+ push @$res, $entry;
+ }
+
+ my $cfg = PVE::Storage::config();
+ my @sids = PVE::Storage::storage_ids ($cfg);
+
+ foreach my $storeid (@sids) {
+ my $scfg = PVE::Storage::storage_config($cfg, $storeid);
+ next if !$rpcenv->check($user, "/storage/$storeid", [ 'Datastore.Audit' ]);
+ # we create a entry for each node
+ foreach my $node (@$nodes) {
+ next if !PVE::Storage::storage_check_enabled($cfg, $storeid, $node, 1);
+ my $entry = {
+ id => "storage/$node/$storeid",
+ storage => $storeid,
+ node => $node,
+ type => 'storage',
+ };
+
+ if (my $d = $rrd->{"pve2-storage/$node/$storeid"}) {
+ $entry->{maxdisk} = $d->[1] + 0;
+ $entry->{disk} = $d->[2] + 0;
+ }
+
+ push @$res, $entry;
+
+ }
+ }
+
+ return $res;
+ }});
+
+__PACKAGE__->register_method({
+ name => 'tasks',
+ path => 'tasks',
+ method => 'GET',
+ description => "List recent tasks (cluster wide).",
+ permissions => { user => 'all' },
+ parameters => {
+ additionalProperties => 0,
+ properties => {},
+ },
+ returns => {
+ type => 'array',
+ items => {
+ type => "object",
+ properties => {
+ upid => { type => 'string' },
+ },
+ },
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $rpcenv = PVE::RPCEnvironment::get();
+ my $user = $rpcenv->get_user();
+
+ my $tlist = PVE::Cluster::get_tasklist();
+
+ my $res = [];
+
+ return $res if !$tlist;
+
+ my $all = $rpcenv->check($user, "/", [ 'Sys.Audit' ]);
+
+ foreach my $task (@$tlist) {
+ push @$res, $task if $all || ($task->{user} eq $user);
+ }
+
+ return $res;
+ }});
+
+__PACKAGE__->register_method({
+ name => 'get_options',
+ path => 'options',
+ method => 'GET',
+ description => "Get datacenter options.",
+ permissions => {
+ path => '/',
+ privs => [ 'Sys.Audit' ],
+ },
+ parameters => {
+ additionalProperties => 0,
+ properties => {},
+ },
+ returns => {
+ type => "object",
+ properties => {},
+ },
+ code => sub {
+ my ($param) = @_;
+ return PVE::Cluster::cfs_read_file('datacenter.cfg');
+ }});
+
+__PACKAGE__->register_method({
+ name => 'set_options',
+ path => 'options',
+ method => 'PUT',
+ description => "Set datacenter options.",
+ permissions => {
+ path => '/',
+ privs => [ 'Sys.Modify' ],
+ },
+ protected => 1,
+ parameters => {
+ additionalProperties => 0,
+ properties => $dc_properties,
+ },
+ returns => { type => "null" },
+ code => sub {
+ my ($param) = @_;
+
+ my $filename = 'datacenter.cfg';
+
+ my $delete = extract_param($param, 'delete');
+
+ my $code = sub {
+
+ my $conf = cfs_read_file($filename);
+
+ foreach my $opt (keys %$param) {
+ $conf->{$opt} = $param->{$opt};
+ }
+
+ foreach my $opt (PVE::Tools::split_list($delete)) {
+ delete $conf->{$opt};
+ };
+
+ cfs_write_file($filename, $conf);
+ };
+
+ cfs_lock_file($filename, undef, $code);
+ die $@ if $@;
+
+ return undef;
+ }});
+
+1;
--- /dev/null
+include ../../defines.mk
+
+PERLSOURCE = \
+ Cluster.pm \
+ Nodes.pm \
+ Tasks.pm \
+ Network.pm \
+ Services.pm
+
+all:
+
+.PHONY: distclean
+distclean: clean
+
+.PHONY: clean
+clean:
+ rm -rf *~
+
+.PHONY: install
+install: ${PERLSOURCE}
+ install -d ${PERLLIBDIR}/PVE/API2
+ install -m 0644 ${PERLSOURCE} ${PERLLIBDIR}/PVE/API2
--- /dev/null
+package PVE::API2::Network;
+
+use strict;
+use warnings;
+
+use PVE::Tools qw(extract_param);
+use PVE::SafeSyslog;
+use PVE::INotify;
+use PVE::Exception qw(raise_param_exc);
+use PVE::RESTHandler;
+use PVE::RPCEnvironment;
+use PVE::JSONSchema qw(get_standard_option);
+use PVE::AccessControl;
+use IO::File;
+
+use base qw(PVE::RESTHandler);
+
+my $iflockfn = "/etc/network/.pve-interfaces.lock";
+
+my $bond_mode_enum = [
+ 'balance-rr',
+ 'active-backup',
+ 'balance-xor',
+ 'broadcast',
+ '802.3ad',
+ 'balance-tlb',
+ 'balance-alb'
+ ];
+
+my $confdesc = {
+ autostart => {
+ description => "Automatically start interface on boot.",
+ type => 'boolean',
+ optional => 1,
+ },
+ bridge_ports => {
+ description => "Specify the iterfaces you want to add to your bridge.",
+ optional => 1,
+ type => 'string', format => 'pve-iface-list',
+ },
+ slaves => {
+ description => "Specify the interfaces used by the bonding device.",
+ optional => 1,
+ type => 'string', format => 'pve-iface-list',
+ },
+ bond_mode => {
+ description => "Bonding mode.",
+ optional => 1,
+ type => 'string', enum => $bond_mode_enum,
+ },
+ gateway => {
+ description => 'Default gateway address.',
+ type => 'string', format => 'ipv4',
+ optional => 1,
+ },
+ netmask => {
+ description => 'Network mask.',
+ type => 'string', format => 'ipv4mask',
+ optional => 1,
+ },
+ address => {
+ description => 'IP address.',
+ type => 'string', format => 'ipv4',
+ optional => 1,
+ requires => 'netmask',
+ }
+};
+
+sub json_config_properties {
+ my $prop = shift;
+
+ foreach my $opt (keys %$confdesc) {
+ $prop->{$opt} = $confdesc->{$opt};
+ }
+
+ return $prop;
+}
+
+__PACKAGE__->register_method({
+ name => 'index',
+ path => '',
+ method => 'GET',
+ permissions => { user => 'all' },
+ description => "List available networks",
+ proxyto => 'node',
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ type => {
+ description => "Only list specific interface types.",
+ type => 'string',
+ enum => ['bond', 'bridge', 'alias', 'eth'],
+ optional => 1,
+ },
+ },
+ },
+ returns => {
+ type => "array",
+ items => {
+ type => "object",
+ properties => {},
+ },
+ links => [ { rel => 'child', href => "{iface}" } ],
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $config = PVE::INotify::read_file('interfaces');
+
+ delete $config->{lo}; # do not list the loopback device
+
+ if ($param->{type}) {
+ foreach my $k (keys %$config) {
+ delete $config->{$k} if $param->{type} ne $config->{$k}->{type};
+ }
+ }
+
+ return PVE::RESTHandler::hash_to_array($config, 'iface');
+ }});
+
+
+my $check_duplicate_gateway = sub {
+ my ($config, $newiface) = @_;
+
+ foreach my $iface (keys %$config) {
+ raise_param_exc({ gateway => "Default gateway already exists on interface '$iface'." })
+ if ($newiface ne $iface) && $config->{$iface}->{gateway};
+ }
+};
+
+
+__PACKAGE__->register_method({
+ name => 'create_network',
+ path => '',
+ method => 'POST',
+ permissions => {
+ path => '/nodes/{node}',
+ privs => [ 'Sys.Modify' ],
+ },
+ description => "Create network device configuration",
+ protected => 1,
+ proxyto => 'node',
+ parameters => {
+ additionalProperties => 0,
+ properties => json_config_properties({
+ node => get_standard_option('pve-node'),
+ iface => get_standard_option('pve-iface')}),
+ },
+ returns => { type => 'null' },
+ code => sub {
+ my ($param) = @_;
+
+ my $node = extract_param($param, 'node');
+ my $iface = extract_param($param, 'iface');
+
+ my $code = sub {
+ my $config = PVE::INotify::read_file('interfaces');
+
+ raise_param_exc({ iface => "interface already exists" })
+ if $config->{$iface};
+
+ &$check_duplicate_gateway($config, $iface)
+ if $param->{gateway};
+
+ $param->{method} = $param->{address} ? 'static' : 'manual';
+
+ $config->{$iface} = $param;
+
+ PVE::INotify::write_file('interfaces', $config);
+ };
+
+ PVE::Tools::lock_file($iflockfn, 10, $code);
+ die $@ if $@;
+
+ return undef;
+ }});
+
+__PACKAGE__->register_method({
+ name => 'update_network',
+ path => '{iface}',
+ method => 'PUT',
+ permissions => {
+ path => '/nodes/{node}',
+ privs => [ 'Sys.Modify' ],
+ },
+ description => "Update network device configuration",
+ protected => 1,
+ proxyto => 'node',
+ parameters => {
+ additionalProperties => 0,
+ properties => json_config_properties({
+ node => get_standard_option('pve-node'),
+ iface => get_standard_option('pve-iface'),
+ delete => {
+ type => 'string', format => 'pve-configid-list',
+ description => "A list of settings you want to delete.",
+ optional => 1,
+ }}),
+ },
+ returns => { type => 'null' },
+ code => sub {
+ my ($param) = @_;
+
+ my $node = extract_param($param, 'node');
+ my $iface = extract_param($param, 'iface');
+ my $delete = extract_param($param, 'delete');
+
+ my $code = sub {
+ my $config = PVE::INotify::read_file('interfaces');
+
+ raise_param_exc({ iface => "interface does not exist" })
+ if !$config->{$iface};
+
+ foreach my $k (PVE::Tools::split_list($delete)) {
+ delete $config->{$iface}->{$k};
+ }
+
+ &$check_duplicate_gateway($config, $iface)
+ if $param->{gateway};
+
+ $param->{method} = $param->{address} ? 'static' : 'manual';
+
+ foreach my $k (keys %$param) {
+ $config->{$iface}->{$k} = $param->{$k};
+ }
+
+ PVE::INotify::write_file('interfaces', $config);
+ };
+
+ PVE::Tools::lock_file($iflockfn, 10, $code);
+ die $@ if $@;
+
+ return undef;
+ }});
+
+__PACKAGE__->register_method({
+ name => 'network_config',
+ path => '{iface}',
+ method => 'GET',
+ permissions => {
+ path => '/nodes/{node}',
+ privs => [ 'Sys.Audit' ],
+ },
+ description => "Read network device configuration",
+ proxyto => 'node',
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ iface => get_standard_option('pve-iface'),
+ },
+ },
+ returns => {
+ type => "object",
+ properties => {
+ type => {
+ type => 'string',
+ },
+ method => {
+ type => 'string',
+ },
+ },
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $config = PVE::INotify::read_file('interfaces');
+
+ raise_param_exc({ iface => "interface does not exist" })
+ if !$config->{$param->{iface}};
+
+ return $config->{$param->{iface}};
+ }});
+
+__PACKAGE__->register_method({
+ name => 'delete_network',
+ path => '{iface}',
+ method => 'DELETE',
+ permissions => {
+ path => '/nodes/{node}',
+ privs => [ 'Sys.Modify' ],
+ },
+ description => "Delete network device configuration",
+ protected => 1,
+ proxyto => 'node',
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ iface => get_standard_option('pve-iface'),
+ },
+ },
+ returns => { type => 'null' },
+ code => sub {
+ my ($param) = @_;
+
+ my $code = sub {
+ my $config = PVE::INotify::read_file('interfaces');
+
+ raise_param_exc({ iface => "interface does not exist" })
+ if !$config->{$param->{iface}};
+
+ delete $config->{$param->{iface}};
+
+ PVE::INotify::write_file('interfaces', $config);
+ };
+
+ PVE::Tools::lock_file($iflockfn, 10, $code);
+ die $@ if $@;
+
+ return undef;
+ }});
+
+
+
--- /dev/null
+package PVE::API2::Nodes::Nodeinfo;
+
+use strict;
+use warnings;
+use POSIX;
+use Filesys::Df;
+use Time::Local qw(timegm_nocheck);
+use PVE::pvecfg;
+use PVE::Tools;
+use PVE::ProcFSTools;
+use PVE::SafeSyslog;
+use PVE::Cluster;
+use PVE::INotify;
+use PVE::RESTHandler;
+use PVE::RPCEnvironment;
+use PVE::JSONSchema qw(get_standard_option);
+use PVE::AccessControl;
+use PVE::API2::Services;
+use PVE::API2::Network;
+use PVE::API2::Tasks;
+use PVE::API2::Storage::Scan;
+use PVE::API2::Storage::Status;
+use PVE::API2::Qemu;
+use JSON;
+
+use base qw(PVE::RESTHandler);
+
+__PACKAGE__->register_method ({
+ subclass => "PVE::API2::Qemu",
+ path => 'qemu',
+});
+
+__PACKAGE__->register_method ({
+ subclass => "PVE::API2::Services",
+ path => 'services',
+});
+
+__PACKAGE__->register_method ({
+ subclass => "PVE::API2::Network",
+ path => 'network',
+});
+
+__PACKAGE__->register_method ({
+ subclass => "PVE::API2::Tasks",
+ path => 'tasks',
+});
+
+__PACKAGE__->register_method ({
+ subclass => "PVE::API2::Storage::Scan",
+ path => 'scan',
+});
+
+__PACKAGE__->register_method ({
+ subclass => "PVE::API2::Storage::Status",
+ path => 'storage',
+});
+
+__PACKAGE__->register_method ({
+ name => 'index',
+ path => '',
+ method => 'GET',
+ permissions => { user => 'all' },
+ description => "Node index.",
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ },
+ },
+ returns => {
+ type => 'array',
+ items => {
+ type => "object",
+ properties => {},
+ },
+ links => [ { rel => 'child', href => "{name}" } ],
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $result = [
+ { name => 'syslog' },
+ { name => 'status' },
+ { name => 'tasks' },
+ { name => 'rrd' }, # fixme: remove?
+ { name => 'rrddata' },# fixme: remove?
+ { name => 'vncshell' },
+ { name => 'time' },
+ { name => 'dns' },
+ { name => 'services' },
+ { name => 'scan' },
+ { name => 'storage' },
+ { name => 'upload' },
+ { name => 'qemu' },
+ { name => 'network' },
+ { name => 'network_changes' },
+ ];
+
+ return $result;
+ }});
+
+__PACKAGE__->register_method({
+ name => 'network_changes',
+ path => 'network_changes',
+ method => 'GET',
+ permissions => {
+ path => '/nodes/{node}',
+ privs => [ 'Sys.Audit' ],
+ },
+ description => "Get network configuration changes (diff) since last boot.",
+ proxyto => 'node',
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ },
+ },
+ returns => { type => "string" },
+ code => sub {
+ my ($param) = @_;
+
+ my $res = PVE::INotify::read_file('interfaces', 1);
+
+ return $res->{changes} || '';
+ }});
+
+__PACKAGE__->register_method({
+ name => 'revert_network_changes',
+ path => 'network_changes',
+ method => 'DELETE',
+ permissions => {
+ path => '/nodes/{node}',
+ privs => [ 'Sys.Modify' ],
+ },
+ protected => 1,
+ description => "Revert network configuration changes.",
+ proxyto => 'node',
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ },
+ },
+ returns => { type => "null" },
+ code => sub {
+ my ($param) = @_;
+
+ unlink "/etc/network/interfaces.new";
+
+ return undef;
+ }});
+
+__PACKAGE__->register_method({
+ name => 'status',
+ path => 'status',
+ method => 'GET',
+ permissions => {
+ path => '/nodes/{node}',
+ privs => [ 'Sys.Audit' ],
+ },
+ description => "Read node status",
+ proxyto => 'node',
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ },
+ },
+ returns => {
+ type => "object",
+ properties => {
+
+ },
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $res = {
+ uptime => 0,
+ idle => 0,
+ };
+
+ my ($uptime, $idle) = PVE::ProcFSTools::read_proc_uptime();
+ $res->{uptime} = $uptime;
+
+ my ($avg1, $avg5, $avg15) = PVE::ProcFSTools::read_loadavg();
+ $res->{loadavg} = [ $avg1, $avg5, $avg15];
+
+ my ($sysname, $nodename, $release, $version, $machine) = POSIX::uname();
+
+ $res->{kversion} = "$sysname $release $version";
+
+ $res->{cpuinfo} = PVE::ProcFSTools::read_cpuinfo();
+
+ my $stat = PVE::ProcFSTools::read_proc_stat();
+ $res->{cpu} = $stat->{cpu};
+ $res->{wait} = $stat->{wait};
+
+ my $meminfo = PVE::ProcFSTools::read_meminfo();
+ $res->{memory} = {
+ free => $meminfo->{memfree},
+ total => $meminfo->{memtotal},
+ used => $meminfo->{memused},
+ };
+ $res->{swap} = {
+ free => $meminfo->{swapfree},
+ total => $meminfo->{swaptotal},
+ used => $meminfo->{swapused},
+ };
+
+ $res->{pveversion} = PVE::pvecfg::package() . "/" .
+ PVE::pvecfg::version() . "/" .
+ PVE::pvecfg::repoid();
+
+ my $dinfo = df('/', 1); # output is bytes
+
+ $res->{rootfs} = {
+ total => $dinfo->{blocks},
+ avail => $dinfo->{bavail},
+ used => $dinfo->{used},
+ free => $dinfo->{bavail} - $dinfo->{used},
+ };
+
+ return $res;
+ }});
+
+__PACKAGE__->register_method({
+ name => 'node_cmd',
+ path => 'status',
+ method => 'POST',
+ permissions => {
+ path => '/nodes/{node}',
+ privs => [ 'Sys.PowerMgmt' ],
+ },
+ protected => 1,
+ description => "Reboot or shutdown a node.",
+ proxyto => 'node',
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ command => {
+ description => "Specify the command.",
+ type => 'string',
+ enum => [qw(reboot shutdown)],
+ },
+ },
+ },
+ returns => { type => "null" },
+ code => sub {
+ my ($param) = @_;
+
+ if ($param->{command} eq 'reboot') {
+ system ("(sleep 2;/sbin/reboot)&");
+ } elsif ($param->{command} eq 'shutdown') {
+ system ("(sleep 2;/sbin/poweroff)&");
+ }
+
+ return undef;
+ }});
+
+
+__PACKAGE__->register_method({
+ name => 'rrd',
+ path => 'rrd',
+ method => 'GET',
+ protected => 1, # fixme: can we avoid that?
+ permissions => {
+ path => '/nodes/{node}',
+ privs => [ 'Sys.Audit' ],
+ },
+ description => "Read node RRD statistics (returns PNG)",
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ timeframe => {
+ description => "Specify the time frame you are interested in.",
+ type => 'string',
+ enum => [ 'hour', 'day', 'week', 'month', 'year' ],
+ },
+ ds => {
+ description => "The list of datasources you want to display.",
+ type => 'string', format => 'pve-configid-list',
+ },
+ cf => {
+ description => "The RRD consolidation function",
+ type => 'string',
+ enum => [ 'AVERAGE', 'MAX' ],
+ optional => 1,
+ },
+ },
+ },
+ returns => {
+ type => "object",
+ properties => {
+ filename => { type => 'string' },
+ },
+ },
+ code => sub {
+ my ($param) = @_;
+
+ return PVE::Cluster::create_rrd_graph(
+ "pve2-node/$param->{node}", $param->{timeframe},
+ $param->{ds}, $param->{cf});
+
+ }});
+
+__PACKAGE__->register_method({
+ name => 'rrddata',
+ path => 'rrddata',
+ method => 'GET',
+ protected => 1, # fixme: can we avoid that?
+ permissions => {
+ path => '/nodes/{node}',
+ privs => [ 'Sys.Audit' ],
+ },
+ description => "Read node RRD statistics",
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ timeframe => {
+ description => "Specify the time frame you are interested in.",
+ type => 'string',
+ enum => [ 'hour', 'day', 'week', 'month', 'year' ],
+ },
+ cf => {
+ description => "The RRD consolidation function",
+ type => 'string',
+ enum => [ 'AVERAGE', 'MAX' ],
+ optional => 1,
+ },
+ },
+ },
+ returns => {
+ type => "array",
+ items => {
+ type => "object",
+ properties => {},
+ },
+ },
+ code => sub {
+ my ($param) = @_;
+
+ return PVE::Cluster::create_rrd_data(
+ "pve2-node/$param->{node}", $param->{timeframe}, $param->{cf});
+ }});
+
+__PACKAGE__->register_method({
+ name => 'syslog',
+ path => 'syslog',
+ method => 'GET',
+ description => "Read system log",
+ proxyto => 'node',
+ permissions => {
+ path => '/nodes/{node}',
+ privs => [ 'Sys.Syslog' ],
+ },
+ protected => 1,
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ start => {
+ type => 'integer',
+ minimum => 0,
+ optional => 1,
+ },
+ limit => {
+ type => 'integer',
+ minimum => 0,
+ optional => 1,
+ },
+ },
+ },
+ returns => {
+ type => 'array',
+ items => {
+ type => "object",
+ properties => {
+ n => {
+ description=> "Line number",
+ type=> 'integer',
+ },
+ t => {
+ description=> "Line text",
+ type => 'string',
+ }
+ }
+ }
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $lines = [];
+
+ my $rpcenv = PVE::RPCEnvironment::get();
+ my $user = $rpcenv->get_user();
+ my $node = $param->{node};
+
+ my $fh = IO::File->new("/var/log/syslog", "r");
+ die "unable to open file - $!" if !$fh;
+
+ my $start = $param->{start} || 0;
+ my $limit = $param->{limit} || 50;
+ my $count = 0;
+ my $line;
+ while (defined ($line = <$fh>)) {
+ next if $count++ < $start;
+ next if $limit <= 0;
+ chomp $line;
+ push @$lines, { n => $count, t => $line};
+ $limit--;
+ }
+
+ close($fh);
+
+ # HACK: ExtJS store.guaranteeRange() does not like empty array
+ # so we add a line
+ if (!$count) {
+ $count++;
+ push @$lines, { n => $count, t => "no content"};
+ }
+
+ $rpcenv->set_result_count($count);
+
+ return $lines;
+ }});
+
+my $sslcert;
+
+__PACKAGE__->register_method ({
+ name => 'vncshell',
+ path => 'vncshell',
+ method => 'POST',
+ protected => 1,
+ permissions => {
+ path => '/nodes/{node}',
+ privs => [ 'Sys.Console' ],
+ },
+ description => "Creates a VNC Shell proxy.",
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ },
+ },
+ returns => {
+ additionalProperties => 0,
+ properties => {
+ user => { type => 'string' },
+ ticket => { type => 'string' },
+ cert => { type => 'string' },
+ port => { type => 'integer' },
+ upid => { type => 'string' },
+ },
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $rpcenv = PVE::RPCEnvironment::get();
+
+ my $user = $rpcenv->get_user();
+
+ my $ticket = PVE::AccessControl::assemble_ticket($user);
+
+ my $node = $param->{node};
+
+ $sslcert = PVE::Tools::file_get_contents("/etc/pve/pve-root-ca.pem", 8192)
+ if !$sslcert;
+
+ my $port = PVE::Tools::next_vnc_port();
+
+ my $remip;
+
+ if ($node ne PVE::INotify::nodename()) {
+ $remip = PVE::Cluster::remote_node_ip($node);
+ }
+
+ # NOTE: vncterm VNC traffic is already TLS encrypted,
+ # so we select the fastest chipher here (or 'none'?)
+ my $remcmd = $remip ?
+ ['/usr/bin/ssh', '-c', 'blowfish-cbc', '-t', $remip] : [];
+
+ my $shcmd = $user eq 'root@pam' ? [ "/bin/bash", "-l" ] : [ "/bin/login" ];
+
+ my $timeout = 10;
+
+ # fixme: do we want to require special auth permissions?
+ # example "-perm Shell"
+ my @cmd = ('/usr/bin/vncterm', '-rfbport', $port,
+ '-timeout', $timeout, '-authpath', "/nodes/$node",
+ '-perm', 'Sys.Console', '-c', @$remcmd, @$shcmd);
+
+ my $realcmd = sub {
+ my $upid = shift;
+
+ syslog ('info', "starting vnc proxy $upid\n");
+
+ my $cmdstr = join (' ', @cmd);
+ syslog ('info', "launch command: $cmdstr");
+
+ if (system(@cmd) != 0) {
+ my $msg = "vncterm failed - $?";
+ syslog ('err', $msg);
+ return;
+ }
+
+ return;
+ };
+
+ my $upid = $rpcenv->fork_worker('vncshell', "", $user, $realcmd);
+
+ return {
+ user => $user,
+ ticket => $ticket,
+ port => $port,
+ upid => $upid,
+ cert => $sslcert,
+ };
+ }});
+
+__PACKAGE__->register_method({
+ name => 'dns',
+ path => 'dns',
+ method => 'GET',
+ permissions => {
+ path => '/nodes/{node}',
+ privs => [ 'Sys.Audit' ],
+ },
+ description => "Read DNS settings.",
+ proxyto => 'node',
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ },
+ },
+ returns => {
+ type => "object",
+ additionalProperties => 0,
+ properties => {
+ search => {
+ description => "Search domain for host-name lookup.",
+ type => 'string',
+ optional => 1,
+ },
+ dns1 => {
+ description => 'First name server IP address.',
+ type => 'string',
+ optional => 1,
+ },
+ dns2 => {
+ description => 'Second name server IP address.',
+ type => 'string',
+ optional => 1,
+ },
+ dns3 => {
+ description => 'Third name server IP address.',
+ type => 'string',
+ optional => 1,
+ },
+ },
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $res = PVE::INotify::read_file('resolvconf');
+
+ return $res;
+ }});
+
+__PACKAGE__->register_method({
+ name => 'update_dns',
+ path => 'dns',
+ method => 'PUT',
+ description => "Write DNS settings.",
+ proxyto => 'node',
+ protected => 1,
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ search => {
+ description => "Search domain for host-name lookup.",
+ type => 'string',
+ },
+ dns1 => {
+ description => 'First name server IP address.',
+ type => 'string', format => 'ipv4',
+ optional => 1,
+ },
+ dns2 => {
+ description => 'Second name server IP address.',
+ type => 'string', format => 'ipv4',
+ optional => 1,
+ },
+ dns3 => {
+ description => 'Third name server IP address.',
+ type => 'string', format => 'ipv4',
+ optional => 1,
+ },
+ },
+ },
+ returns => { type => "null" },
+ code => sub {
+ my ($param) = @_;
+
+ PVE::INotify::update_file('resolvconf', $param);
+
+ return undef;
+ }});
+
+__PACKAGE__->register_method({
+ name => 'time',
+ path => 'time',
+ method => 'GET',
+ permissions => {
+ path => '/nodes/{node}',
+ privs => [ 'Sys.Audit' ],
+ },
+ description => "Read server time and time zone settings.",
+ proxyto => 'node',
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ },
+ },
+ returns => {
+ type => "object",
+ additionalProperties => 0,
+ properties => {
+ timezone => {
+ description => "Time zone",
+ type => 'string',
+ },
+ time => {
+ description => "Seconds since 1970-01-01 00:00:00 UTC.",
+ type => 'integer',
+ minimum => 1297163644,
+ },
+ localtime => {
+ description => "Seconds since 1970-01-01 00:00:00 (local time)",
+ type => 'integer',
+ minimum => 1297163644,
+ },
+ },
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $ctime = time();
+ my $ltime = timegm_nocheck(localtime($ctime));
+ my $res = {
+ timezone => PVE::INotify::read_file('timezone'),
+ time => time(),
+ localtime => $ltime,
+ };
+
+ return $res;
+ }});
+
+__PACKAGE__->register_method({
+ name => 'set_timezone',
+ path => 'time',
+ method => 'PUT',
+ description => "Set time zone.",
+ proxyto => 'node',
+ protected => 1,
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ timezone => {
+ description => "Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names.",
+ type => 'string',
+ },
+ },
+ },
+ returns => { type => "null" },
+ code => sub {
+ my ($param) = @_;
+
+ PVE::INotify::write_file('timezone', $param->{timezone});
+
+ return undef;
+ }});
+
+__PACKAGE__->register_method ({
+ name => 'upload',
+ path => 'upload',
+ method => 'POST',
+ permissions => {
+ path => '/storage/{storage}',
+ privs => [ 'Datastore.AllocateSpace' ],
+ },
+ description => "Upload content.",
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ storage => get_standard_option('pve-storage-id'),
+ filename => {
+ description => "The name of the file to create/upload.",
+ type => 'string',
+ },
+ vmid => get_standard_option
+ ('pve-vmid', {
+ description => "Specify owner VM",
+ optional => 1,
+ }),
+ },
+ },
+ returns => {
+ description => "Volume identifier",
+ type => 'string',
+ },
+ code => sub {
+ my ($param) = @_;
+
+ # todo: can we proxy file uploads to remote nodes?
+ if ($param->{node} ne PVE::INotify::nodename()) {
+ raise_param_exc({ node => "can't upload content to remote node" });
+ }
+
+ my $node = $param->{node};
+ my $storeid = $param->{storage};
+ my $name = $param->{filename};
+
+ my $fh = CGI::upload('filename') || die "unable to get file handle\n";
+
+ syslog ('info', "UPLOAD $name to $node $storeid");
+
+ # fixme:
+ die "upload not implemented\n";
+
+ my $buffer = "";
+ my $tmpname = "/tmp/proxmox_upload-$$.bin";
+
+ eval {
+ open FILE, ">$tmpname" || die "can't open temporary file '$tmpname' - $!\n";
+ while (read($fh, $buffer, 32768)) {
+ die "write failed - $!" unless print FILE $buffer;
+ }
+ close FILE || die " can't close temporary file '$tmpname' - $!\n";
+ };
+ my $err = $@;
+
+ if ($err) {
+ unlink $tmpname;
+ die $err;
+ }
+
+ unlink $tmpname; # fixme: proxy to local host import
+
+ # fixme: return volid
+
+ return undef;
+
+ }});
+
+package PVE::API2::Nodes;
+
+use strict;
+use warnings;
+
+use PVE::SafeSyslog;
+use PVE::Cluster;
+use PVE::RESTHandler;
+use PVE::RPCEnvironment;
+
+use base qw(PVE::RESTHandler);
+
+__PACKAGE__->register_method ({
+ subclass => "PVE::API2::Nodes::Nodeinfo",
+ path => '{node}',
+});
+
+__PACKAGE__->register_method ({
+ name => 'index',
+ path => '',
+ method => 'GET',
+ permissions => { user => 'all' },
+ description => "Cluster node index.",
+ parameters => {
+ additionalProperties => 0,
+ properties => {},
+ },
+ returns => {
+ type => 'array',
+ items => {
+ type => "object",
+ properties => {},
+ },
+ links => [ { rel => 'child', href => "{name}" } ],
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $clinfo = PVE::Cluster::get_clinfo();
+ my $res = [];
+
+ my $nodename = PVE::INotify::nodename();
+ my $nodelist = $clinfo->{nodelist};
+
+ my $rrd = PVE::Cluster::rrd_dump();
+
+ my @nodes = $nodelist ? (keys %$nodelist) : $nodename;
+
+ foreach my $node (@nodes) {
+ my $entry = { name => $node };
+ if (my $d = $rrd->{"pve2-node/$node"}) {
+
+ $entry->{uptime} = $d->[0];
+ $entry->{maxcpu} = $d->[3];
+ $entry->{cpu} = $d->[4];
+ $entry->{maxmem} = $d->[6];
+ $entry->{mem} = $d->[7];
+ $entry->{maxdisk} = $d->[10];
+ $entry->{disk} = $d->[11];
+ }
+
+ push @$res, $entry;
+ }
+
+ return $res;
+ }});
+
+1;
--- /dev/null
+package PVE::API2::Services;
+
+use strict;
+use warnings;
+
+use PVE::Tools;
+use PVE::SafeSyslog;
+use PVE::Cluster;
+use PVE::INotify;
+use PVE::Exception qw(raise_param_exc);
+use PVE::RESTHandler;
+use PVE::RPCEnvironment;
+use PVE::JSONSchema qw(get_standard_option);
+use PVE::AccessControl;
+use IO::File;
+
+use base qw(PVE::RESTHandler);
+
+my $service_list = {
+ apache => { name => 'WWW', desc => 'Web/API server' },
+ postfix => { name => 'SMTP', desc => 'Simple Mail Tranfer Protocol' },
+ ntpd => { name => 'NTP', desc => 'Network time protocol' },
+ sshd => { name => 'SSH', desc => 'Secure shell daemon' },
+ syslog => { name => 'Syslog', desc => 'Syslog daemon' },
+ cron => { name => 'CRON', desc => 'Daemon to execute scheduled commands' },
+ pvedaemon => { name => 'NodeManager', desc => 'PVE node manager daemon' },
+ corosync => { name => 'Corosync', desc => 'Corosync cluster daemon' },
+ pvecluster => { name => 'PVECluster', desc => 'Proxmox VE cluster file system' },
+};
+
+my $service_cmd = sub {
+ my ($service, $cmd) = @_;
+
+ my $initd_cmd;
+
+ die "unknown service command '$cmd'\n"
+ if $cmd !~ m/^(start|stop|restart|reload)$/;
+
+ $cmd = $1; # untaint
+
+ if ($service eq 'postfix') {
+ $initd_cmd = '/etc/init.d/postfix';
+ } elsif ($service eq 'pvecluster') {
+ if ($cmd eq 'restart') {
+ $initd_cmd = '/etc/init.d/pve-cluster';
+ } else {
+ die "invalid service cmd 'pve-cluster $cmd': ERROR";
+ }
+ } elsif ($service eq 'pvedaemon') {
+ if ($cmd eq 'restart') {
+ $initd_cmd = '/etc/init.d/pvedaemon';
+ } else {
+ die "invalid service cmd '$service $cmd': ERROR";
+ }
+ } elsif ($service eq 'apache') {
+ if ($cmd eq 'restart') {
+ $initd_cmd = '/usr/sbin/apache2ctl';
+ $cmd = 'graceful';
+ } else {
+ die "invalid service cmd '$service $cmd': ERROR";
+ }
+ } elsif ($service eq 'ntpd') {
+ # debian start/stop scripts does not work for us
+ if ($cmd eq 'stop') {
+ system ('/etc/init.d/ntp stop');
+ #system ('/usr/bin/killall /usr/sbin/ntpd');
+ } elsif ($cmd eq 'start') {
+ system ('/etc/init.d/ntp start');
+ system ('/sbin/hwclock --systohc');
+ } elsif ($cmd eq 'restart') {
+ system ('/etc/init.d/ntp restart');
+ system ('/sbin/hwclock --systohc');
+ # restart cron/syslog to get right schedules and log time/dates
+ system ('/etc/init.d/rsyslog restart');
+ system ('/etc/init.d/cron restart');
+ }
+ return 0;
+ } elsif ($service eq 'syslog') {
+ $initd_cmd = '/etc/init.d/rsyslog';
+ } elsif ($service eq 'cron') {
+ $initd_cmd = '/etc/init.d/cron';
+ } elsif ($service eq 'corosync') {
+ $initd_cmd = '/etc/init.d/cman';
+ } elsif ($service eq 'sshd') {
+ $initd_cmd = '/etc/init.d/ssh';
+ } else {
+ die "unknown service '$service': ERROR";
+ }
+
+ PVE::Tools::run_command ([$initd_cmd, $cmd]);
+};
+
+my $service_state = sub {
+ my ($service) = @_;
+
+ my $pid_file;
+
+ if ($service eq 'postfix') {
+ $pid_file = '/var/spool/postfix/pid/master.pid';
+ } elsif ($service eq 'apache') {
+ $pid_file = '/var/run/apache2.pid';
+ } elsif ($service eq 'pvedaemon') {
+ $pid_file = '/var/run/pvedaemon.pid';
+ } elsif ($service eq 'pvecluster') {
+ $pid_file = '/var/run/pve-cluster.pid';
+ } elsif ($service eq 'ntpd') {
+ $pid_file = '/var/run/ntpd.pid';
+ } elsif ($service eq 'sshd') {
+ $pid_file = '/var/run/sshd.pid';
+ } elsif ($service eq 'cron') {
+ $pid_file = '/var/run/crond.pid';
+ } elsif ($service eq 'corosync') {
+ $pid_file = '/var/run/corosync.pid';
+ } elsif ($service eq 'syslog') {
+ $pid_file = '/var/run/rsyslogd.pid';
+ } else {
+ die "unknown service '$service': ERROR";
+ }
+
+ my $pid;
+ if (my $fh = IO::File->new ($pid_file, "r")) {
+ my $line = <$fh>;
+ chomp $line;
+
+ if ($line && ($line =~ m/^\s*(\d+)\s*$/)) {
+ $pid = $1;
+ }
+ }
+
+ return 'running' if ($pid && kill (0, $pid));
+
+ return 'stopped';
+};
+
+__PACKAGE__->register_method ({
+ name => 'index',
+ path => '',
+ method => 'GET',
+ permissions => {
+ path => '/nodes/{node}',
+ privs => [ 'Sys.Audit' ],
+ },
+ description => "Service list.",
+ proxyto => 'node',
+ protected => 1,
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ },
+ },
+ returns => {
+ type => 'array',
+ items => {
+ type => "object",
+ properties => {},
+ },
+ links => [ { rel => 'child', href => "{service}" } ],
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $res = [];
+
+ foreach my $id (keys %{$service_list}) {
+ push @$res, {
+ service => $id,
+ name => $service_list->{$id}->{name},
+ desc => $service_list->{$id}->{desc},
+ state => &$service_state($id),
+ };
+ }
+
+ return $res;
+ }});
+
+__PACKAGE__->register_method ({
+ name => 'state',
+ path => '{service}',
+ method => 'GET',
+ permissions => {
+ path => '/nodes/{node}',
+ privs => [ 'Sys.Audit' ],
+ },
+ description => "Read service properties",
+ proxyto => 'node',
+ protected => 1,
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ service => {
+ description => "Service ID",
+ type => 'string',
+ enum => [ keys %{$service_list} ],
+ },
+ },
+ },
+ returns => {
+ type => "object",
+ properties => {},
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $si = $service_list->{$param->{service}};
+ return {
+ service => $param->{service},
+ name => $si->{name},
+ desc => $si->{desc},
+ state => &$service_state($param->{service}),
+ };
+ }});
+
+__PACKAGE__->register_method ({
+ name => 'cmd',
+ path => '{service}',
+ method => 'PUT',
+ description => "Execute service commands.",
+ proxyto => 'node',
+ protected => 1,
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ service => {
+ description => "Service ID",
+ type => 'string',
+ enum => [ keys %{$service_list} ],
+ },
+ command => {
+ description => "The command to execute. The only valid command for service 'apache' and 'pvedaemon' is 'restart', because both services are required by this API.",
+ type => 'string',
+ enum => [qw(start stop restart reload)],
+ },
+ },
+ },
+ returns => { type => 'null'},
+ code => sub {
+ my ($param) = @_;
+
+ my $si = $service_list->{$param->{service}};
+ &$service_cmd($param->{service}, $param->{command});
+
+ return undef;
+ }});
--- /dev/null
+package PVE::API2::Tasks;
+
+use strict;
+use warnings;
+use POSIX;
+use IO::File;
+use File::ReadBackwards;
+use PVE::Tools;
+use PVE::SafeSyslog;
+use PVE::RESTHandler;
+use PVE::ProcFSTools;
+use PVE::RPCEnvironment;
+use PVE::JSONSchema qw(get_standard_option);
+use PVE::AccessControl;
+
+use base qw(PVE::RESTHandler);
+
+__PACKAGE__->register_method({
+ name => 'node_tasks',
+ path => '',
+ method => 'GET',
+ permissions => { user => 'all' },
+ description => "Read task list for one node (finished tasks).",
+ proxyto => 'node',
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ start => {
+ type => 'integer',
+ minimum => 0,
+ optional => 1,
+ },
+ limit => {
+ type => 'integer',
+ minimum => 0,
+ optional => 1,
+ },
+ userfilter => {
+ type => 'string',
+ optional => 1,
+ },
+ errors => {
+ type => 'boolean',
+ optional => 1,
+ },
+ },
+ },
+ returns => {
+ type => 'array',
+ items => {
+ type => "object",
+ properties => {
+ upid => { type => 'string' },
+ },
+ },
+ links => [ { rel => 'child', href => "{upid}" } ],
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my $rpcenv = PVE::RPCEnvironment::get();
+ my $user = $rpcenv->get_user();
+
+ my $res = [];
+
+ my $filename = "/var/log/pve/tasks/index";
+
+ my $node = $param->{node};
+ my $start = $param->{start} || 0;
+ my $limit = $param->{limit} || 50;
+ my $userfilter = $param->{userfilter};
+ my $errors = $param->{errors};
+
+ my $count = 0;
+ my $line;
+
+ my $auditor = $rpcenv->check($user, "/nodes/$node", [ 'Sys.Audit' ]);
+
+ my $parse_line = sub {
+ if ($line =~ m/^(\S+)(\s([0-9A-Za-z]{8})(\s(\S.*))?)?$/) {
+ my $upid = $1;
+ my $endtime = $3;
+ my $status = $5;
+ if ((my $task = PVE::Tools::upid_decode($upid, 1))) {
+ return if $userfilter && $task->{user} !~ m/\Q$userfilter\E/i;
+ next if !($auditor || $user eq $task->{user});
+
+ return if $errors && $status && $status eq 'OK';
+
+ return if $count++ < $start;
+ return if $limit <= 0;
+
+ $task->{upid} = $upid;
+ $task->{endtime} = hex($endtime) if $endtime;
+ $task->{status} = $status if $status;
+ push @$res, $task;
+ $limit--;
+ }
+ }
+ };
+
+ if (my $bw = File::ReadBackwards->new($filename)) {
+ while (defined ($line = $bw->readline)) {
+ &$parse_line();
+ }
+ $bw->close();
+ }
+ if (my $bw = File::ReadBackwards->new("$filename.1")) {
+ while (defined ($line = $bw->readline)) {
+ &$parse_line();
+ }
+ $bw->close();
+ }
+
+ $rpcenv->set_result_count($count);
+
+ return $res;
+ }});
+
+__PACKAGE__->register_method({
+ name => 'upid_index',
+ path => '{upid}',
+ method => 'GET',
+ description => '', # index helper
+ permissions => { user => 'all' },
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ upid => { type => 'string' },
+ }
+ },
+ returns => {
+ type => 'array',
+ items => {
+ type => "object",
+ properties => {},
+ },
+ links => [ { rel => 'child', href => "{name}" } ],
+ },
+ code => sub {
+ my ($param) = @_;
+
+ return [
+ { name => 'log' },
+ { name => 'status' }
+ ];
+ }});
+
+__PACKAGE__->register_method({
+ name => 'stop_task',
+ path => '{upid}',
+ method => 'DELETE',
+ description => 'Stop a task.',
+ permissions => { user => 'all' },
+ protected => 1,
+ proxyto => 'node',
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ upid => { type => 'string' },
+ }
+ },
+ returns => { type => 'null' },
+ code => sub {
+ my ($param) = @_;
+
+ my ($task, $filename) = PVE::Tools::upid_decode($param->{upid}, 1);
+ raise_param_exc({ upid => "unable to parse worker upid" }) if !$task;
+ raise_param_exc({ upid => "no such task" }) if ! -f $filename;
+
+ my $rpcenv = PVE::RPCEnvironment::get();
+ my $user = $rpcenv->get_user();
+ my $node = $param->{node};
+
+ my $sysadmin = $rpcenv->check($user, "/nodes/$node", [ 'Sys.Console' ]);
+ die "Permission check failed\n"
+ if !($sysadmin || $user eq $task->{user});
+
+ my $pstart = PVE::ProcFSTools::read_proc_starttime($task->{pid});
+ $task->{status} = ($pstart && ($pstart == $task->{pstart})) ?
+ 'running' : 'stopped';
+
+ die "not implemented - fixme";
+
+ return undef;
+ }});
+
+__PACKAGE__->register_method({
+ name => 'read_task_log',
+ path => '{upid}/log',
+ method => 'GET',
+ permissions => { user => 'all' },
+ protected => 1,
+ description => "Read task log.",
+ proxyto => 'node',
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ upid => { type => 'string' },
+ start => {
+ type => 'integer',
+ minimum => 0,
+ optional => 1,
+ },
+ limit => {
+ type => 'integer',
+ minimum => 0,
+ optional => 1,
+ },
+ },
+ },
+ returns => {
+ type => 'array',
+ items => {
+ type => "object",
+ properties => {
+ n => {
+ description=> "Line number",
+ type=> 'integer',
+ },
+ t => {
+ description=> "Line text",
+ type => 'string',
+ }
+ }
+ }
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my ($task, $filename) = PVE::Tools::upid_decode($param->{upid}, 1);
+ raise_param_exc({ upid => "unable to parse worker upid" }) if !$task;
+
+ my $lines = [];
+
+ my $rpcenv = PVE::RPCEnvironment::get();
+ my $user = $rpcenv->get_user();
+ my $node = $param->{node};
+
+ my $auditor = $rpcenv->check($user, "/nodes/$node", [ 'Sys.Audit' ]);
+ die "Permission check failed\n"
+ if !($auditor || $user eq $task->{user});
+
+ my $fh = IO::File->new($filename, "r");
+ raise_param_exc({ upid => "no such task - unable to open file - $!" }) if !$fh;
+
+ my $start = $param->{start} || 0;
+ my $limit = $param->{limit} || 50;
+ my $count = 0;
+ my $line;
+ while (defined ($line = <$fh>)) {
+ next if $count++ < $start;
+ next if $limit <= 0;
+ chomp $line;
+ push @$lines, { n => $count, t => $line};
+ $limit--;
+ }
+
+ close($fh);
+
+ # HACK: ExtJS store.guaranteeRange() does not like empty array
+ # so we add a line
+ if (!$count) {
+ $count++;
+ push @$lines, { n => $count, t => "no content"};
+ }
+
+ $rpcenv->set_result_count($count);
+
+ return $lines;
+ }});
+
+__PACKAGE__->register_method({
+ name => 'read_task_status',
+ path => '{upid}/status',
+ method => 'GET',
+ permissions => { user => 'all' },
+ protected => 1,
+ description => "Read task status.",
+ proxyto => 'node',
+ parameters => {
+ additionalProperties => 0,
+ properties => {
+ node => get_standard_option('pve-node'),
+ upid => { type => 'string' },
+ },
+ },
+ returns => {
+ type => "object",
+ properties => {
+ pid => {
+ type => 'integer'
+ },
+ status => {
+ type => 'string', enum => ['running', 'stopped'],
+ },
+ },
+ },
+ code => sub {
+ my ($param) = @_;
+
+ my ($task, $filename) = PVE::Tools::upid_decode($param->{upid}, 1);
+ raise_param_exc({ upid => "unable to parse worker upid" }) if !$task;
+ raise_param_exc({ upid => "no such task" }) if ! -f $filename;
+
+ my $lines = [];
+
+ my $rpcenv = PVE::RPCEnvironment::get();
+ my $user = $rpcenv->get_user();
+ my $node = $param->{node};
+
+ my $auditor = $rpcenv->check($user, "/nodes/$node", [ 'Sys.Audit' ]);
+ die "Permission check failed\n"
+ if !($auditor || $user eq $task->{user});
+
+ my $pstart = PVE::ProcFSTools::read_proc_starttime($task->{pid});
+ $task->{status} = ($pstart && ($pstart == $task->{pstart})) ?
+ 'running' : 'stopped';
+
+ $task->{upid} = $param->{upid}; # include upid
+
+ return $task;
+ }});
--- /dev/null
+package PVE::API2Client;
+
+use strict;
+use warnings;
+use URI;
+use HTTP::Cookies;
+use LWP::UserAgent;
+use JSON;
+use PVE::API2;
+use Data::Dumper; # fixme: remove
+use HTTP::Request::Common;
+
+sub get {
+ my ($self, $path, $param) = @_;
+
+ return $self->call('GET', $path, $param);
+}
+
+sub post {
+ my ($self, $path, $param) = @_;
+
+ return $self->call('POST', $path, $param);
+}
+
+sub put {
+ my ($self, $path, $param) = @_;
+
+ return $self->call('PUT', $path, $param);
+}
+
+sub delete {
+ my ($self, $path, $param) = @_;
+
+ return $self->call('DELETE', $path, $param);
+}
+
+sub call {
+ my ($self, $method, $path, $param) = @_;
+
+ #print "wrapper called\n";
+
+ my $ticket;
+
+ my $ua = $self->{useragent};
+ my $cj = $self->{cookie_jar};
+
+ $cj->scan(sub {
+ my ($version, $key, $val) = @_;
+ $ticket = $val if $key eq 'PVEAuthCookie';
+ });
+
+ if (!$ticket && $self->{username} && $self->{password}) {
+ my $uri = URI->new();
+ $uri->scheme($self->{protocol});
+ $uri->host($self->{host});
+ $uri->port($self->{port});
+ $uri->path('/api2/json/ticket');
+
+ my $response = $ua->post($uri, {
+ username => $self->{username},
+ password => $self->{password}});
+
+ if (!$response->is_success) {
+ die $response->status_line . "\n";
+ }
+ # the auth cookie should be set now
+ }
+
+ my $uri = URI->new();
+ $uri->scheme($self->{protocol});
+ $uri->host($self->{host});
+ $uri->port($self->{port});
+ $uri->path($path);
+
+ # print $ua->{cookie_jar}->as_string;
+
+ #print "CALL $method : " . $uri->as_string() . "\n";
+
+ my $response;
+ if ($method eq 'GET') {
+ $uri->query_form($param);
+ $response = $ua->request(HTTP::Request::Common::GET($uri));
+ } elsif ($method eq 'POST') {
+ $response = $ua->request(HTTP::Request::Common::POST($uri, Content => $param));
+ } elsif ($method eq 'PUT') {
+ $response = $ua->request(HTTP::Request::Common::PUT($uri, Content => $param));
+ } elsif ($method eq 'DELETE') {
+ $response = $ua->request(HTTP::Request::Common::DELETE($uri));
+ } else {
+ die "method $method not implemented\n";
+ }
+
+ #print "RESP: " . Dumper($response) . "\n";
+
+ if ($response->is_success) {
+ my $ct = $response->header('Content-Type');
+
+ die "got unexpected content type" if $ct ne 'application/json';
+
+ return from_json($response->decoded_content, {utf8 => 1, allow_nonref => 1});
+
+ } else {
+
+ die $response->status_line . "\n";
+
+ }
+}
+
+sub new {
+ my ($class, %param) = @_;
+
+ my $self = {
+ ticket => $param{ticket},
+ username => $param{username},
+ password => $param{password},
+ host => $param{host} || 'localhost',
+ port => $param{port},
+ timeout => $param{timeout} || 60,
+ };
+ bless $self;
+
+ if (!$self->{port}) {
+ $self->{port} = $self->{host} eq 'localhost' ? 85 : 8006;
+ }
+ if (!$self->{protocol}) {
+ $self->{protocol} = $self->{host} eq 'localhost' ? 'http' : 'https';
+ }
+
+ $self->{cookie_jar} = HTTP::Cookies->new (ignore_discard => 1);
+
+ if ($self->{ticket}) {
+ my $domain = "$self->{host}.local" unless $self->{host} =~ /\./;
+ $self->{cookie_jar}->set_cookie(0, 'PVEAuthCookie', $self->{ticket},
+ '/', $domain);
+ }
+
+ $self->{useragent} = LWP::UserAgent->new(
+ cookie_jar => $self->{cookie_jar},
+ protocols_allowed => [ 'http', 'https'],
+ timeout => $self->{timeout},
+ );
+
+ $self->{useragent}->default_header('Accept-Encoding' => 'gzip'); # allow gzip
+
+ return $self;
+}
+
+1;
--- /dev/null
+package PVE::APIDaemon;
+
+use strict;
+use warnings;
+use vars qw(@ISA);
+use PVE::SafeSyslog;
+use PVE::INotify;
+use PVE::RPCEnvironment;
+
+use POSIX qw(EINTR);
+use POSIX ":sys_wait_h";
+use IO::Handle;
+use IO::Select;
+use HTTP::Daemon;
+use HTTP::Status qw(:constants);
+use CGI;
+use Data::Dumper; # fixme: remove
+use PVE::REST;
+use JSON;
+
+# This is a quite simple pre-fork server - only listens to local port
+
+@ISA = qw(HTTP::Daemon);
+
+my $documentroot = "/usr/share/pve-api/root";
+
+my $workers = {};
+
+my $max_workers = 3; # pre-forked worker processes
+my $max_requests = 500; # max requests per worker
+
+
+# some global vars
+my $child_terminate = 0;
+my $child_reload_config = 0;
+
+sub worker_finished {
+ my $cpid = shift;
+
+ syslog ('info', "worker $cpid finished");
+}
+
+sub finish_workers {
+ local $!; local $?;
+ foreach my $cpid (keys %$workers) {
+ my $waitpid = waitpid ($cpid, WNOHANG);
+ if (defined($waitpid) && ($waitpid == $cpid)) {
+ delete ($workers->{$cpid});
+ worker_finished ($cpid);
+ }
+ }
+}
+
+sub test_workers {
+ foreach my $cpid (keys %$workers) {
+ if (!kill(0, $cpid)) {
+ waitpid($cpid, POSIX::WNOHANG());
+ delete $workers->{$cpid};
+ worker_finished ($cpid);
+ }
+ }
+}
+
+sub start_workers {
+ my ($self, $rpcenv) = @_;
+
+ my $count = 0;
+ foreach my $cpid (keys %$workers) {
+ $count++;
+ }
+
+ my $need = $max_workers - $count;
+
+ return if $need <= 0;
+
+ syslog ('info', "starting $need worker(s)");
+
+ while ($need > 0) {
+ my $pid = fork;
+
+ if (!defined ($pid)) {
+ syslog ('err', "can't fork worker");
+ sleep (1);
+ } elsif ($pid) { #parent
+ $workers->{$pid} = 1;
+ $0 = 'pvedaemon worker';
+ syslog ('info', "worker $pid started");
+ $need--;
+ } else {
+ $SIG{TERM} = $SIG{QUIT} = sub {
+ $child_terminate = 1;
+ };
+
+ $SIG{USR1} = sub {
+ $child_reload_config = 1;
+ };
+
+ eval {
+ # try to init inotify
+ PVE::INotify::inotify_init();
+
+ $self->handle_requests($rpcenv);
+ };
+ syslog ('err', $@) if $@;
+
+ exit (0);
+ }
+ }
+}
+
+sub terminate_server {
+
+ syslog('info', "received terminate request");
+
+ foreach my $cpid (keys %$workers) {
+ kill (15, $cpid); # TERM childs
+ }
+
+ # nicely shutdown childs (give them max 10 seconds to shut down)
+ my $previous_alarm = alarm (10);
+ eval {
+ local $SIG{ALRM} = sub { die "Timed Out!\n" };
+
+ while ((my $pid = waitpid (-1, 0)) > 0) {
+ if (defined($workers->{$pid})) {
+ delete ($workers->{$pid});
+ worker_finished ($pid);
+ }
+ }
+
+ };
+ alarm ($previous_alarm);
+
+ foreach my $cpid (keys %$workers) {
+ # KILL childs still alive!
+ if (kill (0, $cpid)) {
+ delete ($workers->{$cpid});
+ syslog("err", "kill worker $cpid");
+ kill (9, $cpid);
+ }
+ }
+
+}
+
+sub new {
+ my $class = shift;
+
+ my $self = $class->SUPER::new(@_) ||
+ die "unable to create socket - $@\n";
+
+ return $self;
+}
+
+sub start_server {
+ my $self = shift;
+
+ my $atfork = sub { close($self); };
+ my $rpcenv = PVE::RPCEnvironment->init('priv', atfork => $atfork);
+
+ eval {
+ my $old_sig_chld = $SIG{CHLD};
+ local $SIG{CHLD} = sub {
+ finish_workers ();
+ &$old_sig_chld(@_) if $old_sig_chld;
+ };
+
+ my $old_sig_term = $SIG{TERM};
+ local $SIG{TERM} = sub {
+ terminate_server ();
+ &$old_sig_term(@_) if $old_sig_term;
+ };
+ local $SIG{QUIT} = sub {
+ terminate_server();
+ &$old_sig_term(@_) if $old_sig_term;
+ };
+
+ local $SIG{USR1} = 'IGNORE';
+
+ local $SIG{HUP} = sub {
+ syslog ("info", "received reload request");
+ foreach my $cpid (keys %$workers) {
+ kill (10, $cpid); # SIGUSR1 childs
+ }
+ };
+
+ for (;;) { # forever
+ $self->start_workers ($rpcenv);
+ sleep (5);
+ $self->test_workers ();
+ }
+ };
+ my $err = $@;
+
+ if ($err) {
+ syslog ('err', "ERROR: $err");
+ }
+}
+
+sub send_error {
+ my ($c, $code, $msg) = @_;
+
+ $c->send_response(HTTP::Response->new($code, $msg));
+}
+
+my $known_methods = {
+ GET => 1,
+ POST => 1,
+ PUT => 1,
+ DELETE => 1,
+};
+
+my $extract_params = sub {
+ my ($r, $method) = @_;
+
+ # NOTE: HTTP::Request::Params return undef instead of ''
+ #my $parser = HTTP::Request::Params->new({req => $r});
+ #my $params = $parser->params;
+
+ my $post_params = {};
+
+ if ($method eq 'PUT' || $method eq 'POST') {
+ $post_params = CGI->new($r->content())->Vars;
+ }
+
+ my $query_params = CGI->new($r->url->query)->Vars;
+
+ my $params = $post_params || {};
+
+ foreach my $k (keys %{$query_params}) {
+ $params->{$k} = $query_params->{$k};
+ }
+
+ return $params;
+};
+
+sub handle_requests {
+ my ($self, $rpcenv) = @_;
+
+ my $rcount = 0;
+
+ my $sel = IO::Select->new();
+ $sel->add ($self);
+
+ my $timeout = 5;
+ my @ready;
+ while (1) {
+ if (scalar (@ready = $sel->can_read($timeout))) {
+
+ my $c;
+ while (($c = $self->accept) || ($! == EINTR && !$child_terminate)) {
+ next if !$c; # EINTR
+
+ if ($child_reload_config) {
+ $child_reload_config = 0;
+ syslog('info', "child reload config");
+ # fixme: anything to do here?
+ }
+
+ $c->timeout(5);
+
+ # fixme: limit max request length somehow
+
+ # handle requests
+ while (my $r = $c->get_request) {
+
+ my $method = $r->method();
+
+ syslog('info', "perl method $method");
+
+ if (!$known_methods->{$method}) {
+ $c->send_error(HTTP_NOT_IMPLEMENTED);
+ last;
+ }
+
+ my $uri = $r->uri->path();
+ syslog('info', "start $method $uri");
+
+ my ($rel_uri, $format) = PVE::REST::split_abs_uri($uri);
+ if (!$format) {
+
+ $c->send_error(HTTP_NOT_IMPLEMENTED);
+
+ } else {
+
+ my $headers = $r->headers;
+
+ my $cookie = $headers->header('Cookie');
+
+ my $ticket = PVE::REST::extract_auth_cookie($cookie);
+
+ my $params = &$extract_params($r, $method);
+
+ my $clientip = $headers->header('PVEClientIP');
+
+ my $res = PVE::REST::rest_handler($clientip, $method, $uri, $rel_uri,
+ $ticket, undef, $params);
+
+ if ($res->{proxy}) {
+
+ $res->{status} = 500;
+ $c->send_error($res->{status}, "proxy not allowed");
+
+ } else {
+
+ PVE::REST::prepare_response_data($format, $res);
+ my ($raw, $ct) = PVE::REST::format_response_data($format, $res, $uri);
+
+ my $response = HTTP::Response->new($res->{status}, $res->{message});
+ $response->header("Content-Type" => $ct);
+ $response->header("Pragma", "no-cache");
+
+ if ($res->{ticket}) {
+ my $cookie = PVE::REST::create_auth_cookie($res->{ticket});
+ $response->header("Set-Cookie" => $cookie);
+ }
+ $response->content($raw);
+
+ $c->send_response($response);
+ }
+
+ syslog('info', "end $method $uri ($res->{status})");
+ }
+ }
+ $rcount++;
+
+ # we only handle one request per connection, because
+ # we want to minimize the number of connections
+
+ $c->shutdown(2);
+ $c->close();
+ last;
+ }
+
+ last if $child_terminate || !$c || ($rcount >= $max_requests);
+
+ } else {
+ last if $child_terminate;
+
+ # timeout
+ PVE::INotify::poll(); # read inotify events
+ }
+ }
+}
+
+1;
--- /dev/null
+package PVE::APLInfo;
+
+use strict;
+use IO::File;
+use PVE::SafeSyslog;
+use PVE::I18N;
+use LWP::UserAgent;
+use PVE::Config;
+use POSIX qw(strftime);
+
+my $logfile = "/var/log/pveam.log";
+
+# Default list of GPG keys allowed to sign aplinfo
+#
+#pub 1024D/5CAC72FE 2004-06-24
+# Key fingerprint = 9ABD 7E02 AD24 3AD3 C2FB BCCC B0C1 CC22 5CAC 72FE
+#uid Proxmox Support Team <support@proxmox.com>
+
+my $valid_keys = {
+ '9ABD7E02AD243AD3C2FBBCCCB0C1CC225CAC72FE' => 1, # fingerprint support@proxmox.com
+ '25CAC72FE' => 1, # keyid support@proxmox.com
+};
+
+sub import_gpg_keys {
+
+ my $keyfile = '/usr/share/doc/pve-manager/support@proxmox.com.pubkey';
+
+ return system ("/usr/bin/gpg --batch --no-tty --status-fd=1 -q " .
+ "--logger-fd=1 --import $keyfile >>$logfile");
+}
+
+sub logmsg {
+ my ($logfd, $msg) = @_;
+
+ chomp $msg;
+
+ my $tstr = strftime ("%b %d %H:%M:%S", localtime);
+
+ foreach my $line (split (/\n/, $msg)) {
+ print $logfd "$tstr $line\n";
+ }
+}
+
+sub url_get {
+ my ($ua, $url, $file, $logfh) = @_;
+
+ my $req = HTTP::Request->new(GET => $url);
+
+ logmsg ($logfh, "start download $url");
+ my $res = $ua->request($req, $file);
+
+ if ($res->is_success) {
+ logmsg ($logfh, "download finished: " . $res->status_line);
+ return 0;
+ }
+
+ logmsg ($logfh, "download failed: " . $res->status_line);
+
+ return 1;
+}
+
+sub update {
+ my ($proxy) = @_;
+
+ my $aplurl = "http://download.proxmox.com/appliances";
+ my $aplsrcurl = "$aplurl/aplinfo.dat.gz";
+ my $aplsigurl = "$aplurl/aplinfo.dat.asc";
+
+ my $size;
+ if (($size = (-s $logfile) || 0) > (1024*50)) {
+ system ("mv $logfile $logfile.0");
+ }
+ my $logfd = IO::File->new (">>$logfile");
+ logmsg ($logfd, "starting update");
+
+ import_gpg_keys();
+
+ my $tmp = "/tmp/pveam.tmp.$$";
+ my $tmpgz = "$tmp.gz";
+ my $sigfn = "$tmp.asc";
+
+ # this code works for ftp and http
+ # always use passive ftp
+ local $ENV{FTP_PASSIVE} = 1;
+ my $ua = LWP::UserAgent->new;
+ $ua->agent("PVE/1.0");
+
+ if ($proxy) {
+ $ua->proxy(['http'], $proxy);
+ } else {
+ $ua->env_proxy;
+ }
+
+ eval {
+ if (url_get ($ua, $aplsigurl, $sigfn, $logfd) != 0) {
+ die "update failed - no signature\n";
+ }
+
+ if (url_get ($ua, $aplsrcurl, $tmpgz, $logfd) != 0) {
+ die "update failed - no data\n";
+ }
+
+ if (system ("zcat -f $tmpgz >$tmp 2>/dev/null") != 0) {
+ die "update failed: unable to unpack '$tmpgz'\n";
+ }
+
+ # verify signature
+
+ my $cmd = "/usr/bin/gpg --verify --batch --no-tty --status-fd=1 -q " .
+ "--logger-fd=1 $sigfn $tmp";
+
+ open (CMD, "$cmd|") ||
+ die "unable to execute '$cmd': $!\n";
+
+ my $line;
+ my $signer = '';
+ while (defined ($line = <CMD>)) {
+ chomp $line;
+ logmsg ($logfd, $line);
+
+ # code borrowed from SA
+ next if $line !~ /^\Q[GNUPG:]\E (?:VALID|GOOD)SIG (\S{8,40})/;
+ my $key = $1;
+
+ # we want either a keyid (8) or a fingerprint (40)
+ if (length $key > 8 && length $key < 40) {
+ substr($key, 8) = '';
+ }
+ # use the longest match we can find
+ $signer = $key if (length $key > length $signer) && $valid_keys->{$key};
+ }
+
+ close (CMD);
+
+ die "unable to verify signature\n" if !$signer;
+
+ logmsg ($logfd, "signature valid: $signer");
+
+ # test syntax
+ eval {
+ my $fh = IO::File->new ("<$tmp") ||
+ die "unable to open file '$tmp' - $!\n";
+ PVE::Config::read_aplinfo ($tmp, $fh, 1);
+ close ($fh);
+ };
+ die "update failed: $@" if $@;
+
+ if (system ("mv $tmp /var/lib/pve-manager/apl-available 2>/dev/null") != 0) {
+ die "update failed: unable to store data\n";
+ }
+
+ logmsg ($logfd, "update sucessful");
+ };
+
+ my $err = $@;
+
+ unlink $tmp;
+ unlink $tmpgz;
+ unlink $sigfn;
+
+ if ($err) {
+ logmsg ($logfd, $err);
+ close ($logfd);
+
+ return 0;
+ }
+
+ close ($logfd);
+
+ return 1;
+}
+
+sub load_data {
+
+ my $filename = "/var/lib/pve-manager/apl-available";
+
+ if (! -f $filename) {
+ system ("cp /usr/share/doc/pve-manager/aplinfo.dat /var/lib/pve-manager/apl-available");
+ }
+
+ return PVE::Config::read_file ('aplinfo');
+}
+
+sub display_name {
+ my ($template) = @_;
+
+ my $templates = load_data ();
+
+ return $template if !$templates;
+
+ my $d = $templates->{'all'}->{$template};
+
+ $template =~ s/\.tar\.gz$//;
+ $template =~ s/_i386$//;
+
+ return $template if !$d;
+
+ return "$d->{package}_$d->{version}";
+}
+
+sub pkginfo {
+ my ($template) = @_;
+
+ my $templates = load_data ();
+
+ return undef if !$templates;
+
+ my $d = $templates->{'all'}->{$template};
+
+ return $d;
+}
+
+sub webnews {
+ my ($lang) = @_;
+
+ my $templates = load_data ();
+
+ my $html = '';
+
+ $html .= __("<b>Welcome</b> to the Proxmox Virtual Environment!");
+ $html .= "<br><br>";
+ $html .= __("For more information please visit our homepage at");
+ $html .= " <a href='http://www.proxmox.com' target='_blank'>www.proxmox.com</a>.";
+
+ return $html if !$templates;
+
+ # my $d = $templates->{'all'}->{"pve-web-news-$lang"} ||
+ my $d = $templates->{all}->{'pve-web-news'};
+
+ return $html if !$d;
+
+ return $d->{description};
+}
+
+1;
+
--- /dev/null
+include ../defines.mk
+
+SUBDIRS=API2
+
+PERLSOURCE = \
+ API2.pm \
+ API2Client.pm \
+ APIDaemon.pm \
+ REST.pm \
+ APLInfo.pm
+
+all: pvecfg.pm ${SUBDIRS}
+
+pvecfg.pm: pvecfg.pm.in
+ sed -e s/@VERSION@/${VERSION}/ -e s/@PACKAGE@/${PACKAGE}/ $< >$@
+
+%:
+ set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i $@; done
+
+.PHONY: distclean
+distclean: clean
+ set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i $@; done
+
+.PHONY: clean
+clean:
+ set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i $@; done
+ rm -rf *~ pvecfg.pm
+
+.PHONY: install
+install: pvecfg.pm ${PERLSOURCE}
+ install -d ${PERLLIBDIR}/PVE
+ install -m 0644 pvecfg.pm ${PERLLIBDIR}/PVE/
+ install -m 0644 ${PERLSOURCE} ${PERLLIBDIR}/PVE/
+ set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i $@; done
--- /dev/null
+package PVE::OpenVZ;
+
+use strict;
+use IO::Dir;
+use IO::File;
+use PVE::Config;
+
+my $confdir = "/etc/vz/conf";
+
+my $last_proc_vestat = {};
+
+$ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin';
+
+my $kernel_version = `uname -r`;
+
+sub vmlist {
+
+ my $res = {};
+
+ my $fd = IO::Dir->new ($confdir) ||
+ die "unable to open dir '$confdir' - $!";
+
+ while (defined(my $de = $fd->read)) {
+ if ($de =~ m/^(\d+)\.conf$/) {
+ my $veid = $1;
+ next if !$veid; # skip VE0
+ my $d = {
+ status => 'stopped',
+ type => 'openvz',
+ };
+
+ if (my $conf = PVE::Config::read_file ("$confdir/$de")) {
+ $d->{name} = $conf->{hostname}->{value} || "VM$veid";
+ $d->{name} =~ s/[\s]//g;
+
+ $d->{cpus} = $conf->{cpus}->{value} || 1;
+
+ $d->{disk} = 0;
+ $d->{maxdisk} = int ($conf->{diskspace}->{bar} / 1024);
+
+ $d->{mem} = 0;
+ $d->{maxmem} = int (($conf->{vmguarpages}->{bar} * 4) / 1024);
+ $d->{nproc} = 0;
+
+ $d->{uptime} = 0;
+ $d->{pctcpu} = 0;
+ $d->{relcpu} = 0;
+
+ if (my $ip = $conf->{ip_address}->{value}) {
+ $ip =~ s/,;/ /g;
+ $d->{ip} = (split(/\s+/, $ip))[0];
+ } else {
+ $d->{ip} = '-';
+ }
+ $res->{"VEID_$veid"} = $d;
+ }
+ }
+ }
+
+ my $fh;
+
+ if ($fh = IO::File->new ("/proc/mounts", "r")) {
+ while (defined (my $line = <$fh>)) {
+ if ($line =~ m|^/var/lib/vz/private/(\d+)\s+/var/lib/vz/root/|) {
+ $res->{"VEID_$1"}->{status} = 'mounted';
+ }
+ }
+ }
+
+ if ($fh = IO::File->new ("/proc/user_beancounters", "r")) {
+ my $veid;
+ while (defined (my $line = <$fh>)) {
+ if ($line =~ m|\s*((\d+):\s*)?([a-z]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$|) {
+ $veid = $2 if defined($2);
+ next if !$veid;
+ my ($name, $held, $maxheld, $bar, $lim, $failcnt) = ($3, $4, $5, $6, $7, $8);
+ if (my $d = $res->{"VEID_$veid"}) {
+ if ($name eq 'privvmpages') {
+ $d->{mem} = int (($held *4) / 1024);
+ $d->{maxmem} = int (($bar *4) / 1024);
+ } elsif ($name eq 'numproc') {
+ $d->{nproc} = $held;
+ }
+ }
+ }
+ }
+ }
+
+ if ($fh = IO::File->new ("/proc/vz/vzquota", "r")) {
+ while (defined (my $line = <$fh>)) {
+ if ($line =~ m|^(\d+):\s+/var/lib/vz/private/\d+$|) {
+ if (my $d = $res->{"VEID_$1"}) {
+ $line = <$fh>;
+ if ($line =~ m|^\s*1k-blocks\s+(\d+)\s+(\d+)\s|) {
+ $d->{disk} = int ($1/1024);
+ $d->{maxdisk} = int ($2/1024);
+ }
+ }
+ }
+ }
+ }
+
+ my $cpuinfo = PVE::Utils::get_cpu_info();
+ my $cpus = $cpuinfo->{cpus} || 1;
+
+ # see http://wiki.openvz.org/Vestat
+ if ($fh = new IO::File ("/proc/vz/vestat", "r")) {
+ while (defined (my $line = <$fh>)) {
+ if ($line =~ m/^\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+/) {
+ my $veid = $1;
+ my $user = $2;
+ my $nice = $3;
+ my $system = $4;
+ my $ut = $5;
+ my $sum = $8*$cpus; # uptime in jiffies * cpus = available jiffies
+ my $used = $9; # used time in jiffies
+
+ # HZ is 250 in our kernel 2.6.24 kernel
+ # but HZ is 1000 in our kernel 2.6.18 kernel
+ my $hz = 250;
+ $hz = 1000 if $kernel_version && $kernel_version =~ m/^2.6.18/;
+ my $uptime = int ($ut / $hz); # HZ is 250 in our kernel
+
+ my $d = $res->{"VEID_$veid"};
+ next if !$d;
+
+ $d->{status} = 'running';
+ $d->{uptime} = $uptime;
+
+ if (!defined ($last_proc_vestat->{$veid}) ||
+ ($last_proc_vestat->{$veid}->{sum} > $sum)) {
+ $last_proc_vestat->{$veid} = { used => 0, sum => 0, pctcpu => 0, relcpu => 0};
+ }
+
+ my $diff = $sum - $last_proc_vestat->{$veid}->{sum};
+
+ if ($diff > 1000) { # don't update too often
+ my $useddiff = $used - $last_proc_vestat->{$veid}->{used};
+ my $pctcpu = int ($useddiff*100/$diff);
+ $last_proc_vestat->{$veid}->{sum} = $sum;
+ $last_proc_vestat->{$veid}->{used} = $used;
+ $last_proc_vestat->{$veid}->{pctcpu} = $d->{pctcpu} = $pctcpu;
+
+ # fixme: openvz --cpus does not work currently
+ my $relcpu = $pctcpu;
+ $last_proc_vestat->{$veid}->{relcpu} = $d->{relcpu} = $relcpu;
+
+ } else {
+ $d->{pctcpu} = $last_proc_vestat->{$veid}->{pctcpu};
+ $d->{relcpu} = $last_proc_vestat->{$veid}->{relcpu};
+ }
+ }
+ }
+ }
+
+ return $res;
+
+}
--- /dev/null
+package PVE::REST;
+
+use warnings;
+use strict;
+use Digest::SHA1 qw(sha1_base64);
+use PVE::Cluster;
+use PVE::SafeSyslog;
+use PVE::Tools;
+use PVE::API2;
+use Apache2::Const;
+use CGI;
+use mod_perl2;
+use JSON;
+use Digest::SHA;
+use LWP::UserAgent;
+use HTTP::Request::Common;
+use HTTP::Status qw(:constants :is status_message);
+use HTML::Entities;
+use PVE::JSONSchema;
+use PVE::AccessControl;
+use PVE::RPCEnvironment;
+
+use Data::Dumper; # fixme: remove
+
+my $cookie_name = 'PVEAuthCookie';
+
+my $baseuri = "/api2";
+
+# http://perl.apache.org/docs/2.0/api/Apache2/SubProcess.html
+
+sub extract_auth_cookie {
+ my ($cookie) = @_;
+
+ return undef if !$cookie;
+
+ return ($cookie =~ /(?:^|\s)$cookie_name=([^;]*)/)[0];
+}
+
+sub create_auth_cookie {
+ my ($ticket) = @_;
+
+ return "${cookie_name}=$ticket; path=/; secure;";
+}
+
+sub format_response_data {
+ my($format, $res, $uri) = @_;
+
+ my $data = $res->{data};
+ my $info = $res->{info};
+
+ my ($ct, $raw);
+
+ if ($format eq 'json') {
+ $ct = 'application/json';
+ $raw = to_json($data, {utf8 => 1, allow_nonref => 1});
+ } elsif ($format eq 'html') {
+ $ct = 'text/html';
+ $raw = "<html><body>";
+ if (!is_success($res->{status})) {
+ my $msg = $res->{message} || '';
+ $raw .= "<h1>ERROR $res->{status} $msg</h1>";
+ }
+ my $lnk = PVE::JSONSchema::method_get_child_link($info);
+ if ($lnk && $data && $data->{data} && is_success($res->{status})) {
+
+ my $href = $lnk->{href};
+ if ($href =~ m/^\{(\S+)\}$/) {
+ my $prop = $1;
+ $uri =~ s/\/+$//; # remove trailing slash
+ foreach my $elem (sort {$a->{$prop} cmp $b->{$prop}} @{$data->{data}}) {
+ next if !ref($elem);
+
+ if (defined(my $value = $elem->{$prop})) {
+ if ($value ne '') {
+ if (scalar(keys %$elem) > 1) {
+ my $tv = to_json($elem, {allow_nonref => 1, canonical => 1});
+ $raw .= "<a href='$uri/$value'>$value</a> <pre>$tv</pre><br>";
+ } else {
+ $raw .= "<a href='$uri/$value'>$value</a><br>";
+ }
+ }
+ }
+ }
+ }
+ } else {
+ $raw .= "<pre>";
+ $raw .= encode_entities(to_json($data, {utf8 => 1, allow_nonref => 1, pretty => 1}));
+ $raw .= "</pre>";
+ }
+ $raw .= "</body></html>";
+
+ } elsif ($format eq 'png') {
+ $ct = 'image/png';
+
+ # fixme: better to revove that whole png thing ?
+
+ my $filename;
+ $raw = '';
+
+ if ($data && ref($data) && ref($data->{data}) &&
+ $data->{data}->{filename}) {
+ $filename = $data->{data}->{filename};
+ $raw = PVE::Tools::file_get_contents($filename);
+ }
+
+ } elsif ($format eq 'extjs') {
+ $ct = 'application/json';
+ $raw = to_json($data, {utf8 => 1, allow_nonref => 1});
+ } elsif ($format eq 'htmljs') {
+ # we use this for extjs file upload forms
+ $ct = 'text/html';
+ $raw = encode_entities(to_json($data, {utf8 => 1, allow_nonref => 1}));
+ } else {
+ $ct = 'text/plain';
+ $raw = to_json($data, {utf8 => 1, allow_nonref => 1, pretty => 1});
+ }
+
+ return wantarray ? ($raw, $ct) : $raw;
+}
+
+sub prepare_response_data {
+ my ($format, $res) = @_;
+
+ my $success = 1;
+ my $new = {
+ data => $res->{data},
+ };
+ if (scalar(keys %{$res->{errors}})) {
+ $success = 0;
+ $new->{errors} = $res->{errors};
+ }
+
+ if ($format eq 'extjs' || $format eq 'htmljs') {
+ # HACK: extjs wants 'success' property instead of useful HTTP status codes
+ if (is_error($res->{status})) {
+ $success = 0;
+ $new->{message} = $res->{message} || status_message($res->{status});
+ $new->{status} = $res->{status} || HTTP_OK;
+ $res->{message} = undef;
+ $res->{status} = HTTP_OK;
+ }
+ $new->{success} = $success;
+ }
+
+ if ($success && $res->{total}) {
+ $new->{total} = $res->{total};
+ }
+
+ $res->{data} = $new;
+}
+
+sub create_http_request {
+ my ($uri, $method, $params) = @_;
+
+ # NOTE: HTTP::Request::Common::PUT is crap - so we use our own code
+ # borrowed from HTTP::Request::Common::POST
+
+ if ($method eq 'POST' || $method eq 'PUT') {
+
+ my $req = HTTP::Request->new($method => $uri);
+ $req->header('Content-Type' => 'application/x-www-form-urlencoded');
+
+ # We use a temporary URI object to format
+ # the application/x-www-form-urlencoded content.
+ my $url = URI->new('http:');
+ $url->query_form(%$params);
+ my $content = $url->query;
+ if (defined($content)) {
+ $req->header('Content-Length' => length($content));
+ $req->content($content);
+ } else {
+ $req->header('Content-Length' => 0);
+ }
+
+ return $req;
+ }
+
+ die "unknown method '$method'";
+}
+
+sub proxy_handler {
+ my($r, $clientip, $host, $method, $abs_uri, $ticket, $token, $params) = @_;
+
+ syslog('info', "proxy start $method $host:$abs_uri");
+
+ my $ua = LWP::UserAgent->new(
+ protocols_allowed => [ 'http', 'https' ],
+ timeout => 30,
+ );
+
+ $ua->default_header('cookie' => "${cookie_name}=$ticket") if $ticket;
+ $ua->default_header('CSRFPreventionToken' => $token) if $token;
+ $ua->default_header('PVEDisableProxy' => 'true');
+ $ua->default_header('PVEClientIP' => $clientip);
+
+ my $uri = URI->new();
+
+ if ($host eq 'localhost') {
+ $uri->scheme('http');
+ $uri->host('localhost');
+ $uri->port(85);
+ } else {
+ $uri->scheme('https');
+ $uri->host($host);
+ $uri->port(8006);
+ }
+
+ $uri->path($abs_uri);
+
+ my $response;
+ if ($method eq 'GET') {
+ $uri->query_form($params);
+ $response = $ua->request(HTTP::Request::Common::GET($uri));
+ } elsif ($method eq 'POST' || $method eq 'PUT') {
+ $response = $ua->request(create_http_request($uri, $method, $params));
+ } elsif ($method eq 'DELETE') {
+ $response = $ua->request(HTTP::Request::Common::DELETE($uri));
+ } else {
+ my $code = HTTP_NOT_IMPLEMENTED;
+ $r->status_line("$code proxy method '$method' not implemented");
+ return $code;
+ }
+
+
+ if (my $cookie = $response->header("Set-Cookie")) {
+ $r->err_headers_out()->add("Set-Cookie" => $cookie);
+ }
+
+ my $ct = $response->header('Content-Type');
+
+ my $code = $response->code;
+ $r->status($code);
+
+ if (my $message = $response->message) {
+ $r->status_line("$code $message");
+ }
+
+ $r->content_type($ct) if $ct;
+ my $raw = $response->decoded_content;
+
+ # note: do not use err_headers_out(), because mod_deflate has a bug,
+ # resulting in dup length (for exampe 'content-length: 89, 75')
+ $r->headers_out()->add('Content-Length' , length($raw));
+ $r->print($raw);
+
+ syslog('info', "proxy end $method $host:$abs_uri ($code)");
+
+ return OK;
+}
+
+my $check_permissions = sub {
+ my ($rpcenv, $perm, $username, $param) = @_;
+
+ return 1 if !$username && $perm->{user} eq 'world';
+
+ return 1 if $username eq 'root@pam';
+
+ die "permission check failed (user != root)\n" if !$perm;
+
+ return 1 if $perm->{user} && $perm->{user} eq 'all';
+
+ return 1 if $perm->{user} && $perm->{user} eq 'arg' &&
+ $username eq $param->{username};
+
+ if ($perm->{path} && $perm->{privs}) {
+ my $path = PVE::Tools::template_replace($perm->{path}, $param);
+ if (!$rpcenv->check($username, $path, $perm->{privs})) {
+ my $privstr = join(',', @{$perm->{privs}});
+ die "Permission check failed ($path, $privstr)\n";
+ }
+ return 1;
+ }
+
+ die "Permission check failed\n";
+};
+
+sub rest_handler {
+ my ($clientip, $method, $abs_uri, $rel_uri, $ticket, $token, $params) = @_;
+
+ my $rpcenv = PVE::RPCEnvironment::get();
+
+ eval { $rpcenv->init_request(); };
+ if (my $err = $@) {
+ syslog('err', $err);
+ return { status => HTTP_INTERNAL_SERVER_ERROR, message => $err };
+ }
+
+ my $euid = $>;
+
+ my $require_auth = 1;
+
+ # explicitly allow some calls without auth
+ if (($rel_uri eq '/access/domains' && $method eq 'GET') ||
+ ($rel_uri eq '/access/ticket' && $method eq 'POST')) {
+ $require_auth = 0;
+ }
+
+ my ($username, $age);
+
+ if ($require_auth) {
+
+ eval {
+ die "No ticket\n" if !$ticket;
+
+ ($username, $age) = PVE::AccessControl::verify_ticket($ticket);
+
+ PVE::AccessControl::verify_csrf_prevention_token($username, $token)
+ if ($euid != 0) && ($method ne 'GET');
+ };
+ if (my $err = $@) {
+ return {
+ status => HTTP_UNAUTHORIZED,
+ message => $err,
+ };
+ }
+ }
+
+ my $uri_param = {};
+ my ($handler, $info) = PVE::API2->find_handler($method, $rel_uri, $uri_param);
+ if (!$handler || !$info) {
+ return {
+ status => HTTP_NOT_IMPLEMENTED,
+ message => "Method '$method $abs_uri' not implemented",
+ };
+ }
+
+ delete $params->{_dc}; # remove disable cache parameter
+
+ foreach my $p (keys %{$params}) {
+ if (defined($uri_param->{$p})) {
+ return {
+ status => HTTP_BAD_REQUEST,
+ message => "Parameter verification failed - duplicate parameter '$p'",
+ };
+ }
+ $uri_param->{$p} = $params->{$p};
+ }
+
+ # check access permissions
+ eval { &$check_permissions($rpcenv, $info->{permissions}, $username, $uri_param); };
+ if (my $err = $@) {
+ return {
+ status => HTTP_FORBIDDEN,
+ message => $err,
+ };
+ }
+
+ if ($info->{proxyto}) {
+ my $remip;
+ eval {
+ my $pn = $info->{proxyto};
+ my $node = $uri_param->{$pn};
+ die "proxy parameter '$pn' does not exists" if !$node;
+
+ if ($node ne 'localhost' &&
+ $node ne PVE::INotify::nodename()) {
+ $remip = PVE::Cluster::remote_node_ip($node);
+ }
+ };
+ if (my $err = $@) {
+ return {
+ status => HTTP_INTERNAL_SERVER_ERROR,
+ message => $err,
+ };
+ }
+ if ($remip) {
+ return { proxy => $remip };
+ }
+ }
+
+ # fixme: not sure if we should do that here, because we can't proxy those
+ # methods to other hosts?
+ return { proxy => 'localhost' } if $info->{protected} && ($euid != 0);
+
+ # set environment variables
+ $rpcenv->set_language('C'); # fixme:
+ $rpcenv->set_user($username);
+ $rpcenv->set_client_ip($clientip);
+ $rpcenv->set_result_count(undef);
+
+ my $resp = {
+ info => $info, # useful to format output
+ status => HTTP_OK,
+ };
+
+ eval {
+ $resp->{data} = $handler->handle($info, $uri_param);
+
+ if (my $count = $rpcenv->get_result_count()) {
+ $resp->{total} = $count;
+ }
+ };
+ my $err = $@;
+ if ($err) {
+ if (ref($err) eq "PVE::Exception") {
+ $resp->{status} = $err->{code} || HTTP_INTERNAL_SERVER_ERROR;
+ $resp->{message} = $err->{msg} || $@;
+ $resp->{errors} = $err->{errors} if $err->{errors};
+ } else {
+ $resp->{status} = HTTP_INTERNAL_SERVER_ERROR;
+ $resp->{message} = $@;
+ }
+ }
+
+ $rpcenv->set_user(undef);
+
+ if ($rel_uri eq '/access/ticket') {
+ $resp->{ticket} = $resp->{data}->{ticket};
+ }
+
+ # fixme: update ticket if too old
+ # $resp->{ticket} = update_ticket($ticket);
+
+ return $resp;
+}
+
+sub split_abs_uri {
+ my ($abs_uri) = @_;
+
+ my ($format, $rel_uri) = $abs_uri =~ m/^\Q$baseuri\E\/+(html|json|extjs|png|htmljs)(\/.*)?$/;
+ $rel_uri = '/' if !$rel_uri;
+
+ return wantarray ? ($rel_uri, $format) : $rel_uri;
+}
+
+my $known_methods = {
+ GET => 1,
+ POST => 1,
+ PUT => 1,
+ DELETE => 1,
+};
+
+sub handler {
+ my($r) = @_;
+
+ #syslog('info', "perl handler called");
+
+ my $method = $r->method;
+ my $clientip = $r->connection->remote_ip();
+
+ return HTTP_NOT_IMPLEMENTED
+ if !$known_methods->{$method};
+
+ my $cgi = CGI->new ($r);
+
+ my $params = $cgi->Vars();
+
+ my $cookie = $r->headers_in->{Cookie};
+ my $token = $r->headers_in->{CSRFPreventionToken};
+
+ my $ticket = extract_auth_cookie($cookie);
+
+ $r->no_cache (1);
+
+ my $abs_uri = $r->uri;
+ my ($rel_uri, $format) = split_abs_uri($abs_uri);
+ return HTTP_NOT_IMPLEMENTED if !$format;
+
+ my $res = rest_handler($clientip, $method, $abs_uri, $rel_uri,
+ $ticket, $token, $params);
+
+ if ($res->{proxy}) {
+ if (($res->{proxy} ne 'localhost') && $r->headers_in->{'PVEDisableProxy'}) {
+ my $code = FORBIDDEN;
+ $r->status($code);
+ $r->status_line("$code proxy loop detected - aborted ");
+ return $res->{status};
+ }
+ return proxy_handler($r, $clientip, $res->{proxy}, $method,
+ $abs_uri, $ticket, $token, $params);
+ }
+
+ prepare_response_data($format, $res);
+
+ if ($res->{ticket}) {
+ my $cookie = create_auth_cookie($res->{ticket});
+ $r->err_headers_out()->add("Set-Cookie" => $cookie);
+ }
+
+ $r->status($res->{status} || HTTP_OK);
+
+ if ($res->{message}) {
+ my ($firstline) = $res->{message} =~ m/\A(.*)$/m;
+ $r->status_line("$res->{status} $firstline");
+ }
+
+ my ($raw, $ct) = format_response_data($format, $res, $abs_uri);
+ $r->content_type ($ct);
+
+ # note: do not use err_headers_out(), because mod_deflate has a bug,
+ # resulting in dup length (for exampe 'content-length: 89, 75')
+ $r->headers_out()->add('Content-Length', length($raw));
+ $r->print($raw);
+
+ #syslog('info', "perl handler end $res->{status}");
+
+ return OK;
+}
+
+1;
--- /dev/null
+package PVE::pvecfg;
+
+use strict;
+use vars qw(@ISA);
+use Carp;
+
+sub package {
+ return '@PACKAGE@';
+}
+
+sub version {
+ return '@VERSION@';
+}
+
+sub repoid {
+ return '@REPOID@';
+}
+
+1;
\ No newline at end of file
+++ /dev/null
-# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-m4_ifndef([AC_AUTOCONF_VERSION],
- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-m4_if(m4_defn([AC_AUTOCONF_VERSION]), [2.67],,
-[m4_warning([this file was generated for autoconf 2.67.
-You have another version of autoconf. It may work, but is not guaranteed to.
-If you have problems, you may need to regenerate the build system entirely.
-To do so, use the procedure documented by the package, typically `autoreconf'.])])
-
-# nls.m4 serial 5 (gettext-0.18)
-dnl Copyright (C) 1995-2003, 2005-2006, 2008-2010 Free Software Foundation,
-dnl Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Authors:
-dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
-dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003.
-
-AC_PREREQ([2.50])
-
-AC_DEFUN([AM_NLS],
-[
- AC_MSG_CHECKING([whether NLS is requested])
- dnl Default is enabled NLS
- AC_ARG_ENABLE([nls],
- [ --disable-nls do not use Native Language Support],
- USE_NLS=$enableval, USE_NLS=yes)
- AC_MSG_RESULT([$USE_NLS])
- AC_SUBST([USE_NLS])
-])
-
-# po.m4 serial 17 (gettext-0.18)
-dnl Copyright (C) 1995-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Authors:
-dnl Ulrich Drepper <drepper@cygnus.com>, 1995-2000.
-dnl Bruno Haible <haible@clisp.cons.org>, 2000-2003.
-
-AC_PREREQ([2.50])
-
-dnl Checks for all prerequisites of the po subdirectory.
-AC_DEFUN([AM_PO_SUBDIRS],
-[
- AC_REQUIRE([AC_PROG_MAKE_SET])dnl
- AC_REQUIRE([AC_PROG_INSTALL])dnl
- AC_REQUIRE([AM_PROG_MKDIR_P])dnl defined by automake
- AC_REQUIRE([AM_NLS])dnl
-
- dnl Release version of the gettext macros. This is used to ensure that
- dnl the gettext macros and po/Makefile.in.in are in sync.
- AC_SUBST([GETTEXT_MACRO_VERSION], [0.18])
-
- dnl Perform the following tests also if --disable-nls has been given,
- dnl because they are needed for "make dist" to work.
-
- dnl Search for GNU msgfmt in the PATH.
- dnl The first test excludes Solaris msgfmt and early GNU msgfmt versions.
- dnl The second test excludes FreeBSD msgfmt.
- AM_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
- [$ac_dir/$ac_word --statistics /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
- (if $ac_dir/$ac_word --statistics /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
- :)
- AC_PATH_PROG([GMSGFMT], [gmsgfmt], [$MSGFMT])
-
- dnl Test whether it is GNU msgfmt >= 0.15.
-changequote(,)dnl
- case `$MSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) MSGFMT_015=: ;;
- *) MSGFMT_015=$MSGFMT ;;
- esac
-changequote([,])dnl
- AC_SUBST([MSGFMT_015])
-changequote(,)dnl
- case `$GMSGFMT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) GMSGFMT_015=: ;;
- *) GMSGFMT_015=$GMSGFMT ;;
- esac
-changequote([,])dnl
- AC_SUBST([GMSGFMT_015])
-
- dnl Search for GNU xgettext 0.12 or newer in the PATH.
- dnl The first test excludes Solaris xgettext and early GNU xgettext versions.
- dnl The second test excludes FreeBSD xgettext.
- AM_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
- [$ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1 &&
- (if $ac_dir/$ac_word --omit-header --copyright-holder= --msgid-bugs-address= /dev/null 2>&1 >/dev/null | grep usage >/dev/null; then exit 1; else exit 0; fi)],
- :)
- dnl Remove leftover from FreeBSD xgettext call.
- rm -f messages.po
-
- dnl Test whether it is GNU xgettext >= 0.15.
-changequote(,)dnl
- case `$XGETTEXT --version | sed 1q | sed -e 's,^[^0-9]*,,'` in
- '' | 0.[0-9] | 0.[0-9].* | 0.1[0-4] | 0.1[0-4].*) XGETTEXT_015=: ;;
- *) XGETTEXT_015=$XGETTEXT ;;
- esac
-changequote([,])dnl
- AC_SUBST([XGETTEXT_015])
-
- dnl Search for GNU msgmerge 0.11 or newer in the PATH.
- AM_PATH_PROG_WITH_TEST(MSGMERGE, msgmerge,
- [$ac_dir/$ac_word --update -q /dev/null /dev/null >&]AS_MESSAGE_LOG_FD[ 2>&1], :)
-
- dnl Installation directories.
- dnl Autoconf >= 2.60 defines localedir. For older versions of autoconf, we
- dnl have to define it here, so that it can be used in po/Makefile.
- test -n "$localedir" || localedir='${datadir}/locale'
- AC_SUBST([localedir])
-
- dnl Support for AM_XGETTEXT_OPTION.
- test -n "${XGETTEXT_EXTRA_OPTIONS+set}" || XGETTEXT_EXTRA_OPTIONS=
- AC_SUBST([XGETTEXT_EXTRA_OPTIONS])
-
- AC_CONFIG_COMMANDS([po-directories], [[
- for ac_file in $CONFIG_FILES; do
- # Support "outfile[:infile[:infile...]]"
- case "$ac_file" in
- *:*) ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
- esac
- # PO directories have a Makefile.in generated from Makefile.in.in.
- case "$ac_file" in */Makefile.in)
- # Adjust a relative srcdir.
- ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
- ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
- ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
- # In autoconf-2.13 it is called $ac_given_srcdir.
- # In autoconf-2.50 it is called $srcdir.
- test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
- case "$ac_given_srcdir" in
- .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
- /*) top_srcdir="$ac_given_srcdir" ;;
- *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
- esac
- # Treat a directory as a PO directory if and only if it has a
- # POTFILES.in file. This allows packages to have multiple PO
- # directories under different names or in different locations.
- if test -f "$ac_given_srcdir/$ac_dir/POTFILES.in"; then
- rm -f "$ac_dir/POTFILES"
- test -n "$as_me" && echo "$as_me: creating $ac_dir/POTFILES" || echo "creating $ac_dir/POTFILES"
- cat "$ac_given_srcdir/$ac_dir/POTFILES.in" | sed -e "/^#/d" -e "/^[ ]*\$/d" -e "s,.*, $top_srcdir/& \\\\," | sed -e "\$s/\(.*\) \\\\/\1/" > "$ac_dir/POTFILES"
- POMAKEFILEDEPS="POTFILES.in"
- # ALL_LINGUAS, POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES depend
- # on $ac_dir but don't depend on user-specified configuration
- # parameters.
- if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
- # The LINGUAS file contains the set of available languages.
- if test -n "$OBSOLETE_ALL_LINGUAS"; then
- test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
- fi
- ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
- # Hide the ALL_LINGUAS assigment from automake < 1.5.
- eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
- POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
- else
- # The set of available languages was given in configure.in.
- # Hide the ALL_LINGUAS assigment from automake < 1.5.
- eval 'ALL_LINGUAS''=$OBSOLETE_ALL_LINGUAS'
- fi
- # Compute POFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
- # Compute UPDATEPOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
- # Compute DUMMYPOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
- # Compute GMOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
- case "$ac_given_srcdir" in
- .) srcdirpre= ;;
- *) srcdirpre='$(srcdir)/' ;;
- esac
- POFILES=
- UPDATEPOFILES=
- DUMMYPOFILES=
- GMOFILES=
- for lang in $ALL_LINGUAS; do
- POFILES="$POFILES $srcdirpre$lang.po"
- UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
- DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
- GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
- done
- # CATALOGS depends on both $ac_dir and the user's LINGUAS
- # environment variable.
- INST_LINGUAS=
- if test -n "$ALL_LINGUAS"; then
- for presentlang in $ALL_LINGUAS; do
- useit=no
- if test "%UNSET%" != "$LINGUAS"; then
- desiredlanguages="$LINGUAS"
- else
- desiredlanguages="$ALL_LINGUAS"
- fi
- for desiredlang in $desiredlanguages; do
- # Use the presentlang catalog if desiredlang is
- # a. equal to presentlang, or
- # b. a variant of presentlang (because in this case,
- # presentlang can be used as a fallback for messages
- # which are not translated in the desiredlang catalog).
- case "$desiredlang" in
- "$presentlang"*) useit=yes;;
- esac
- done
- if test $useit = yes; then
- INST_LINGUAS="$INST_LINGUAS $presentlang"
- fi
- done
- fi
- CATALOGS=
- if test -n "$INST_LINGUAS"; then
- for lang in $INST_LINGUAS; do
- CATALOGS="$CATALOGS $lang.gmo"
- done
- fi
- test -n "$as_me" && echo "$as_me: creating $ac_dir/Makefile" || echo "creating $ac_dir/Makefile"
- sed -e "/^POTFILES =/r $ac_dir/POTFILES" -e "/^# Makevars/r $ac_given_srcdir/$ac_dir/Makevars" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@POMAKEFILEDEPS@|$POMAKEFILEDEPS|g" "$ac_dir/Makefile.in" > "$ac_dir/Makefile"
- for f in "$ac_given_srcdir/$ac_dir"/Rules-*; do
- if test -f "$f"; then
- case "$f" in
- *.orig | *.bak | *~) ;;
- *) cat "$f" >> "$ac_dir/Makefile" ;;
- esac
- fi
- done
- fi
- ;;
- esac
- done]],
- [# Capture the value of obsolete ALL_LINGUAS because we need it to compute
- # POFILES, UPDATEPOFILES, DUMMYPOFILES, GMOFILES, CATALOGS. But hide it
- # from automake < 1.5.
- eval 'OBSOLETE_ALL_LINGUAS''="$ALL_LINGUAS"'
- # Capture the value of LINGUAS because we need it to compute CATALOGS.
- LINGUAS="${LINGUAS-%UNSET%}"
- ])
-])
-
-dnl Postprocesses a Makefile in a directory containing PO files.
-AC_DEFUN([AM_POSTPROCESS_PO_MAKEFILE],
-[
- # When this code is run, in config.status, two variables have already been
- # set:
- # - OBSOLETE_ALL_LINGUAS is the value of LINGUAS set in configure.in,
- # - LINGUAS is the value of the environment variable LINGUAS at configure
- # time.
-
-changequote(,)dnl
- # Adjust a relative srcdir.
- ac_dir=`echo "$ac_file"|sed 's%/[^/][^/]*$%%'`
- ac_dir_suffix="/`echo "$ac_dir"|sed 's%^\./%%'`"
- ac_dots=`echo "$ac_dir_suffix"|sed 's%/[^/]*%../%g'`
- # In autoconf-2.13 it is called $ac_given_srcdir.
- # In autoconf-2.50 it is called $srcdir.
- test -n "$ac_given_srcdir" || ac_given_srcdir="$srcdir"
- case "$ac_given_srcdir" in
- .) top_srcdir=`echo $ac_dots|sed 's%/$%%'` ;;
- /*) top_srcdir="$ac_given_srcdir" ;;
- *) top_srcdir="$ac_dots$ac_given_srcdir" ;;
- esac
-
- # Find a way to echo strings without interpreting backslash.
- if test "X`(echo '\t') 2>/dev/null`" = 'X\t'; then
- gt_echo='echo'
- else
- if test "X`(printf '%s\n' '\t') 2>/dev/null`" = 'X\t'; then
- gt_echo='printf %s\n'
- else
- echo_func () {
- cat <<EOT
-$*
-EOT
- }
- gt_echo='echo_func'
- fi
- fi
-
- # A sed script that extracts the value of VARIABLE from a Makefile.
- sed_x_variable='
-# Test if the hold space is empty.
-x
-s/P/P/
-x
-ta
-# Yes it was empty. Look if we have the expected variable definition.
-/^[ ]*VARIABLE[ ]*=/{
- # Seen the first line of the variable definition.
- s/^[ ]*VARIABLE[ ]*=//
- ba
-}
-bd
-:a
-# Here we are processing a line from the variable definition.
-# Remove comment, more precisely replace it with a space.
-s/#.*$/ /
-# See if the line ends in a backslash.
-tb
-:b
-s/\\$//
-# Print the line, without the trailing backslash.
-p
-tc
-# There was no trailing backslash. The end of the variable definition is
-# reached. Clear the hold space.
-s/^.*$//
-x
-bd
-:c
-# A trailing backslash means that the variable definition continues in the
-# next line. Put a nonempty string into the hold space to indicate this.
-s/^.*$/P/
-x
-:d
-'
-changequote([,])dnl
-
- # Set POTFILES to the value of the Makefile variable POTFILES.
- sed_x_POTFILES=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/POTFILES/g'`
- POTFILES=`sed -n -e "$sed_x_POTFILES" < "$ac_file"`
- # Compute POTFILES_DEPS as
- # $(foreach file, $(POTFILES), $(top_srcdir)/$(file))
- POTFILES_DEPS=
- for file in $POTFILES; do
- POTFILES_DEPS="$POTFILES_DEPS "'$(top_srcdir)/'"$file"
- done
- POMAKEFILEDEPS=""
-
- if test -n "$OBSOLETE_ALL_LINGUAS"; then
- test -n "$as_me" && echo "$as_me: setting ALL_LINGUAS in configure.in is obsolete" || echo "setting ALL_LINGUAS in configure.in is obsolete"
- fi
- if test -f "$ac_given_srcdir/$ac_dir/LINGUAS"; then
- # The LINGUAS file contains the set of available languages.
- ALL_LINGUAS_=`sed -e "/^#/d" -e "s/#.*//" "$ac_given_srcdir/$ac_dir/LINGUAS"`
- POMAKEFILEDEPS="$POMAKEFILEDEPS LINGUAS"
- else
- # Set ALL_LINGUAS to the value of the Makefile variable LINGUAS.
- sed_x_LINGUAS=`$gt_echo "$sed_x_variable" | sed -e '/^ *#/d' -e 's/VARIABLE/LINGUAS/g'`
- ALL_LINGUAS_=`sed -n -e "$sed_x_LINGUAS" < "$ac_file"`
- fi
- # Hide the ALL_LINGUAS assigment from automake < 1.5.
- eval 'ALL_LINGUAS''=$ALL_LINGUAS_'
- # Compute POFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).po)
- # Compute UPDATEPOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(lang).po-update)
- # Compute DUMMYPOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(lang).nop)
- # Compute GMOFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).gmo)
- # Compute PROPERTIESFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).properties)
- # Compute CLASSFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(top_srcdir)/$(DOMAIN)_$(lang).class)
- # Compute QMFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(lang).qm)
- # Compute MSGFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang)).msg)
- # Compute RESOURCESDLLFILES
- # as $(foreach lang, $(ALL_LINGUAS), $(srcdir)/$(frob $(lang))/$(DOMAIN).resources.dll)
- case "$ac_given_srcdir" in
- .) srcdirpre= ;;
- *) srcdirpre='$(srcdir)/' ;;
- esac
- POFILES=
- UPDATEPOFILES=
- DUMMYPOFILES=
- GMOFILES=
- PROPERTIESFILES=
- CLASSFILES=
- QMFILES=
- MSGFILES=
- RESOURCESDLLFILES=
- for lang in $ALL_LINGUAS; do
- POFILES="$POFILES $srcdirpre$lang.po"
- UPDATEPOFILES="$UPDATEPOFILES $lang.po-update"
- DUMMYPOFILES="$DUMMYPOFILES $lang.nop"
- GMOFILES="$GMOFILES $srcdirpre$lang.gmo"
- PROPERTIESFILES="$PROPERTIESFILES \$(top_srcdir)/\$(DOMAIN)_$lang.properties"
- CLASSFILES="$CLASSFILES \$(top_srcdir)/\$(DOMAIN)_$lang.class"
- QMFILES="$QMFILES $srcdirpre$lang.qm"
- frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
- MSGFILES="$MSGFILES $srcdirpre$frobbedlang.msg"
- frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
- RESOURCESDLLFILES="$RESOURCESDLLFILES $srcdirpre$frobbedlang/\$(DOMAIN).resources.dll"
- done
- # CATALOGS depends on both $ac_dir and the user's LINGUAS
- # environment variable.
- INST_LINGUAS=
- if test -n "$ALL_LINGUAS"; then
- for presentlang in $ALL_LINGUAS; do
- useit=no
- if test "%UNSET%" != "$LINGUAS"; then
- desiredlanguages="$LINGUAS"
- else
- desiredlanguages="$ALL_LINGUAS"
- fi
- for desiredlang in $desiredlanguages; do
- # Use the presentlang catalog if desiredlang is
- # a. equal to presentlang, or
- # b. a variant of presentlang (because in this case,
- # presentlang can be used as a fallback for messages
- # which are not translated in the desiredlang catalog).
- case "$desiredlang" in
- "$presentlang"*) useit=yes;;
- esac
- done
- if test $useit = yes; then
- INST_LINGUAS="$INST_LINGUAS $presentlang"
- fi
- done
- fi
- CATALOGS=
- JAVACATALOGS=
- QTCATALOGS=
- TCLCATALOGS=
- CSHARPCATALOGS=
- if test -n "$INST_LINGUAS"; then
- for lang in $INST_LINGUAS; do
- CATALOGS="$CATALOGS $lang.gmo"
- JAVACATALOGS="$JAVACATALOGS \$(DOMAIN)_$lang.properties"
- QTCATALOGS="$QTCATALOGS $lang.qm"
- frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
- TCLCATALOGS="$TCLCATALOGS $frobbedlang.msg"
- frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
- CSHARPCATALOGS="$CSHARPCATALOGS $frobbedlang/\$(DOMAIN).resources.dll"
- done
- fi
-
- sed -e "s|@POTFILES_DEPS@|$POTFILES_DEPS|g" -e "s|@POFILES@|$POFILES|g" -e "s|@UPDATEPOFILES@|$UPDATEPOFILES|g" -e "s|@DUMMYPOFILES@|$DUMMYPOFILES|g" -e "s|@GMOFILES@|$GMOFILES|g" -e "s|@PROPERTIESFILES@|$PROPERTIESFILES|g" -e "s|@CLASSFILES@|$CLASSFILES|g" -e "s|@QMFILES@|$QMFILES|g" -e "s|@MSGFILES@|$MSGFILES|g" -e "s|@RESOURCESDLLFILES@|$RESOURCESDLLFILES|g" -e "s|@CATALOGS@|$CATALOGS|g" -e "s|@JAVACATALOGS@|$JAVACATALOGS|g" -e "s|@QTCATALOGS@|$QTCATALOGS|g" -e "s|@TCLCATALOGS@|$TCLCATALOGS|g" -e "s|@CSHARPCATALOGS@|$CSHARPCATALOGS|g" -e 's,^#distdir:,distdir:,' < "$ac_file" > "$ac_file.tmp"
- if grep -l '@TCLCATALOGS@' "$ac_file" > /dev/null; then
- # Add dependencies that cannot be formulated as a simple suffix rule.
- for lang in $ALL_LINGUAS; do
- frobbedlang=`echo $lang | sed -e 's/\..*$//' -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
- cat >> "$ac_file.tmp" <<EOF
-$frobbedlang.msg: $lang.po
- @echo "\$(MSGFMT) -c --tcl -d \$(srcdir) -l $lang $srcdirpre$lang.po"; \
- \$(MSGFMT) -c --tcl -d "\$(srcdir)" -l $lang $srcdirpre$lang.po || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
-EOF
- done
- fi
- if grep -l '@CSHARPCATALOGS@' "$ac_file" > /dev/null; then
- # Add dependencies that cannot be formulated as a simple suffix rule.
- for lang in $ALL_LINGUAS; do
- frobbedlang=`echo $lang | sed -e 's/_/-/g' -e 's/^sr-CS/sr-SP/' -e 's/@latin$/-Latn/' -e 's/@cyrillic$/-Cyrl/' -e 's/^sr-SP$/sr-SP-Latn/' -e 's/^uz-UZ$/uz-UZ-Latn/'`
- cat >> "$ac_file.tmp" <<EOF
-$frobbedlang/\$(DOMAIN).resources.dll: $lang.po
- @echo "\$(MSGFMT) -c --csharp -d \$(srcdir) -l $lang $srcdirpre$lang.po -r \$(DOMAIN)"; \
- \$(MSGFMT) -c --csharp -d "\$(srcdir)" -l $lang $srcdirpre$lang.po -r "\$(DOMAIN)" || { rm -f "\$(srcdir)/$frobbedlang.msg"; exit 1; }
-EOF
- done
- fi
- if test -n "$POMAKEFILEDEPS"; then
- cat >> "$ac_file.tmp" <<EOF
-Makefile: $POMAKEFILEDEPS
-EOF
- fi
- mv "$ac_file.tmp" "$ac_file"
-])
-
-dnl Initializes the accumulator used by AM_XGETTEXT_OPTION.
-AC_DEFUN([AM_XGETTEXT_OPTION_INIT],
-[
- XGETTEXT_EXTRA_OPTIONS=
-])
-
-dnl Registers an option to be passed to xgettext in the po subdirectory.
-AC_DEFUN([AM_XGETTEXT_OPTION],
-[
- AC_REQUIRE([AM_XGETTEXT_OPTION_INIT])
- XGETTEXT_EXTRA_OPTIONS="$XGETTEXT_EXTRA_OPTIONS $1"
-])
-
-# progtest.m4 serial 6 (gettext-0.18)
-dnl Copyright (C) 1996-2003, 2005, 2008-2010 Free Software Foundation, Inc.
-dnl This file is free software; the Free Software Foundation
-dnl gives unlimited permission to copy and/or distribute it,
-dnl with or without modifications, as long as this notice is preserved.
-dnl
-dnl This file can can be used in projects which are not available under
-dnl the GNU General Public License or the GNU Library General Public
-dnl License but which still want to provide support for the GNU gettext
-dnl functionality.
-dnl Please note that the actual code of the GNU gettext library is covered
-dnl by the GNU Library General Public License, and the rest of the GNU
-dnl gettext package package is covered by the GNU General Public License.
-dnl They are *not* in the public domain.
-
-dnl Authors:
-dnl Ulrich Drepper <drepper@cygnus.com>, 1996.
-
-AC_PREREQ([2.50])
-
-# Search path for a program which passes the given test.
-
-dnl AM_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
-dnl TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
-AC_DEFUN([AM_PATH_PROG_WITH_TEST],
-[
-# Prepare PATH_SEPARATOR.
-# The user is always right.
-if test "${PATH_SEPARATOR+set}" != set; then
- echo "#! /bin/sh" >conf$$.sh
- echo "exit 0" >>conf$$.sh
- chmod +x conf$$.sh
- if (PATH="/nonexistent;."; conf$$.sh) >/dev/null 2>&1; then
- PATH_SEPARATOR=';'
- else
- PATH_SEPARATOR=:
- fi
- rm -f conf$$.sh
-fi
-
-# Find out how to test for executable files. Don't use a zero-byte file,
-# as systems may use methods other than mode bits to determine executability.
-cat >conf$$.file <<_ASEOF
-#! /bin/sh
-exit 0
-_ASEOF
-chmod +x conf$$.file
-if test -x conf$$.file >/dev/null 2>&1; then
- ac_executable_p="test -x"
-else
- ac_executable_p="test -f"
-fi
-rm -f conf$$.file
-
-# Extract the first word of "$2", so it can be a program name with args.
-set dummy $2; ac_word=[$]2
-AC_MSG_CHECKING([for $ac_word])
-AC_CACHE_VAL([ac_cv_path_$1],
-[case "[$]$1" in
- [[\\/]]* | ?:[[\\/]]*)
- ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
- ;;
- *)
- ac_save_IFS="$IFS"; IFS=$PATH_SEPARATOR
- for ac_dir in ifelse([$5], , $PATH, [$5]); do
- IFS="$ac_save_IFS"
- test -z "$ac_dir" && ac_dir=.
- for ac_exec_ext in '' $ac_executable_extensions; do
- if $ac_executable_p "$ac_dir/$ac_word$ac_exec_ext"; then
- echo "$as_me: trying $ac_dir/$ac_word..." >&AS_MESSAGE_LOG_FD
- if [$3]; then
- ac_cv_path_$1="$ac_dir/$ac_word$ac_exec_ext"
- break 2
- fi
- fi
- done
- done
- IFS="$ac_save_IFS"
-dnl If no 4th arg is given, leave the cache variable unset,
-dnl so AC_PATH_PROGS will keep looking.
-ifelse([$4], , , [ test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
-])dnl
- ;;
-esac])dnl
-$1="$ac_cv_path_$1"
-if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
- AC_MSG_RESULT([$][$1])
-else
- AC_MSG_RESULT([no])
-fi
-AC_SUBST([$1])dnl
-])
-
-# Copyright (C) 2002, 2003, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_AUTOMAKE_VERSION(VERSION)
-# ----------------------------
-# Automake X.Y traces this macro to ensure aclocal.m4 has been
-# generated from the m4 files accompanying Automake X.Y.
-# (This private macro should not be called outside this file.)
-AC_DEFUN([AM_AUTOMAKE_VERSION],
-[am__api_version='1.11'
-dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to
-dnl require some minimum version. Point them to the right macro.
-m4_if([$1], [1.11.1], [],
- [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl
-])
-
-# _AM_AUTOCONF_VERSION(VERSION)
-# -----------------------------
-# aclocal traces this macro to find the Autoconf version.
-# This is a private macro too. Using m4_define simplifies
-# the logic in aclocal, which can simply ignore this definition.
-m4_define([_AM_AUTOCONF_VERSION], [])
-
-# AM_SET_CURRENT_AUTOMAKE_VERSION
-# -------------------------------
-# Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced.
-# This function is AC_REQUIREd by AM_INIT_AUTOMAKE.
-AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION],
-[AM_AUTOMAKE_VERSION([1.11.1])dnl
-m4_ifndef([AC_AUTOCONF_VERSION],
- [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl
-_AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))])
-
-# AM_AUX_DIR_EXPAND -*- Autoconf -*-
-
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# For projects using AC_CONFIG_AUX_DIR([foo]), Autoconf sets
-# $ac_aux_dir to `$srcdir/foo'. In other projects, it is set to
-# `$srcdir', `$srcdir/..', or `$srcdir/../..'.
-#
-# Of course, Automake must honor this variable whenever it calls a
-# tool from the auxiliary directory. The problem is that $srcdir (and
-# therefore $ac_aux_dir as well) can be either absolute or relative,
-# depending on how configure is run. This is pretty annoying, since
-# it makes $ac_aux_dir quite unusable in subdirectories: in the top
-# source directory, any form will work fine, but in subdirectories a
-# relative path needs to be adjusted first.
-#
-# $ac_aux_dir/missing
-# fails when called from a subdirectory if $ac_aux_dir is relative
-# $top_srcdir/$ac_aux_dir/missing
-# fails if $ac_aux_dir is absolute,
-# fails when called from a subdirectory in a VPATH build with
-# a relative $ac_aux_dir
-#
-# The reason of the latter failure is that $top_srcdir and $ac_aux_dir
-# are both prefixed by $srcdir. In an in-source build this is usually
-# harmless because $srcdir is `.', but things will broke when you
-# start a VPATH build or use an absolute $srcdir.
-#
-# So we could use something similar to $top_srcdir/$ac_aux_dir/missing,
-# iff we strip the leading $srcdir from $ac_aux_dir. That would be:
-# am_aux_dir='\$(top_srcdir)/'`expr "$ac_aux_dir" : "$srcdir//*\(.*\)"`
-# and then we would define $MISSING as
-# MISSING="\${SHELL} $am_aux_dir/missing"
-# This will work as long as MISSING is not called from configure, because
-# unfortunately $(top_srcdir) has no meaning in configure.
-# However there are other variables, like CC, which are often used in
-# configure, and could therefore not use this "fixed" $ac_aux_dir.
-#
-# Another solution, used here, is to always expand $ac_aux_dir to an
-# absolute PATH. The drawback is that using absolute paths prevent a
-# configured tree to be moved without reconfiguration.
-
-AC_DEFUN([AM_AUX_DIR_EXPAND],
-[dnl Rely on autoconf to set up CDPATH properly.
-AC_PREREQ([2.50])dnl
-# expand $ac_aux_dir to an absolute path
-am_aux_dir=`cd $ac_aux_dir && pwd`
-])
-
-# AM_CONDITIONAL -*- Autoconf -*-
-
-# Copyright (C) 1997, 2000, 2001, 2003, 2004, 2005, 2006, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 9
-
-# AM_CONDITIONAL(NAME, SHELL-CONDITION)
-# -------------------------------------
-# Define a conditional.
-AC_DEFUN([AM_CONDITIONAL],
-[AC_PREREQ(2.52)dnl
- ifelse([$1], [TRUE], [AC_FATAL([$0: invalid condition: $1])],
- [$1], [FALSE], [AC_FATAL([$0: invalid condition: $1])])dnl
-AC_SUBST([$1_TRUE])dnl
-AC_SUBST([$1_FALSE])dnl
-_AM_SUBST_NOTMAKE([$1_TRUE])dnl
-_AM_SUBST_NOTMAKE([$1_FALSE])dnl
-m4_define([_AM_COND_VALUE_$1], [$2])dnl
-if $2; then
- $1_TRUE=
- $1_FALSE='#'
-else
- $1_TRUE='#'
- $1_FALSE=
-fi
-AC_CONFIG_COMMANDS_PRE(
-[if test -z "${$1_TRUE}" && test -z "${$1_FALSE}"; then
- AC_MSG_ERROR([[conditional "$1" was never defined.
-Usually this means the macro was only invoked conditionally.]])
-fi])])
-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2009
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 10
-
-# There are a few dirty hacks below to avoid letting `AC_PROG_CC' be
-# written in clear, in which case automake, when reading aclocal.m4,
-# will think it sees a *use*, and therefore will trigger all it's
-# C support machinery. Also note that it means that autoscan, seeing
-# CC etc. in the Makefile, will ask for an AC_PROG_CC use...
-
-
-# _AM_DEPENDENCIES(NAME)
-# ----------------------
-# See how the compiler implements dependency checking.
-# NAME is "CC", "CXX", "GCJ", or "OBJC".
-# We try a few techniques and use that to set a single cache variable.
-#
-# We don't AC_REQUIRE the corresponding AC_PROG_CC since the latter was
-# modified to invoke _AM_DEPENDENCIES(CC); we would have a circular
-# dependency, and given that the user is not expected to run this macro,
-# just rely on AC_PROG_CC.
-AC_DEFUN([_AM_DEPENDENCIES],
-[AC_REQUIRE([AM_SET_DEPDIR])dnl
-AC_REQUIRE([AM_OUTPUT_DEPENDENCY_COMMANDS])dnl
-AC_REQUIRE([AM_MAKE_INCLUDE])dnl
-AC_REQUIRE([AM_DEP_TRACK])dnl
-
-ifelse([$1], CC, [depcc="$CC" am_compiler_list=],
- [$1], CXX, [depcc="$CXX" am_compiler_list=],
- [$1], OBJC, [depcc="$OBJC" am_compiler_list='gcc3 gcc'],
- [$1], UPC, [depcc="$UPC" am_compiler_list=],
- [$1], GCJ, [depcc="$GCJ" am_compiler_list='gcc3 gcc'],
- [depcc="$$1" am_compiler_list=])
-
-AC_CACHE_CHECK([dependency style of $depcc],
- [am_cv_$1_dependencies_compiler_type],
-[if test -z "$AMDEP_TRUE" && test -f "$am_depcomp"; then
- # We make a subdir and do the tests there. Otherwise we can end up
- # making bogus files that we don't know about and never remove. For
- # instance it was reported that on HP-UX the gcc test will end up
- # making a dummy file named `D' -- because `-MD' means `put the output
- # in D'.
- mkdir conftest.dir
- # Copy depcomp to subdir because otherwise we won't find it if we're
- # using a relative directory.
- cp "$am_depcomp" conftest.dir
- cd conftest.dir
- # We will build objects and dependencies in a subdirectory because
- # it helps to detect inapplicable dependency modes. For instance
- # both Tru64's cc and ICC support -MD to output dependencies as a
- # side effect of compilation, but ICC will put the dependencies in
- # the current directory while Tru64 will put them in the object
- # directory.
- mkdir sub
-
- am_cv_$1_dependencies_compiler_type=none
- if test "$am_compiler_list" = ""; then
- am_compiler_list=`sed -n ['s/^#*\([a-zA-Z0-9]*\))$/\1/p'] < ./depcomp`
- fi
- am__universal=false
- m4_case([$1], [CC],
- [case " $depcc " in #(
- *\ -arch\ *\ -arch\ *) am__universal=true ;;
- esac],
- [CXX],
- [case " $depcc " in #(
- *\ -arch\ *\ -arch\ *) am__universal=true ;;
- esac])
-
- for depmode in $am_compiler_list; do
- # Setup a source with many dependencies, because some compilers
- # like to wrap large dependency lists on column 80 (with \), and
- # we should not choose a depcomp mode which is confused by this.
- #
- # We need to recreate these files for each test, as the compiler may
- # overwrite some of them when testing with obscure command lines.
- # This happens at least with the AIX C compiler.
- : > sub/conftest.c
- for i in 1 2 3 4 5 6; do
- echo '#include "conftst'$i'.h"' >> sub/conftest.c
- # Using `: > sub/conftst$i.h' creates only sub/conftst1.h with
- # Solaris 8's {/usr,}/bin/sh.
- touch sub/conftst$i.h
- done
- echo "${am__include} ${am__quote}sub/conftest.Po${am__quote}" > confmf
-
- # We check with `-c' and `-o' for the sake of the "dashmstdout"
- # mode. It turns out that the SunPro C++ compiler does not properly
- # handle `-M -o', and we need to detect this. Also, some Intel
- # versions had trouble with output in subdirs
- am__obj=sub/conftest.${OBJEXT-o}
- am__minus_obj="-o $am__obj"
- case $depmode in
- gcc)
- # This depmode causes a compiler race in universal mode.
- test "$am__universal" = false || continue
- ;;
- nosideeffect)
- # after this tag, mechanisms are not by side-effect, so they'll
- # only be used when explicitly requested
- if test "x$enable_dependency_tracking" = xyes; then
- continue
- else
- break
- fi
- ;;
- msvisualcpp | msvcmsys)
- # This compiler won't grok `-c -o', but also, the minuso test has
- # not run yet. These depmodes are late enough in the game, and
- # so weak that their functioning should not be impacted.
- am__obj=conftest.${OBJEXT-o}
- am__minus_obj=
- ;;
- none) break ;;
- esac
- if depmode=$depmode \
- source=sub/conftest.c object=$am__obj \
- depfile=sub/conftest.Po tmpdepfile=sub/conftest.TPo \
- $SHELL ./depcomp $depcc -c $am__minus_obj sub/conftest.c \
- >/dev/null 2>conftest.err &&
- grep sub/conftst1.h sub/conftest.Po > /dev/null 2>&1 &&
- grep sub/conftst6.h sub/conftest.Po > /dev/null 2>&1 &&
- grep $am__obj sub/conftest.Po > /dev/null 2>&1 &&
- ${MAKE-make} -s -f confmf > /dev/null 2>&1; then
- # icc doesn't choke on unknown options, it will just issue warnings
- # or remarks (even with -Werror). So we grep stderr for any message
- # that says an option was ignored or not supported.
- # When given -MP, icc 7.0 and 7.1 complain thusly:
- # icc: Command line warning: ignoring option '-M'; no argument required
- # The diagnosis changed in icc 8.0:
- # icc: Command line remark: option '-MP' not supported
- if (grep 'ignoring option' conftest.err ||
- grep 'not supported' conftest.err) >/dev/null 2>&1; then :; else
- am_cv_$1_dependencies_compiler_type=$depmode
- break
- fi
- fi
- done
-
- cd ..
- rm -rf conftest.dir
-else
- am_cv_$1_dependencies_compiler_type=none
-fi
-])
-AC_SUBST([$1DEPMODE], [depmode=$am_cv_$1_dependencies_compiler_type])
-AM_CONDITIONAL([am__fastdep$1], [
- test "x$enable_dependency_tracking" != xno \
- && test "$am_cv_$1_dependencies_compiler_type" = gcc3])
-])
-
-
-# AM_SET_DEPDIR
-# -------------
-# Choose a directory name for dependency files.
-# This macro is AC_REQUIREd in _AM_DEPENDENCIES
-AC_DEFUN([AM_SET_DEPDIR],
-[AC_REQUIRE([AM_SET_LEADING_DOT])dnl
-AC_SUBST([DEPDIR], ["${am__leading_dot}deps"])dnl
-])
-
-
-# AM_DEP_TRACK
-# ------------
-AC_DEFUN([AM_DEP_TRACK],
-[AC_ARG_ENABLE(dependency-tracking,
-[ --disable-dependency-tracking speeds up one-time build
- --enable-dependency-tracking do not reject slow dependency extractors])
-if test "x$enable_dependency_tracking" != xno; then
- am_depcomp="$ac_aux_dir/depcomp"
- AMDEPBACKSLASH='\'
-fi
-AM_CONDITIONAL([AMDEP], [test "x$enable_dependency_tracking" != xno])
-AC_SUBST([AMDEPBACKSLASH])dnl
-_AM_SUBST_NOTMAKE([AMDEPBACKSLASH])dnl
-])
-
-# Generate code to set up dependency tracking. -*- Autoconf -*-
-
-# Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-#serial 5
-
-# _AM_OUTPUT_DEPENDENCY_COMMANDS
-# ------------------------------
-AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS],
-[{
- # Autoconf 2.62 quotes --file arguments for eval, but not when files
- # are listed without --file. Let's play safe and only enable the eval
- # if we detect the quoting.
- case $CONFIG_FILES in
- *\'*) eval set x "$CONFIG_FILES" ;;
- *) set x $CONFIG_FILES ;;
- esac
- shift
- for mf
- do
- # Strip MF so we end up with the name of the file.
- mf=`echo "$mf" | sed -e 's/:.*$//'`
- # Check whether this is an Automake generated Makefile or not.
- # We used to match only the files named `Makefile.in', but
- # some people rename them; so instead we look at the file content.
- # Grep'ing the first line is not enough: some people post-process
- # each Makefile.in and add a new line on top of each file to say so.
- # Grep'ing the whole file is not good either: AIX grep has a line
- # limit of 2048, but all sed's we know have understand at least 4000.
- if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then
- dirpart=`AS_DIRNAME("$mf")`
- else
- continue
- fi
- # Extract the definition of DEPDIR, am__include, and am__quote
- # from the Makefile without running `make'.
- DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"`
- test -z "$DEPDIR" && continue
- am__include=`sed -n 's/^am__include = //p' < "$mf"`
- test -z "am__include" && continue
- am__quote=`sed -n 's/^am__quote = //p' < "$mf"`
- # When using ansi2knr, U may be empty or an underscore; expand it
- U=`sed -n 's/^U = //p' < "$mf"`
- # Find all dependency output files, they are included files with
- # $(DEPDIR) in their names. We invoke sed twice because it is the
- # simplest approach to changing $(DEPDIR) to its actual value in the
- # expansion.
- for file in `sed -n "
- s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \
- sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g' -e 's/\$U/'"$U"'/g'`; do
- # Make sure the directory exists.
- test -f "$dirpart/$file" && continue
- fdir=`AS_DIRNAME(["$file"])`
- AS_MKDIR_P([$dirpart/$fdir])
- # echo "creating $dirpart/$file"
- echo '# dummy' > "$dirpart/$file"
- done
- done
-}
-])# _AM_OUTPUT_DEPENDENCY_COMMANDS
-
-
-# AM_OUTPUT_DEPENDENCY_COMMANDS
-# -----------------------------
-# This macro should only be invoked once -- use via AC_REQUIRE.
-#
-# This code is only required when automatic dependency tracking
-# is enabled. FIXME. This creates each `.P' file that we will
-# need in order to bootstrap the dependency handling code.
-AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS],
-[AC_CONFIG_COMMANDS([depfiles],
- [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS],
- [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"])
-])
-
-# Do all the work for Automake. -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
-# 2005, 2006, 2008, 2009 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 16
-
-# This macro actually does too much. Some checks are only needed if
-# your package does certain things. But this isn't really a big deal.
-
-# AM_INIT_AUTOMAKE(PACKAGE, VERSION, [NO-DEFINE])
-# AM_INIT_AUTOMAKE([OPTIONS])
-# -----------------------------------------------
-# The call with PACKAGE and VERSION arguments is the old style
-# call (pre autoconf-2.50), which is being phased out. PACKAGE
-# and VERSION should now be passed to AC_INIT and removed from
-# the call to AM_INIT_AUTOMAKE.
-# We support both call styles for the transition. After
-# the next Automake release, Autoconf can make the AC_INIT
-# arguments mandatory, and then we can depend on a new Autoconf
-# release and drop the old call support.
-AC_DEFUN([AM_INIT_AUTOMAKE],
-[AC_PREREQ([2.62])dnl
-dnl Autoconf wants to disallow AM_ names. We explicitly allow
-dnl the ones we care about.
-m4_pattern_allow([^AM_[A-Z]+FLAGS$])dnl
-AC_REQUIRE([AM_SET_CURRENT_AUTOMAKE_VERSION])dnl
-AC_REQUIRE([AC_PROG_INSTALL])dnl
-if test "`cd $srcdir && pwd`" != "`pwd`"; then
- # Use -I$(srcdir) only when $(srcdir) != ., so that make's output
- # is not polluted with repeated "-I."
- AC_SUBST([am__isrc], [' -I$(srcdir)'])_AM_SUBST_NOTMAKE([am__isrc])dnl
- # test to see if srcdir already configured
- if test -f $srcdir/config.status; then
- AC_MSG_ERROR([source directory already configured; run "make distclean" there first])
- fi
-fi
-
-# test whether we have cygpath
-if test -z "$CYGPATH_W"; then
- if (cygpath --version) >/dev/null 2>/dev/null; then
- CYGPATH_W='cygpath -w'
- else
- CYGPATH_W=echo
- fi
-fi
-AC_SUBST([CYGPATH_W])
-
-# Define the identity of the package.
-dnl Distinguish between old-style and new-style calls.
-m4_ifval([$2],
-[m4_ifval([$3], [_AM_SET_OPTION([no-define])])dnl
- AC_SUBST([PACKAGE], [$1])dnl
- AC_SUBST([VERSION], [$2])],
-[_AM_SET_OPTIONS([$1])dnl
-dnl Diagnose old-style AC_INIT with new-style AM_AUTOMAKE_INIT.
-m4_if(m4_ifdef([AC_PACKAGE_NAME], 1)m4_ifdef([AC_PACKAGE_VERSION], 1), 11,,
- [m4_fatal([AC_INIT should be called with package and version arguments])])dnl
- AC_SUBST([PACKAGE], ['AC_PACKAGE_TARNAME'])dnl
- AC_SUBST([VERSION], ['AC_PACKAGE_VERSION'])])dnl
-
-_AM_IF_OPTION([no-define],,
-[AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE", [Name of package])
- AC_DEFINE_UNQUOTED(VERSION, "$VERSION", [Version number of package])])dnl
-
-# Some tools Automake needs.
-AC_REQUIRE([AM_SANITY_CHECK])dnl
-AC_REQUIRE([AC_ARG_PROGRAM])dnl
-AM_MISSING_PROG(ACLOCAL, aclocal-${am__api_version})
-AM_MISSING_PROG(AUTOCONF, autoconf)
-AM_MISSING_PROG(AUTOMAKE, automake-${am__api_version})
-AM_MISSING_PROG(AUTOHEADER, autoheader)
-AM_MISSING_PROG(MAKEINFO, makeinfo)
-AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl
-AC_REQUIRE([AM_PROG_MKDIR_P])dnl
-# We need awk for the "check" target. The system "awk" is bad on
-# some platforms.
-AC_REQUIRE([AC_PROG_AWK])dnl
-AC_REQUIRE([AC_PROG_MAKE_SET])dnl
-AC_REQUIRE([AM_SET_LEADING_DOT])dnl
-_AM_IF_OPTION([tar-ustar], [_AM_PROG_TAR([ustar])],
- [_AM_IF_OPTION([tar-pax], [_AM_PROG_TAR([pax])],
- [_AM_PROG_TAR([v7])])])
-_AM_IF_OPTION([no-dependencies],,
-[AC_PROVIDE_IFELSE([AC_PROG_CC],
- [_AM_DEPENDENCIES(CC)],
- [define([AC_PROG_CC],
- defn([AC_PROG_CC])[_AM_DEPENDENCIES(CC)])])dnl
-AC_PROVIDE_IFELSE([AC_PROG_CXX],
- [_AM_DEPENDENCIES(CXX)],
- [define([AC_PROG_CXX],
- defn([AC_PROG_CXX])[_AM_DEPENDENCIES(CXX)])])dnl
-AC_PROVIDE_IFELSE([AC_PROG_OBJC],
- [_AM_DEPENDENCIES(OBJC)],
- [define([AC_PROG_OBJC],
- defn([AC_PROG_OBJC])[_AM_DEPENDENCIES(OBJC)])])dnl
-])
-_AM_IF_OPTION([silent-rules], [AC_REQUIRE([AM_SILENT_RULES])])dnl
-dnl The `parallel-tests' driver may need to know about EXEEXT, so add the
-dnl `am__EXEEXT' conditional if _AM_COMPILER_EXEEXT was seen. This macro
-dnl is hooked onto _AC_COMPILER_EXEEXT early, see below.
-AC_CONFIG_COMMANDS_PRE(dnl
-[m4_provide_if([_AM_COMPILER_EXEEXT],
- [AM_CONDITIONAL([am__EXEEXT], [test -n "$EXEEXT"])])])dnl
-])
-
-dnl Hook into `_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
-dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
-dnl mangled by Autoconf and run in a shell conditional statement.
-m4_define([_AC_COMPILER_EXEEXT],
-m4_defn([_AC_COMPILER_EXEEXT])[m4_provide([_AM_COMPILER_EXEEXT])])
-
-
-# When config.status generates a header, we must update the stamp-h file.
-# This file resides in the same directory as the config header
-# that is generated. The stamp files are numbered to have different names.
-
-# Autoconf calls _AC_AM_CONFIG_HEADER_HOOK (when defined) in the
-# loop where config.status creates the headers, so we can generate
-# our stamp files there.
-AC_DEFUN([_AC_AM_CONFIG_HEADER_HOOK],
-[# Compute $1's index in $config_headers.
-_am_arg=$1
-_am_stamp_count=1
-for _am_header in $config_headers :; do
- case $_am_header in
- $_am_arg | $_am_arg:* )
- break ;;
- * )
- _am_stamp_count=`expr $_am_stamp_count + 1` ;;
- esac
-done
-echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count])
-
-# Copyright (C) 2001, 2003, 2005, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_INSTALL_SH
-# ------------------
-# Define $install_sh.
-AC_DEFUN([AM_PROG_INSTALL_SH],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-if test x"${install_sh}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- install_sh="\${SHELL} '$am_aux_dir/install-sh'" ;;
- *)
- install_sh="\${SHELL} $am_aux_dir/install-sh"
- esac
-fi
-AC_SUBST(install_sh)])
-
-# Copyright (C) 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
-
-# Check whether the underlying file-system supports filenames
-# with a leading dot. For instance MS-DOS doesn't.
-AC_DEFUN([AM_SET_LEADING_DOT],
-[rm -rf .tst 2>/dev/null
-mkdir .tst 2>/dev/null
-if test -d .tst; then
- am__leading_dot=.
-else
- am__leading_dot=_
-fi
-rmdir .tst 2>/dev/null
-AC_SUBST([am__leading_dot])])
-
-# Add --enable-maintainer-mode option to configure. -*- Autoconf -*-
-# From Jim Meyering
-
-# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 5
-
-# AM_MAINTAINER_MODE([DEFAULT-MODE])
-# ----------------------------------
-# Control maintainer-specific portions of Makefiles.
-# Default is to disable them, unless `enable' is passed literally.
-# For symmetry, `disable' may be passed as well. Anyway, the user
-# can override the default with the --enable/--disable switch.
-AC_DEFUN([AM_MAINTAINER_MODE],
-[m4_case(m4_default([$1], [disable]),
- [enable], [m4_define([am_maintainer_other], [disable])],
- [disable], [m4_define([am_maintainer_other], [enable])],
- [m4_define([am_maintainer_other], [enable])
- m4_warn([syntax], [unexpected argument to AM@&t@_MAINTAINER_MODE: $1])])
-AC_MSG_CHECKING([whether to am_maintainer_other maintainer-specific portions of Makefiles])
- dnl maintainer-mode's default is 'disable' unless 'enable' is passed
- AC_ARG_ENABLE([maintainer-mode],
-[ --][am_maintainer_other][-maintainer-mode am_maintainer_other make rules and dependencies not useful
- (and sometimes confusing) to the casual installer],
- [USE_MAINTAINER_MODE=$enableval],
- [USE_MAINTAINER_MODE=]m4_if(am_maintainer_other, [enable], [no], [yes]))
- AC_MSG_RESULT([$USE_MAINTAINER_MODE])
- AM_CONDITIONAL([MAINTAINER_MODE], [test $USE_MAINTAINER_MODE = yes])
- MAINT=$MAINTAINER_MODE_TRUE
- AC_SUBST([MAINT])dnl
-]
-)
-
-AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
-
-# Check to see how 'make' treats includes. -*- Autoconf -*-
-
-# Copyright (C) 2001, 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 4
-
-# AM_MAKE_INCLUDE()
-# -----------------
-# Check to see how make treats includes.
-AC_DEFUN([AM_MAKE_INCLUDE],
-[am_make=${MAKE-make}
-cat > confinc << 'END'
-am__doit:
- @echo this is the am__doit target
-.PHONY: am__doit
-END
-# If we don't find an include directive, just comment out the code.
-AC_MSG_CHECKING([for style of include used by $am_make])
-am__include="#"
-am__quote=
-_am_result=none
-# First try GNU make style include.
-echo "include confinc" > confmf
-# Ignore all kinds of additional output from `make'.
-case `$am_make -s -f confmf 2> /dev/null` in #(
-*the\ am__doit\ target*)
- am__include=include
- am__quote=
- _am_result=GNU
- ;;
-esac
-# Now try BSD make style include.
-if test "$am__include" = "#"; then
- echo '.include "confinc"' > confmf
- case `$am_make -s -f confmf 2> /dev/null` in #(
- *the\ am__doit\ target*)
- am__include=.include
- am__quote="\""
- _am_result=BSD
- ;;
- esac
-fi
-AC_SUBST([am__include])
-AC_SUBST([am__quote])
-AC_MSG_RESULT([$_am_result])
-rm -f confinc confmf
-])
-
-# Fake the existence of programs that GNU maintainers use. -*- Autoconf -*-
-
-# Copyright (C) 1997, 1999, 2000, 2001, 2003, 2004, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 6
-
-# AM_MISSING_PROG(NAME, PROGRAM)
-# ------------------------------
-AC_DEFUN([AM_MISSING_PROG],
-[AC_REQUIRE([AM_MISSING_HAS_RUN])
-$1=${$1-"${am_missing_run}$2"}
-AC_SUBST($1)])
-
-
-# AM_MISSING_HAS_RUN
-# ------------------
-# Define MISSING if not defined so far and test if it supports --run.
-# If it does, set am_missing_run to use it, otherwise, to nothing.
-AC_DEFUN([AM_MISSING_HAS_RUN],
-[AC_REQUIRE([AM_AUX_DIR_EXPAND])dnl
-AC_REQUIRE_AUX_FILE([missing])dnl
-if test x"${MISSING+set}" != xset; then
- case $am_aux_dir in
- *\ * | *\ *)
- MISSING="\${SHELL} \"$am_aux_dir/missing\"" ;;
- *)
- MISSING="\${SHELL} $am_aux_dir/missing" ;;
- esac
-fi
-# Use eval to expand $SHELL
-if eval "$MISSING --run true"; then
- am_missing_run="$MISSING --run "
-else
- am_missing_run=
- AC_MSG_WARN([`missing' script is too old or missing])
-fi
-])
-
-# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_MKDIR_P
-# ---------------
-# Check for `mkdir -p'.
-AC_DEFUN([AM_PROG_MKDIR_P],
-[AC_PREREQ([2.60])dnl
-AC_REQUIRE([AC_PROG_MKDIR_P])dnl
-dnl Automake 1.8 to 1.9.6 used to define mkdir_p. We now use MKDIR_P,
-dnl while keeping a definition of mkdir_p for backward compatibility.
-dnl @MKDIR_P@ is magic: AC_OUTPUT adjusts its value for each Makefile.
-dnl However we cannot define mkdir_p as $(MKDIR_P) for the sake of
-dnl Makefile.ins that do not define MKDIR_P, so we do our own
-dnl adjustment using top_builddir (which is defined more often than
-dnl MKDIR_P).
-AC_SUBST([mkdir_p], ["$MKDIR_P"])dnl
-case $mkdir_p in
- [[\\/$]]* | ?:[[\\/]]*) ;;
- */*) mkdir_p="\$(top_builddir)/$mkdir_p" ;;
-esac
-])
-
-# Helper functions for option handling. -*- Autoconf -*-
-
-# Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 4
-
-# _AM_MANGLE_OPTION(NAME)
-# -----------------------
-AC_DEFUN([_AM_MANGLE_OPTION],
-[[_AM_OPTION_]m4_bpatsubst($1, [[^a-zA-Z0-9_]], [_])])
-
-# _AM_SET_OPTION(NAME)
-# ------------------------------
-# Set option NAME. Presently that only means defining a flag for this option.
-AC_DEFUN([_AM_SET_OPTION],
-[m4_define(_AM_MANGLE_OPTION([$1]), 1)])
-
-# _AM_SET_OPTIONS(OPTIONS)
-# ----------------------------------
-# OPTIONS is a space-separated list of Automake options.
-AC_DEFUN([_AM_SET_OPTIONS],
-[m4_foreach_w([_AM_Option], [$1], [_AM_SET_OPTION(_AM_Option)])])
-
-# _AM_IF_OPTION(OPTION, IF-SET, [IF-NOT-SET])
-# -------------------------------------------
-# Execute IF-SET if OPTION is set, IF-NOT-SET otherwise.
-AC_DEFUN([_AM_IF_OPTION],
-[m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])])
-
-# Check to make sure that the build environment is sane. -*- Autoconf -*-
-
-# Copyright (C) 1996, 1997, 2000, 2001, 2003, 2005, 2008
-# Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 5
-
-# AM_SANITY_CHECK
-# ---------------
-AC_DEFUN([AM_SANITY_CHECK],
-[AC_MSG_CHECKING([whether build environment is sane])
-# Just in case
-sleep 1
-echo timestamp > conftest.file
-# Reject unsafe characters in $srcdir or the absolute working directory
-# name. Accept space and tab only in the latter.
-am_lf='
-'
-case `pwd` in
- *[[\\\"\#\$\&\'\`$am_lf]]*)
- AC_MSG_ERROR([unsafe absolute working directory name]);;
-esac
-case $srcdir in
- *[[\\\"\#\$\&\'\`$am_lf\ \ ]]*)
- AC_MSG_ERROR([unsafe srcdir value: `$srcdir']);;
-esac
-
-# Do `set' in a subshell so we don't clobber the current shell's
-# arguments. Must try -L first in case configure is actually a
-# symlink; some systems play weird games with the mod time of symlinks
-# (eg FreeBSD returns the mod time of the symlink's containing
-# directory).
-if (
- set X `ls -Lt "$srcdir/configure" conftest.file 2> /dev/null`
- if test "$[*]" = "X"; then
- # -L didn't work.
- set X `ls -t "$srcdir/configure" conftest.file`
- fi
- rm -f conftest.file
- if test "$[*]" != "X $srcdir/configure conftest.file" \
- && test "$[*]" != "X conftest.file $srcdir/configure"; then
-
- # If neither matched, then we have a broken ls. This can happen
- # if, for instance, CONFIG_SHELL is bash and it inherits a
- # broken ls alias from the environment. This has actually
- # happened. Such a system could not be considered "sane".
- AC_MSG_ERROR([ls -t appears to fail. Make sure there is not a broken
-alias in your environment])
- fi
-
- test "$[2]" = conftest.file
- )
-then
- # Ok.
- :
-else
- AC_MSG_ERROR([newly created file is older than distributed files!
-Check your system clock])
-fi
-AC_MSG_RESULT(yes)])
-
-# Copyright (C) 2001, 2003, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# AM_PROG_INSTALL_STRIP
-# ---------------------
-# One issue with vendor `install' (even GNU) is that you can't
-# specify the program used to strip binaries. This is especially
-# annoying in cross-compiling environments, where the build's strip
-# is unlikely to handle the host's binaries.
-# Fortunately install-sh will honor a STRIPPROG variable, so we
-# always use install-sh in `make install-strip', and initialize
-# STRIPPROG with the value of the STRIP variable (set by the user).
-AC_DEFUN([AM_PROG_INSTALL_STRIP],
-[AC_REQUIRE([AM_PROG_INSTALL_SH])dnl
-# Installed binaries are usually stripped using `strip' when the user
-# run `make install-strip'. However `strip' might not be the right
-# tool to use in cross-compilation environments, therefore Automake
-# will honor the `STRIP' environment variable to overrule this program.
-dnl Don't test for $cross_compiling = yes, because it might be `maybe'.
-if test "$cross_compiling" != no; then
- AC_CHECK_TOOL([STRIP], [strip], :)
-fi
-INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s"
-AC_SUBST([INSTALL_STRIP_PROGRAM])])
-
-# Copyright (C) 2006, 2008 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
-
-# _AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
-# Prevent Automake from outputting VARIABLE = @VARIABLE@ in Makefile.in.
-# This macro is traced by Automake.
-AC_DEFUN([_AM_SUBST_NOTMAKE])
-
-# AM_SUBST_NOTMAKE(VARIABLE)
-# ---------------------------
-# Public sister of _AM_SUBST_NOTMAKE.
-AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)])
-
-# Check how to create a tarball. -*- Autoconf -*-
-
-# Copyright (C) 2004, 2005 Free Software Foundation, Inc.
-#
-# This file is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# serial 2
-
-# _AM_PROG_TAR(FORMAT)
-# --------------------
-# Check how to create a tarball in format FORMAT.
-# FORMAT should be one of `v7', `ustar', or `pax'.
-#
-# Substitute a variable $(am__tar) that is a command
-# writing to stdout a FORMAT-tarball containing the directory
-# $tardir.
-# tardir=directory && $(am__tar) > result.tar
-#
-# Substitute a variable $(am__untar) that extract such
-# a tarball read from stdin.
-# $(am__untar) < result.tar
-AC_DEFUN([_AM_PROG_TAR],
-[# Always define AMTAR for backward compatibility.
-AM_MISSING_PROG([AMTAR], [tar])
-m4_if([$1], [v7],
- [am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'],
- [m4_case([$1], [ustar],, [pax],,
- [m4_fatal([Unknown tar format])])
-AC_MSG_CHECKING([how to create a $1 tar archive])
-# Loop over all known methods to create a tar archive until one works.
-_am_tools='gnutar m4_if([$1], [ustar], [plaintar]) pax cpio none'
-_am_tools=${am_cv_prog_tar_$1-$_am_tools}
-# Do not fold the above two line into one, because Tru64 sh and
-# Solaris sh will not grok spaces in the rhs of `-'.
-for _am_tool in $_am_tools
-do
- case $_am_tool in
- gnutar)
- for _am_tar in tar gnutar gtar;
- do
- AM_RUN_LOG([$_am_tar --version]) && break
- done
- am__tar="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$$tardir"'
- am__tar_="$_am_tar --format=m4_if([$1], [pax], [posix], [$1]) -chf - "'"$tardir"'
- am__untar="$_am_tar -xf -"
- ;;
- plaintar)
- # Must skip GNU tar: if it does not support --format= it doesn't create
- # ustar tarball either.
- (tar --version) >/dev/null 2>&1 && continue
- am__tar='tar chf - "$$tardir"'
- am__tar_='tar chf - "$tardir"'
- am__untar='tar xf -'
- ;;
- pax)
- am__tar='pax -L -x $1 -w "$$tardir"'
- am__tar_='pax -L -x $1 -w "$tardir"'
- am__untar='pax -r'
- ;;
- cpio)
- am__tar='find "$$tardir" -print | cpio -o -H $1 -L'
- am__tar_='find "$tardir" -print | cpio -o -H $1 -L'
- am__untar='cpio -i -H $1 -d'
- ;;
- none)
- am__tar=false
- am__tar_=false
- am__untar=false
- ;;
- esac
-
- # If the value was cached, stop now. We just wanted to have am__tar
- # and am__untar set.
- test -n "${am_cv_prog_tar_$1}" && break
-
- # tar/untar a dummy directory, and stop if the command works
- rm -rf conftest.dir
- mkdir conftest.dir
- echo GrepMe > conftest.dir/file
- AM_RUN_LOG([tardir=conftest.dir && eval $am__tar_ >conftest.tar])
- rm -rf conftest.dir
- if test -s conftest.tar; then
- AM_RUN_LOG([$am__untar <conftest.tar])
- grep GrepMe conftest.dir/file >/dev/null 2>&1 && break
- fi
-done
-rm -rf conftest.dir
-
-AC_CACHE_VAL([am_cv_prog_tar_$1], [am_cv_prog_tar_$1=$_am_tool])
-AC_MSG_RESULT([$am_cv_prog_tar_$1])])
-AC_SUBST([am__tar])
-AC_SUBST([am__untar])
-]) # _AM_PROG_TAR
-
--- /dev/null
+
+DOCDIR=/usr/share/doc/pve-manager/
+
+all:
+
+.PHONY: install
+install: aplinfo.dat support@proxmox.com.pubkey
+ install -D -m 0644 aplinfo.dat ${DESTDIR}${DOCDIR}/aplinfo.dat
+ install -D -m 0644 support@proxmox.com.pubkey ${DESTDIR}${DOCDIR}/support@proxmox.com.pubkey
+
+.PHONY: distclean
+distclean: clean
+
+.PHONY: clean
+clean:
+ rm -rf *~ aplinfo.dat.gz aplinfo.dat.asc
+++ /dev/null
-include $(top_builddir)/common.mk
-
-aplinfo_DATA = aplinfo.dat support@proxmox.com.pubkey
-
-CLEANFILES = *~ aplinfo.dat.gz aplinfo.dat.asc
-
-aplinfodir = /usr/share/doc/pve-manager
+++ /dev/null
-#!/bin/sh
-
-# Refresh GNU autotools toolchain.
-for i in config.guess config.sub missing install-sh mkinstalldirs ; do
- test -r /usr/share/automake-1.9/${i} && {
- rm -f ${i}
- cp /usr/share/automake-1.9/${i} .
- }
- chmod 755 ${i}
-done
-
-aclocal
-#aclocal -I m4
-#aclocal -I cmulocal
-#autoheader
-automake --foreign --add-missing
-autoconf
-
-exit 0
--- /dev/null
+include ../defines.mk
+
+SUBDIRS = init.d cron test
+
+SCRIPTS = \
+ pvestatd \
+ pvesh \
+ pveam \
+ pvebanner \
+ pvectl \
+ pvedaemon \
+ pveversion \
+ pveperf
+
+MANS = \
+ pvestatd.1 \
+ pvedaemon.1 \
+ pveversion.1 \
+ pveperf.1
+
+%.1: %
+ pod2man -n $* -s 1 -r "proxmox ${VERSION}" -c "Proxmox Documentation" <$* >$*.1
+
+.PHONY: install
+install: ${SCRIPTS} ${MANS}
+ perl -I.. ./pvesh verifyapi
+ install -d ${BINDIR}
+ install -m 0755 ${SCRIPTS} ${BINDIR}
+ install -d ${MAN1DIR}
+ install -m 0644 ${MANS} ${MAN1DIR}
+ set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i $@; done
+
+.PHONY: distclean
+distclean: clean
+ set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i $@; done
+
+.PHONY: clean
+clean:
+ rm -rf *~ ${MANS}
+ set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i $@; done
+++ /dev/null
-include $(top_builddir)/common.mk
-
-SUBDIRS = init.d cron test
-
-bin_SCRIPTS = \
- pvestatd \
- pvesh \
- pveam \
- pvebanner \
- pvectl \
- pvedaemon \
- pveversion \
- pveperf
-
-man_MANS = \
- pvestatd.1 \
- pvedaemon.1 \
- pveversion.1 \
- pveperf.1
-
-CLEANFILES = $(man_MANS) *~
-
-bindir = /usr/bin
-
-install-exec-hook:
- perl -I$(top_builddir)/lib ./pvesh verifyapi
+++ /dev/null
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-subdir = bin
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
- *) f=$$p;; \
- esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
- srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
- for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
- for p in $$list; do echo "$$p $$p"; done | \
- sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
- $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
- if (++n[$$2] == $(am__install_max)) \
- { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
- END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
- sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
- sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__installdirs = "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"
-SCRIPTS = $(bin_SCRIPTS)
-SOURCES =
-DIST_SOURCES =
-RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
- html-recursive info-recursive install-data-recursive \
- install-dvi-recursive install-exec-recursive \
- install-html-recursive install-info-recursive \
- install-pdf-recursive install-ps-recursive install-recursive \
- installcheck-recursive installdirs-recursive pdf-recursive \
- ps-recursive uninstall-recursive
-man1dir = $(mandir)/man1
-NROFF = nroff
-MANS = $(man_MANS)
-RECURSIVE_CLEAN_TARGETS = mostlyclean-recursive clean-recursive \
- distclean-recursive maintainer-clean-recursive
-AM_RECURSIVE_TARGETS = $(RECURSIVE_TARGETS:-recursive=) \
- $(RECURSIVE_CLEAN_TARGETS:-recursive=) tags TAGS ctags CTAGS \
- distdir
-ETAGS = etags
-CTAGS = ctags
-DIST_SUBDIRS = $(SUBDIRS)
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-am__relativize = \
- dir0=`pwd`; \
- sed_first='s,^\([^/]*\)/.*$$,\1,'; \
- sed_rest='s,^[^/]*/*,,'; \
- sed_last='s,^.*/\([^/]*\)$$,\1,'; \
- sed_butlast='s,/*[^/]*$$,,'; \
- while test -n "$$dir1"; do \
- first=`echo "$$dir1" | sed -e "$$sed_first"`; \
- if test "$$first" != "."; then \
- if test "$$first" = ".."; then \
- dir2=`echo "$$dir0" | sed -e "$$sed_last"`/"$$dir2"; \
- dir0=`echo "$$dir0" | sed -e "$$sed_butlast"`; \
- else \
- first2=`echo "$$dir2" | sed -e "$$sed_first"`; \
- if test "$$first2" = "$$first"; then \
- dir2=`echo "$$dir2" | sed -e "$$sed_rest"`; \
- else \
- dir2="../$$dir2"; \
- fi; \
- dir0="$$dir0"/"$$first"; \
- fi; \
- fi; \
- dir1=`echo "$$dir1" | sed -e "$$sed_rest"`; \
- done; \
- reldir="$$dir2"
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DOCDIR = @DOCDIR@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EXEEXT = @EXEEXT@
-GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
-GMSGFMT = @GMSGFMT@
-GMSGFMT_015 = @GMSGFMT_015@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-MSGFMT = @MSGFMT@
-MSGFMT_015 = @MSGFMT_015@
-MSGMERGE = @MSGMERGE@
-OBJEXT = @OBJEXT@
-PACKAGE = @PACKAGE@
-PACKAGERELEASE = @PACKAGERELEASE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PERL_LIBDIR = @PERL_LIBDIR@
-PROXMOX_ETC = @PROXMOX_ETC@
-REPOID = @REPOID@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-USE_NLS = @USE_NLS@
-VERSION = @VERSION@
-WWW_BASEDIR = @WWW_BASEDIR@
-WWW_CSSDIR = @WWW_CSSDIR@
-WWW_EXTDIR = @WWW_EXTDIR@
-WWW_IMAGEDIR = @WWW_IMAGEDIR@
-WWW_ROOTDIR = @WWW_ROOTDIR@
-XGETTEXT = @XGETTEXT@
-XGETTEXT_015 = @XGETTEXT_015@
-XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = /usr/bin
-build_alias = @build_alias@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host_alias = @host_alias@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-SUBDIRS = init.d cron test
-bin_SCRIPTS = \
- pvestatd \
- pvesh \
- pveam \
- pvebanner \
- pvectl \
- pvedaemon \
- pveversion \
- pveperf
-
-man_MANS = \
- pvestatd.1 \
- pvedaemon.1 \
- pveversion.1 \
- pveperf.1
-
-CLEANFILES = $(man_MANS) *~
-all: all-recursive
-
-.SUFFIXES:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bin/Makefile'; \
- $(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign bin/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-install-binSCRIPTS: $(bin_SCRIPTS)
- @$(NORMAL_INSTALL)
- test -z "$(bindir)" || $(MKDIR_P) "$(DESTDIR)$(bindir)"
- @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || list=; \
- for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
- done | \
- sed -e 'p;s,.*/,,;n' \
- -e 'h;s|.*|.|' \
- -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
- $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
- { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
- if ($$2 == $$4) { files[d] = files[d] " " $$1; \
- if (++n[d] == $(am__install_max)) { \
- print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
- else { print "f", d "/" $$4, $$1 } } \
- END { for (d in files) print "f", d, files[d] }' | \
- while read type dir files; do \
- if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
- test -z "$$files" || { \
- echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(bindir)$$dir'"; \
- $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \
- } \
- ; done
-
-uninstall-binSCRIPTS:
- @$(NORMAL_UNINSTALL)
- @list='$(bin_SCRIPTS)'; test -n "$(bindir)" || exit 0; \
- files=`for p in $$list; do echo "$$p"; done | \
- sed -e 's,.*/,,;$(transform)'`; \
- test -n "$$list" || exit 0; \
- echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \
- cd "$(DESTDIR)$(bindir)" && rm -f $$files
-install-man1: $(man_MANS)
- @$(NORMAL_INSTALL)
- test -z "$(man1dir)" || $(MKDIR_P) "$(DESTDIR)$(man1dir)"
- @list=''; test -n "$(man1dir)" || exit 0; \
- { for i in $$list; do echo "$$i"; done; \
- l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
- sed -n '/\.1[a-z]*$$/p'; \
- } | while read p; do \
- if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
- echo "$$d$$p"; echo "$$p"; \
- done | \
- sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
- -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
- sed 'N;N;s,\n, ,g' | { \
- list=; while read file base inst; do \
- if test "$$base" = "$$inst"; then list="$$list $$file"; else \
- echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man1dir)/$$inst'"; \
- $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man1dir)/$$inst" || exit $$?; \
- fi; \
- done; \
- for i in $$list; do echo "$$i"; done | $(am__base_list) | \
- while read files; do \
- test -z "$$files" || { \
- echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man1dir)'"; \
- $(INSTALL_DATA) $$files "$(DESTDIR)$(man1dir)" || exit $$?; }; \
- done; }
-
-uninstall-man1:
- @$(NORMAL_UNINSTALL)
- @list=''; test -n "$(man1dir)" || exit 0; \
- files=`{ for i in $$list; do echo "$$i"; done; \
- l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
- sed -n '/\.1[a-z]*$$/p'; \
- } | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^1][0-9a-z]*$$,1,;x' \
- -e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
- test -z "$$files" || { \
- echo " ( cd '$(DESTDIR)$(man1dir)' && rm -f" $$files ")"; \
- cd "$(DESTDIR)$(man1dir)" && rm -f $$files; }
-
-# This directory's subdirectories are mostly independent; you can cd
-# into them and run `make' without going through this Makefile.
-# To change the values of `make' variables: instead of editing Makefiles,
-# (1) if the variable is set in `config.status', edit `config.status'
-# (which will cause the Makefiles to be regenerated when you run `make');
-# (2) otherwise, pass the desired values on the `make' command line.
-$(RECURSIVE_TARGETS):
- @fail= failcom='exit 1'; \
- for f in x $$MAKEFLAGS; do \
- case $$f in \
- *=* | --[!k]*);; \
- *k*) failcom='fail=yes';; \
- esac; \
- done; \
- dot_seen=no; \
- target=`echo $@ | sed s/-recursive//`; \
- list='$(SUBDIRS)'; for subdir in $$list; do \
- echo "Making $$target in $$subdir"; \
- if test "$$subdir" = "."; then \
- dot_seen=yes; \
- local_target="$$target-am"; \
- else \
- local_target="$$target"; \
- fi; \
- ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
- || eval $$failcom; \
- done; \
- if test "$$dot_seen" = "no"; then \
- $(MAKE) $(AM_MAKEFLAGS) "$$target-am" || exit 1; \
- fi; test -z "$$fail"
-
-$(RECURSIVE_CLEAN_TARGETS):
- @fail= failcom='exit 1'; \
- for f in x $$MAKEFLAGS; do \
- case $$f in \
- *=* | --[!k]*);; \
- *k*) failcom='fail=yes';; \
- esac; \
- done; \
- dot_seen=no; \
- case "$@" in \
- distclean-* | maintainer-clean-*) list='$(DIST_SUBDIRS)' ;; \
- *) list='$(SUBDIRS)' ;; \
- esac; \
- rev=''; for subdir in $$list; do \
- if test "$$subdir" = "."; then :; else \
- rev="$$subdir $$rev"; \
- fi; \
- done; \
- rev="$$rev ."; \
- target=`echo $@ | sed s/-recursive//`; \
- for subdir in $$rev; do \
- echo "Making $$target in $$subdir"; \
- if test "$$subdir" = "."; then \
- local_target="$$target-am"; \
- else \
- local_target="$$target"; \
- fi; \
- ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) $$local_target) \
- || eval $$failcom; \
- done && test -z "$$fail"
-tags-recursive:
- list='$(SUBDIRS)'; for subdir in $$list; do \
- test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) tags); \
- done
-ctags-recursive:
- list='$(SUBDIRS)'; for subdir in $$list; do \
- test "$$subdir" = . || ($(am__cd) $$subdir && $(MAKE) $(AM_MAKEFLAGS) ctags); \
- done
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: tags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- set x; \
- here=`pwd`; \
- if ($(ETAGS) --etags-include --version) >/dev/null 2>&1; then \
- include_option=--etags-include; \
- empty_fix=.; \
- else \
- include_option=--include; \
- empty_fix=; \
- fi; \
- list='$(SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- test ! -f $$subdir/TAGS || \
- set "$$@" "$$include_option=$$here/$$subdir/TAGS"; \
- fi; \
- done; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- shift; \
- if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
- test -n "$$unique" || unique=$$empty_fix; \
- if test $$# -gt 0; then \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- "$$@" $$unique; \
- else \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$unique; \
- fi; \
- fi
-ctags: CTAGS
-CTAGS: ctags-recursive $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
- END { if (nonempty) { for (i in files) print i; }; }'`; \
- test -z "$(CTAGS_ARGS)$$unique" \
- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && $(am__cd) $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) "$$here"
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- @list='$(MANS)'; if test -n "$$list"; then \
- list=`for p in $$list; do \
- if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
- if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
- if test -n "$$list" && \
- grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
- echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
- grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \
- echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \
- echo " typically \`make maintainer-clean' will remove them" >&2; \
- exit 1; \
- else :; fi; \
- else :; fi
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
- @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- test -d "$(distdir)/$$subdir" \
- || $(MKDIR_P) "$(distdir)/$$subdir" \
- || exit 1; \
- fi; \
- done
- @list='$(DIST_SUBDIRS)'; for subdir in $$list; do \
- if test "$$subdir" = .; then :; else \
- dir1=$$subdir; dir2="$(distdir)/$$subdir"; \
- $(am__relativize); \
- new_distdir=$$reldir; \
- dir1=$$subdir; dir2="$(top_distdir)"; \
- $(am__relativize); \
- new_top_distdir=$$reldir; \
- echo " (cd $$subdir && $(MAKE) $(AM_MAKEFLAGS) top_distdir="$$new_top_distdir" distdir="$$new_distdir" \\"; \
- echo " am__remove_distdir=: am__skip_length_check=: am__skip_mode_fix=: distdir)"; \
- ($(am__cd) $$subdir && \
- $(MAKE) $(AM_MAKEFLAGS) \
- top_distdir="$$new_top_distdir" \
- distdir="$$new_distdir" \
- am__remove_distdir=: \
- am__skip_length_check=: \
- am__skip_mode_fix=: \
- distdir) \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-recursive
-all-am: Makefile $(SCRIPTS) $(MANS)
-installdirs: installdirs-recursive
-installdirs-am:
- for dir in "$(DESTDIR)$(bindir)" "$(DESTDIR)$(man1dir)"; do \
- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
- done
-install: install-recursive
-install-exec: install-exec-recursive
-install-data: install-data-recursive
-uninstall: uninstall-recursive
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-recursive
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
- -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-recursive
-
-clean-am: clean-generic mostlyclean-am
-
-distclean: distclean-recursive
- -rm -f Makefile
-distclean-am: clean-am distclean-generic distclean-tags
-
-dvi: dvi-recursive
-
-dvi-am:
-
-html: html-recursive
-
-html-am:
-
-info: info-recursive
-
-info-am:
-
-install-data-am: install-man
-
-install-dvi: install-dvi-recursive
-
-install-dvi-am:
-
-install-exec-am: install-binSCRIPTS
- @$(NORMAL_INSTALL)
- $(MAKE) $(AM_MAKEFLAGS) install-exec-hook
-install-html: install-html-recursive
-
-install-html-am:
-
-install-info: install-info-recursive
-
-install-info-am:
-
-install-man: install-man1
-
-install-pdf: install-pdf-recursive
-
-install-pdf-am:
-
-install-ps: install-ps-recursive
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-recursive
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-recursive
-
-mostlyclean-am: mostlyclean-generic
-
-pdf: pdf-recursive
-
-pdf-am:
-
-ps: ps-recursive
-
-ps-am:
-
-uninstall-am: uninstall-binSCRIPTS uninstall-man
-
-uninstall-man: uninstall-man1
-
-.MAKE: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) ctags-recursive \
- install-am install-exec-am install-strip tags-recursive
-
-.PHONY: $(RECURSIVE_CLEAN_TARGETS) $(RECURSIVE_TARGETS) CTAGS GTAGS \
- all all-am check check-am clean clean-generic ctags \
- ctags-recursive distclean distclean-generic distclean-tags \
- distdir dvi dvi-am html html-am info info-am install \
- install-am install-binSCRIPTS install-data install-data-am \
- install-dvi install-dvi-am install-exec install-exec-am \
- install-exec-hook install-html install-html-am install-info \
- install-info-am install-man install-man1 install-pdf \
- install-pdf-am install-ps install-ps-am install-strip \
- installcheck installcheck-am installdirs installdirs-am \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-generic pdf pdf-am ps ps-am tags tags-recursive \
- uninstall uninstall-am uninstall-binSCRIPTS uninstall-man \
- uninstall-man1
-
-include $(top_builddir)/common.mk
-
-install-exec-hook:
- perl -I$(top_builddir)/lib ./pvesh verifyapi
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
--- /dev/null
+SUBDIRS = daily
+
+all: ${SUBDIRS}
+
+%:
+ set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i $@; done
+++ /dev/null
-SUBDIRS = daily
\ No newline at end of file
--- /dev/null
+include ../../../defines.mk
+
+all:
+
+.PHONY: install
+install: pve
+ install -d ${CRONDAILYDIR}
+ install -m 0755 pve ${CRONDAILYDIR}
+
+.PHONY: distclean
+distclean: clean
+
+.PHONY: clean
+clean:
+ rm -rf *~
+++ /dev/null
-include $(top_builddir)/common.mk
-
-crondaily_SCRIPTS = pve
-crondailydir = /etc/cron.daily
-
-CLEANFILES = *~
--- /dev/null
+include ../../defines.mk
+
+all:
+
+SCRIPTS = \
+ pvedaemon \
+ pvebanner \
+ pvestatd \
+ pvenetcommit
+
+.PHONY: install
+install: ${SCRIPTS}
+ install -d ${INITDBINDIR}
+ install -m 0755 ${SCRIPTS} ${INITDBINDIR}
+
+.PHONY: distclean
+distclean: clean
+
+.PHONY: clean
+clean:
+ rm -rf *~
+++ /dev/null
-include $(top_builddir)/common.mk
-
-initdbin_SCRIPTS = \
- pvedaemon \
- pvebanner \
- pvestatd \
- pvenetcommit
-
-initdbindir = /etc/init.d/
-
-CLEANFILES=*~
\ No newline at end of file
+++ /dev/null
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-subdir = bin/init.d
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
- *) f=$$p;; \
- esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
- srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
- for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
- for p in $$list; do echo "$$p $$p"; done | \
- sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
- $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
- if (++n[$$2] == $(am__install_max)) \
- { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
- END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
- sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
- sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__installdirs = "$(DESTDIR)$(initdbindir)"
-SCRIPTS = $(initdbin_SCRIPTS)
-SOURCES =
-DIST_SOURCES =
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DOCDIR = @DOCDIR@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EXEEXT = @EXEEXT@
-GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
-GMSGFMT = @GMSGFMT@
-GMSGFMT_015 = @GMSGFMT_015@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-MSGFMT = @MSGFMT@
-MSGFMT_015 = @MSGFMT_015@
-MSGMERGE = @MSGMERGE@
-OBJEXT = @OBJEXT@
-PACKAGE = @PACKAGE@
-PACKAGERELEASE = @PACKAGERELEASE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PERL_LIBDIR = @PERL_LIBDIR@
-PROXMOX_ETC = @PROXMOX_ETC@
-REPOID = @REPOID@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-USE_NLS = @USE_NLS@
-VERSION = @VERSION@
-WWW_BASEDIR = @WWW_BASEDIR@
-WWW_CSSDIR = @WWW_CSSDIR@
-WWW_EXTDIR = @WWW_EXTDIR@
-WWW_IMAGEDIR = @WWW_IMAGEDIR@
-WWW_ROOTDIR = @WWW_ROOTDIR@
-XGETTEXT = @XGETTEXT@
-XGETTEXT_015 = @XGETTEXT_015@
-XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build_alias = @build_alias@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host_alias = @host_alias@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-initdbin_SCRIPTS = \
- pvedaemon \
- pvebanner \
- pvestatd \
- pvenetcommit
-
-initdbindir = /etc/init.d/
-CLEANFILES = *~
-all: all-am
-
-.SUFFIXES:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bin/init.d/Makefile'; \
- $(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign bin/init.d/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-install-initdbinSCRIPTS: $(initdbin_SCRIPTS)
- @$(NORMAL_INSTALL)
- test -z "$(initdbindir)" || $(MKDIR_P) "$(DESTDIR)$(initdbindir)"
- @list='$(initdbin_SCRIPTS)'; test -n "$(initdbindir)" || list=; \
- for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
- done | \
- sed -e 'p;s,.*/,,;n' \
- -e 'h;s|.*|.|' \
- -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
- $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
- { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
- if ($$2 == $$4) { files[d] = files[d] " " $$1; \
- if (++n[d] == $(am__install_max)) { \
- print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
- else { print "f", d "/" $$4, $$1 } } \
- END { for (d in files) print "f", d, files[d] }' | \
- while read type dir files; do \
- if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
- test -z "$$files" || { \
- echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(initdbindir)$$dir'"; \
- $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(initdbindir)$$dir" || exit $$?; \
- } \
- ; done
-
-uninstall-initdbinSCRIPTS:
- @$(NORMAL_UNINSTALL)
- @list='$(initdbin_SCRIPTS)'; test -n "$(initdbindir)" || exit 0; \
- files=`for p in $$list; do echo "$$p"; done | \
- sed -e 's,.*/,,;$(transform)'`; \
- test -n "$$list" || exit 0; \
- echo " ( cd '$(DESTDIR)$(initdbindir)' && rm -f" $$files ")"; \
- cd "$(DESTDIR)$(initdbindir)" && rm -f $$files
-tags: TAGS
-TAGS:
-
-ctags: CTAGS
-CTAGS:
-
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-am
-all-am: Makefile $(SCRIPTS)
-installdirs:
- for dir in "$(DESTDIR)$(initdbindir)"; do \
- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
- done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
- -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic mostlyclean-am
-
-distclean: distclean-am
- -rm -f Makefile
-distclean-am: clean-am distclean-generic
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-initdbinSCRIPTS
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-generic
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-initdbinSCRIPTS
-
-.MAKE: install-am install-strip
-
-.PHONY: all all-am check check-am clean clean-generic distclean \
- distclean-generic distdir dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am install-dvi \
- install-dvi-am install-exec install-exec-am install-html \
- install-html-am install-info install-info-am \
- install-initdbinSCRIPTS install-man install-pdf install-pdf-am \
- install-ps install-ps-am install-strip installcheck \
- installcheck-am installdirs maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
- pdf-am ps ps-am uninstall uninstall-am \
- uninstall-initdbinSCRIPTS
-
-include $(top_builddir)/common.mk
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
--- /dev/null
+include ../../defines.mk
+
+all:
+
+SCRIPTS = \
+ example1.pl \
+ example2.pl
+
+.PHONY: install
+install: ${SCRIPTS}
+ install -d ${DOCDIR}/examples
+ install -m 0755 ${SCRIPTS} ${DOCDIR}/examples
+
+.PHONY: distclean
+distclean: clean
+
+.PHONY: clean
+clean:
+ rm -rf *~
+++ /dev/null
-include $(top_builddir)/common.mk
-
-exampledir = ${DOCDIR}/examples
-
-example_SCRIPTS = \
- example1.pl \
- example2.pl
-
-
-CLEANFILES = *~
+++ /dev/null
-# Makefile.in generated by automake 1.11.1 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
-# Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkglibexecdir = $(libexecdir)/@PACKAGE@
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-subdir = bin/test
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/configure.in
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_CLEAN_FILES =
-CONFIG_CLEAN_VPATH_FILES =
-am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
-am__vpath_adj = case $$p in \
- $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
- *) f=$$p;; \
- esac;
-am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
-am__install_max = 40
-am__nobase_strip_setup = \
- srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
-am__nobase_strip = \
- for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
-am__nobase_list = $(am__nobase_strip_setup); \
- for p in $$list; do echo "$$p $$p"; done | \
- sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
- $(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
- if (++n[$$2] == $(am__install_max)) \
- { print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
- END { for (dir in files) print dir, files[dir] }'
-am__base_list = \
- sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
- sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
-am__installdirs = "$(DESTDIR)$(exampledir)"
-SCRIPTS = $(example_SCRIPTS)
-SOURCES =
-DIST_SOURCES =
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMTAR = @AMTAR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPPFLAGS = @CPPFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-DOCDIR = @DOCDIR@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EXEEXT = @EXEEXT@
-GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
-GMSGFMT = @GMSGFMT@
-GMSGFMT_015 = @GMSGFMT_015@
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
-LIBOBJS = @LIBOBJS@
-LIBS = @LIBS@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAKEINFO = @MAKEINFO@
-MKDIR_P = @MKDIR_P@
-MSGFMT = @MSGFMT@
-MSGFMT_015 = @MSGFMT_015@
-MSGMERGE = @MSGMERGE@
-OBJEXT = @OBJEXT@
-PACKAGE = @PACKAGE@
-PACKAGERELEASE = @PACKAGERELEASE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_URL = @PACKAGE_URL@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-PERL_LIBDIR = @PERL_LIBDIR@
-PROXMOX_ETC = @PROXMOX_ETC@
-REPOID = @REPOID@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-USE_NLS = @USE_NLS@
-VERSION = @VERSION@
-WWW_BASEDIR = @WWW_BASEDIR@
-WWW_CSSDIR = @WWW_CSSDIR@
-WWW_EXTDIR = @WWW_EXTDIR@
-WWW_IMAGEDIR = @WWW_IMAGEDIR@
-WWW_ROOTDIR = @WWW_ROOTDIR@
-XGETTEXT = @XGETTEXT@
-XGETTEXT_015 = @XGETTEXT_015@
-XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
-abs_builddir = @abs_builddir@
-abs_srcdir = @abs_srcdir@
-abs_top_builddir = @abs_top_builddir@
-abs_top_srcdir = @abs_top_srcdir@
-ac_ct_CC = @ac_ct_CC@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build_alias = @build_alias@
-builddir = @builddir@
-datadir = @datadir@
-datarootdir = @datarootdir@
-docdir = @docdir@
-dvidir = @dvidir@
-exec_prefix = @exec_prefix@
-host_alias = @host_alias@
-htmldir = @htmldir@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localedir = @localedir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-pdfdir = @pdfdir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-psdir = @psdir@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-srcdir = @srcdir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-top_build_prefix = @top_build_prefix@
-top_builddir = @top_builddir@
-top_srcdir = @top_srcdir@
-exampledir = ${DOCDIR}/examples
-example_SCRIPTS = \
- example1.pl \
- example2.pl
-
-CLEANFILES = *~
-all: all-am
-
-.SUFFIXES:
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
- && { if test -f $@; then exit 0; else break; fi; }; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign bin/test/Makefile'; \
- $(am__cd) $(top_srcdir) && \
- $(AUTOMAKE) --foreign bin/test/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(am__aclocal_m4_deps):
-install-exampleSCRIPTS: $(example_SCRIPTS)
- @$(NORMAL_INSTALL)
- test -z "$(exampledir)" || $(MKDIR_P) "$(DESTDIR)$(exampledir)"
- @list='$(example_SCRIPTS)'; test -n "$(exampledir)" || list=; \
- for p in $$list; do \
- if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
- if test -f "$$d$$p"; then echo "$$d$$p"; echo "$$p"; else :; fi; \
- done | \
- sed -e 'p;s,.*/,,;n' \
- -e 'h;s|.*|.|' \
- -e 'p;x;s,.*/,,;$(transform)' | sed 'N;N;N;s,\n, ,g' | \
- $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1; } \
- { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \
- if ($$2 == $$4) { files[d] = files[d] " " $$1; \
- if (++n[d] == $(am__install_max)) { \
- print "f", d, files[d]; n[d] = 0; files[d] = "" } } \
- else { print "f", d "/" $$4, $$1 } } \
- END { for (d in files) print "f", d, files[d] }' | \
- while read type dir files; do \
- if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \
- test -z "$$files" || { \
- echo " $(INSTALL_SCRIPT) $$files '$(DESTDIR)$(exampledir)$$dir'"; \
- $(INSTALL_SCRIPT) $$files "$(DESTDIR)$(exampledir)$$dir" || exit $$?; \
- } \
- ; done
-
-uninstall-exampleSCRIPTS:
- @$(NORMAL_UNINSTALL)
- @list='$(example_SCRIPTS)'; test -n "$(exampledir)" || exit 0; \
- files=`for p in $$list; do echo "$$p"; done | \
- sed -e 's,.*/,,;$(transform)'`; \
- test -n "$$list" || exit 0; \
- echo " ( cd '$(DESTDIR)$(exampledir)' && rm -f" $$files ")"; \
- cd "$(DESTDIR)$(exampledir)" && rm -f $$files
-tags: TAGS
-TAGS:
-
-ctags: CTAGS
-CTAGS:
-
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
- list='$(DISTFILES)'; \
- dist_files=`for file in $$list; do echo $$file; done | \
- sed -e "s|^$$srcdirstrip/||;t" \
- -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
- case $$dist_files in \
- */*) $(MKDIR_P) `echo "$$dist_files" | \
- sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
- sort -u` ;; \
- esac; \
- for file in $$dist_files; do \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- if test -d $$d/$$file; then \
- dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test -d "$(distdir)/$$file"; then \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
- find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
- fi; \
- cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
- else \
- test -f "$(distdir)/$$file" \
- || cp -p $$d/$$file "$(distdir)/$$file" \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-am
-all-am: Makefile $(SCRIPTS)
-installdirs:
- for dir in "$(DESTDIR)$(exampledir)"; do \
- test -z "$$dir" || $(MKDIR_P) "$$dir"; \
- done
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
- -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
- -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic mostlyclean-am
-
-distclean: distclean-am
- -rm -f Makefile
-distclean-am: clean-am distclean-generic
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-html-am:
-
-info: info-am
-
-info-am:
-
-install-data-am: install-exampleSCRIPTS
-
-install-dvi: install-dvi-am
-
-install-dvi-am:
-
-install-exec-am:
-
-install-html: install-html-am
-
-install-html-am:
-
-install-info: install-info-am
-
-install-info-am:
-
-install-man:
-
-install-pdf: install-pdf-am
-
-install-pdf-am:
-
-install-ps: install-ps-am
-
-install-ps-am:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-generic
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-exampleSCRIPTS
-
-.MAKE: install-am install-strip
-
-.PHONY: all all-am check check-am clean clean-generic distclean \
- distclean-generic distdir dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am install-dvi \
- install-dvi-am install-exampleSCRIPTS install-exec \
- install-exec-am install-html install-html-am install-info \
- install-info-am install-man install-pdf install-pdf-am \
- install-ps install-ps-am install-strip installcheck \
- installcheck-am installdirs maintainer-clean \
- maintainer-clean-generic mostlyclean mostlyclean-generic pdf \
- pdf-am ps ps-am uninstall uninstall-am \
- uninstall-exampleSCRIPTS
-
-include $(top_builddir)/common.mk
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
+++ /dev/null
-RELEASE=2.0
-
-man1dir = "/usr/share/man/man1"
-man7dir = "/usr/share/man/man7"
-
-
-%.1: %
- pod2man -n $* -s 1 -r "proxmox 1.0" -c "Proxmox Documentation" <$* >$*.1
+++ /dev/null
-#! /bin/sh
-# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-# Free Software Foundation, Inc.
-
-timestamp='2009-12-30'
-
-# This file is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Originally written by Per Bothner. Please send patches (context
-# diff format) to <config-patches@gnu.org> and include a ChangeLog
-# entry.
-#
-# This script attempts to guess a canonical system name similar to
-# config.sub. If it succeeds, it prints the system name on stdout, and
-# exits with 0. Otherwise, it exits with 1.
-#
-# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION]
-
-Output the configuration name of the system \`$me' is run on.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.guess ($timestamp)
-
-Originally written by Per Bothner.
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
-Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help" >&2
- exit 1 ;;
- * )
- break ;;
- esac
-done
-
-if test $# != 0; then
- echo "$me: too many arguments$help" >&2
- exit 1
-fi
-
-trap 'exit 1' 1 2 15
-
-# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
-# compiler to aid in system detection is discouraged as it requires
-# temporary files to be created and, as you can see below, it is a
-# headache to deal with in a portable fashion.
-
-# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
-# use `HOST_CC' if defined, but it is deprecated.
-
-# Portable tmp directory creation inspired by the Autoconf team.
-
-set_cc_for_build='
-trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
-trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
-: ${TMPDIR=/tmp} ;
- { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
- { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
- { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
- { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
-dummy=$tmp/dummy ;
-tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
-case $CC_FOR_BUILD,$HOST_CC,$CC in
- ,,) echo "int x;" > $dummy.c ;
- for c in cc gcc c89 c99 ; do
- if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
- CC_FOR_BUILD="$c"; break ;
- fi ;
- done ;
- if test x"$CC_FOR_BUILD" = x ; then
- CC_FOR_BUILD=no_compiler_found ;
- fi
- ;;
- ,,*) CC_FOR_BUILD=$CC ;;
- ,*,*) CC_FOR_BUILD=$HOST_CC ;;
-esac ; set_cc_for_build= ;'
-
-# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
-# (ghazi@noc.rutgers.edu 1994-08-24)
-if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
- PATH=$PATH:/.attbin ; export PATH
-fi
-
-UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
-UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
-UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
-UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
-
-# Note: order is significant - the case branches are not exclusive.
-
-case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- *:NetBSD:*:*)
- # NetBSD (nbsd) targets should (where applicable) match one or
- # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
- # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
- # switched to ELF, *-*-netbsd* would select the old
- # object file format. This provides both forward
- # compatibility and a consistent mechanism for selecting the
- # object file format.
- #
- # Note: NetBSD doesn't particularly care about the vendor
- # portion of the name. We always set it to "unknown".
- sysctl="sysctl -n hw.machine_arch"
- UNAME_MACHINE_ARCH=`(/sbin/$sysctl 2>/dev/null || \
- /usr/sbin/$sysctl 2>/dev/null || echo unknown)`
- case "${UNAME_MACHINE_ARCH}" in
- armeb) machine=armeb-unknown ;;
- arm*) machine=arm-unknown ;;
- sh3el) machine=shl-unknown ;;
- sh3eb) machine=sh-unknown ;;
- sh5el) machine=sh5le-unknown ;;
- *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
- esac
- # The Operating System including object format, if it has switched
- # to ELF recently, or will in the future.
- case "${UNAME_MACHINE_ARCH}" in
- arm*|i386|m68k|ns32k|sh3*|sparc|vax)
- eval $set_cc_for_build
- if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ELF__
- then
- # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
- # Return netbsd for either. FIX?
- os=netbsd
- else
- os=netbsdelf
- fi
- ;;
- *)
- os=netbsd
- ;;
- esac
- # The OS release
- # Debian GNU/NetBSD machines have a different userland, and
- # thus, need a distinct triplet. However, they do not need
- # kernel version information, so it can be replaced with a
- # suitable tag, in the style of linux-gnu.
- case "${UNAME_VERSION}" in
- Debian*)
- release='-gnu'
- ;;
- *)
- release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
- ;;
- esac
- # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
- # contains redundant information, the shorter form:
- # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
- echo "${machine}-${os}${release}"
- exit ;;
- *:OpenBSD:*:*)
- UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
- echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
- exit ;;
- *:ekkoBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
- exit ;;
- *:SolidBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
- exit ;;
- macppc:MirBSD:*:*)
- echo powerpc-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- *:MirBSD:*:*)
- echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
- exit ;;
- alpha:OSF1:*:*)
- case $UNAME_RELEASE in
- *4.0)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
- ;;
- *5.*)
- UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
- ;;
- esac
- # According to Compaq, /usr/sbin/psrinfo has been available on
- # OSF/1 and Tru64 systems produced since 1995. I hope that
- # covers most systems running today. This code pipes the CPU
- # types through head -n 1, so we only detect the type of CPU 0.
- ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
- case "$ALPHA_CPU_TYPE" in
- "EV4 (21064)")
- UNAME_MACHINE="alpha" ;;
- "EV4.5 (21064)")
- UNAME_MACHINE="alpha" ;;
- "LCA4 (21066/21068)")
- UNAME_MACHINE="alpha" ;;
- "EV5 (21164)")
- UNAME_MACHINE="alphaev5" ;;
- "EV5.6 (21164A)")
- UNAME_MACHINE="alphaev56" ;;
- "EV5.6 (21164PC)")
- UNAME_MACHINE="alphapca56" ;;
- "EV5.7 (21164PC)")
- UNAME_MACHINE="alphapca57" ;;
- "EV6 (21264)")
- UNAME_MACHINE="alphaev6" ;;
- "EV6.7 (21264A)")
- UNAME_MACHINE="alphaev67" ;;
- "EV6.8CB (21264C)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8AL (21264B)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.8CX (21264D)")
- UNAME_MACHINE="alphaev68" ;;
- "EV6.9A (21264/EV69A)")
- UNAME_MACHINE="alphaev69" ;;
- "EV7 (21364)")
- UNAME_MACHINE="alphaev7" ;;
- "EV7.9 (21364A)")
- UNAME_MACHINE="alphaev79" ;;
- esac
- # A Pn.n version is a patched version.
- # A Vn.n version is a released version.
- # A Tn.n version is a released field test version.
- # A Xn.n version is an unreleased experimental baselevel.
- # 1.2 uses "1.2" for uname -r.
- echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- exit ;;
- Alpha\ *:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # Should we change UNAME_MACHINE based on the output of uname instead
- # of the specific Alpha model?
- echo alpha-pc-interix
- exit ;;
- 21064:Windows_NT:50:3)
- echo alpha-dec-winnt3.5
- exit ;;
- Amiga*:UNIX_System_V:4.0:*)
- echo m68k-unknown-sysv4
- exit ;;
- *:[Aa]miga[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-amigaos
- exit ;;
- *:[Mm]orph[Oo][Ss]:*:*)
- echo ${UNAME_MACHINE}-unknown-morphos
- exit ;;
- *:OS/390:*:*)
- echo i370-ibm-openedition
- exit ;;
- *:z/VM:*:*)
- echo s390-ibm-zvmoe
- exit ;;
- *:OS400:*:*)
- echo powerpc-ibm-os400
- exit ;;
- arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
- echo arm-acorn-riscix${UNAME_RELEASE}
- exit ;;
- arm:riscos:*:*|arm:RISCOS:*:*)
- echo arm-unknown-riscos
- exit ;;
- SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
- echo hppa1.1-hitachi-hiuxmpp
- exit ;;
- Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
- # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
- if test "`(/bin/universe) 2>/dev/null`" = att ; then
- echo pyramid-pyramid-sysv3
- else
- echo pyramid-pyramid-bsd
- fi
- exit ;;
- NILE*:*:*:dcosx)
- echo pyramid-pyramid-svr4
- exit ;;
- DRS?6000:unix:4.0:6*)
- echo sparc-icl-nx6
- exit ;;
- DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
- case `/usr/bin/uname -p` in
- sparc) echo sparc-icl-nx7; exit ;;
- esac ;;
- s390x:SunOS:*:*)
- echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4H:SunOS:5.*:*)
- echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
- echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
- echo i386-pc-auroraux${UNAME_RELEASE}
- exit ;;
- i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
- eval $set_cc_for_build
- SUN_ARCH="i386"
- # If there is a compiler, see if it is configured for 64-bit objects.
- # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
- # This test works for both compilers.
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- SUN_ARCH="x86_64"
- fi
- fi
- echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:6*:*)
- # According to config.sub, this is the proper way to canonicalize
- # SunOS6. Hard to guess exactly what SunOS6 will be like, but
- # it's likely to be more like Solaris than SunOS4.
- echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- sun4*:SunOS:*:*)
- case "`/usr/bin/arch -k`" in
- Series*|S4*)
- UNAME_RELEASE=`uname -v`
- ;;
- esac
- # Japanese Language versions have a version number like `4.1.3-JL'.
- echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
- exit ;;
- sun3*:SunOS:*:*)
- echo m68k-sun-sunos${UNAME_RELEASE}
- exit ;;
- sun*:*:4.2BSD:*)
- UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
- test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
- case "`/bin/arch`" in
- sun3)
- echo m68k-sun-sunos${UNAME_RELEASE}
- ;;
- sun4)
- echo sparc-sun-sunos${UNAME_RELEASE}
- ;;
- esac
- exit ;;
- aushp:SunOS:*:*)
- echo sparc-auspex-sunos${UNAME_RELEASE}
- exit ;;
- # The situation for MiNT is a little confusing. The machine name
- # can be virtually everything (everything which is not
- # "atarist" or "atariste" at least should have a processor
- # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
- # to the lowercase version "mint" (or "freemint"). Finally
- # the system name "TOS" denotes a system which is actually not
- # MiNT. But MiNT is downward compatible to TOS, so this should
- # be no problem.
- atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
- echo m68k-atari-mint${UNAME_RELEASE}
- exit ;;
- milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
- echo m68k-milan-mint${UNAME_RELEASE}
- exit ;;
- hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
- echo m68k-hades-mint${UNAME_RELEASE}
- exit ;;
- *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
- echo m68k-unknown-mint${UNAME_RELEASE}
- exit ;;
- m68k:machten:*:*)
- echo m68k-apple-machten${UNAME_RELEASE}
- exit ;;
- powerpc:machten:*:*)
- echo powerpc-apple-machten${UNAME_RELEASE}
- exit ;;
- RISC*:Mach:*:*)
- echo mips-dec-mach_bsd4.3
- exit ;;
- RISC*:ULTRIX:*:*)
- echo mips-dec-ultrix${UNAME_RELEASE}
- exit ;;
- VAX*:ULTRIX*:*:*)
- echo vax-dec-ultrix${UNAME_RELEASE}
- exit ;;
- 2020:CLIX:*:* | 2430:CLIX:*:*)
- echo clipper-intergraph-clix${UNAME_RELEASE}
- exit ;;
- mips:*:*:UMIPS | mips:*:*:RISCos)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-#ifdef __cplusplus
-#include <stdio.h> /* for printf() prototype */
- int main (int argc, char *argv[]) {
-#else
- int main (argc, argv) int argc; char *argv[]; {
-#endif
- #if defined (host_mips) && defined (MIPSEB)
- #if defined (SYSTYPE_SYSV)
- printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_SVR4)
- printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
- #endif
- #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
- printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
- #endif
- #endif
- exit (-1);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c &&
- dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
- SYSTEM_NAME=`$dummy $dummyarg` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo mips-mips-riscos${UNAME_RELEASE}
- exit ;;
- Motorola:PowerMAX_OS:*:*)
- echo powerpc-motorola-powermax
- exit ;;
- Motorola:*:4.3:PL8-*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
- echo powerpc-harris-powermax
- exit ;;
- Night_Hawk:Power_UNIX:*:*)
- echo powerpc-harris-powerunix
- exit ;;
- m88k:CX/UX:7*:*)
- echo m88k-harris-cxux7
- exit ;;
- m88k:*:4*:R4*)
- echo m88k-motorola-sysv4
- exit ;;
- m88k:*:3*:R3*)
- echo m88k-motorola-sysv3
- exit ;;
- AViiON:dgux:*:*)
- # DG/UX returns AViiON for all architectures
- UNAME_PROCESSOR=`/usr/bin/uname -p`
- if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
- then
- if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
- [ ${TARGET_BINARY_INTERFACE}x = x ]
- then
- echo m88k-dg-dgux${UNAME_RELEASE}
- else
- echo m88k-dg-dguxbcs${UNAME_RELEASE}
- fi
- else
- echo i586-dg-dgux${UNAME_RELEASE}
- fi
- exit ;;
- M88*:DolphinOS:*:*) # DolphinOS (SVR3)
- echo m88k-dolphin-sysv3
- exit ;;
- M88*:*:R3*:*)
- # Delta 88k system running SVR3
- echo m88k-motorola-sysv3
- exit ;;
- XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
- echo m88k-tektronix-sysv3
- exit ;;
- Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
- echo m68k-tektronix-bsd
- exit ;;
- *:IRIX*:*:*)
- echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
- exit ;;
- ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
- echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
- exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
- i*86:AIX:*:*)
- echo i386-ibm-aix
- exit ;;
- ia64:AIX:*:*)
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:2:3)
- if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <sys/systemcfg.h>
-
- main()
- {
- if (!__power_pc())
- exit(1);
- puts("powerpc-ibm-aix3.2.5");
- exit(0);
- }
-EOF
- if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
- then
- echo "$SYSTEM_NAME"
- else
- echo rs6000-ibm-aix3.2.5
- fi
- elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
- echo rs6000-ibm-aix3.2.4
- else
- echo rs6000-ibm-aix3.2
- fi
- exit ;;
- *:AIX:*:[456])
- IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
- if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
- IBM_ARCH=rs6000
- else
- IBM_ARCH=powerpc
- fi
- if [ -x /usr/bin/oslevel ] ; then
- IBM_REV=`/usr/bin/oslevel`
- else
- IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
- fi
- echo ${IBM_ARCH}-ibm-aix${IBM_REV}
- exit ;;
- *:AIX:*:*)
- echo rs6000-ibm-aix
- exit ;;
- ibmrt:4.4BSD:*|romp-ibm:BSD:*)
- echo romp-ibm-bsd4.4
- exit ;;
- ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
- exit ;; # report: romp-ibm BSD 4.3
- *:BOSX:*:*)
- echo rs6000-bull-bosx
- exit ;;
- DPX/2?00:B.O.S.:*:*)
- echo m68k-bull-sysv3
- exit ;;
- 9000/[34]??:4.3bsd:1.*:*)
- echo m68k-hp-bsd
- exit ;;
- hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
- echo m68k-hp-bsd4.4
- exit ;;
- 9000/[34678]??:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- case "${UNAME_MACHINE}" in
- 9000/31? ) HP_ARCH=m68000 ;;
- 9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/[678][0-9][0-9])
- if [ -x /usr/bin/getconf ]; then
- sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
- sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
- case "${sc_cpu_version}" in
- 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
- 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
- 532) # CPU_PA_RISC2_0
- case "${sc_kernel_bits}" in
- 32) HP_ARCH="hppa2.0n" ;;
- 64) HP_ARCH="hppa2.0w" ;;
- '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
- esac ;;
- esac
- fi
- if [ "${HP_ARCH}" = "" ]; then
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
-
- #define _HPUX_SOURCE
- #include <stdlib.h>
- #include <unistd.h>
-
- int main ()
- {
- #if defined(_SC_KERNEL_BITS)
- long bits = sysconf(_SC_KERNEL_BITS);
- #endif
- long cpu = sysconf (_SC_CPU_VERSION);
-
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
- case CPU_PA_RISC2_0:
- #if defined(_SC_KERNEL_BITS)
- switch (bits)
- {
- case 64: puts ("hppa2.0w"); break;
- case 32: puts ("hppa2.0n"); break;
- default: puts ("hppa2.0"); break;
- } break;
- #else /* !defined(_SC_KERNEL_BITS) */
- puts ("hppa2.0"); break;
- #endif
- default: puts ("hppa1.0"); break;
- }
- exit (0);
- }
-EOF
- (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
- test -z "$HP_ARCH" && HP_ARCH=hppa
- fi ;;
- esac
- if [ ${HP_ARCH} = "hppa2.0w" ]
- then
- eval $set_cc_for_build
-
- # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
- # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
- # generating 64-bit code. GNU and HP use different nomenclature:
- #
- # $ CC_FOR_BUILD=cc ./config.guess
- # => hppa2.0w-hp-hpux11.23
- # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
- # => hppa64-hp-hpux11.23
-
- if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
- grep -q __LP64__
- then
- HP_ARCH="hppa2.0w"
- else
- HP_ARCH="hppa64"
- fi
- fi
- echo ${HP_ARCH}-hp-hpux${HPUX_REV}
- exit ;;
- ia64:HP-UX:*:*)
- HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
- echo ia64-hp-hpux${HPUX_REV}
- exit ;;
- 3050*:HI-UX:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #include <unistd.h>
- int
- main ()
- {
- long cpu = sysconf (_SC_CPU_VERSION);
- /* The order matters, because CPU_IS_HP_MC68K erroneously returns
- true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
- results, however. */
- if (CPU_IS_PA_RISC (cpu))
- {
- switch (cpu)
- {
- case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
- case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
- default: puts ("hppa-hitachi-hiuxwe2"); break;
- }
- }
- else if (CPU_IS_HP_MC68K (cpu))
- puts ("m68k-hitachi-hiuxwe2");
- else puts ("unknown-hitachi-hiuxwe2");
- exit (0);
- }
-EOF
- $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
- echo unknown-hitachi-hiuxwe2
- exit ;;
- 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
- echo hppa1.1-hp-bsd
- exit ;;
- 9000/8??:4.3bsd:*:*)
- echo hppa1.0-hp-bsd
- exit ;;
- *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
- echo hppa1.0-hp-mpeix
- exit ;;
- hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
- echo hppa1.1-hp-osf
- exit ;;
- hp8??:OSF1:*:*)
- echo hppa1.0-hp-osf
- exit ;;
- i*86:OSF1:*:*)
- if [ -x /usr/sbin/sysversion ] ; then
- echo ${UNAME_MACHINE}-unknown-osf1mk
- else
- echo ${UNAME_MACHINE}-unknown-osf1
- fi
- exit ;;
- parisc*:Lites*:*:*)
- echo hppa1.1-hp-lites
- exit ;;
- C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
- echo c1-convex-bsd
- exit ;;
- C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
- echo c34-convex-bsd
- exit ;;
- C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
- echo c38-convex-bsd
- exit ;;
- C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
- echo c4-convex-bsd
- exit ;;
- CRAY*Y-MP:*:*:*)
- echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*[A-Z]90:*:*:*)
- echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
- | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
- -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
- -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*TS:*:*:*)
- echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*T3E:*:*:*)
- echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- CRAY*SV1:*:*:*)
- echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- *:UNICOS/mp:*:*)
- echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
- exit ;;
- F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
- FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
- echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- 5000:UNIX_System_V:4.*:*)
- FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
- FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
- echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
- exit ;;
- i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
- echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
- exit ;;
- sparc*:BSD/OS:*:*)
- echo sparc-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
- exit ;;
- *:FreeBSD:*:*)
- case ${UNAME_MACHINE} in
- pc98)
- echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- amd64)
- echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- *)
- echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
- esac
- exit ;;
- i*:CYGWIN*:*)
- echo ${UNAME_MACHINE}-pc-cygwin
- exit ;;
- *:MINGW*:*)
- echo ${UNAME_MACHINE}-pc-mingw32
- exit ;;
- i*:windows32*:*)
- # uname -m includes "-pc" on this system.
- echo ${UNAME_MACHINE}-mingw32
- exit ;;
- i*:PW*:*)
- echo ${UNAME_MACHINE}-pc-pw32
- exit ;;
- *:Interix*:*)
- case ${UNAME_MACHINE} in
- x86)
- echo i586-pc-interix${UNAME_RELEASE}
- exit ;;
- authenticamd | genuineintel | EM64T)
- echo x86_64-unknown-interix${UNAME_RELEASE}
- exit ;;
- IA64)
- echo ia64-unknown-interix${UNAME_RELEASE}
- exit ;;
- esac ;;
- [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
- echo i${UNAME_MACHINE}-pc-mks
- exit ;;
- 8664:Windows_NT:*)
- echo x86_64-pc-mks
- exit ;;
- i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
- # How do we know it's Interix rather than the generic POSIX subsystem?
- # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
- # UNAME_MACHINE based on the output of uname instead of i386?
- echo i586-pc-interix
- exit ;;
- i*:UWIN*:*)
- echo ${UNAME_MACHINE}-pc-uwin
- exit ;;
- amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
- echo x86_64-unknown-cygwin
- exit ;;
- p*:CYGWIN*:*)
- echo powerpcle-unknown-cygwin
- exit ;;
- prep*:SunOS:5.*:*)
- echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
- exit ;;
- *:GNU:*:*)
- # the GNU system
- echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
- exit ;;
- *:GNU/*:*:*)
- # other systems with GNU libc and userland
- echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
- exit ;;
- i*86:Minix:*:*)
- echo ${UNAME_MACHINE}-pc-minix
- exit ;;
- alpha:Linux:*:*)
- case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
- EV5) UNAME_MACHINE=alphaev5 ;;
- EV56) UNAME_MACHINE=alphaev56 ;;
- PCA56) UNAME_MACHINE=alphapca56 ;;
- PCA57) UNAME_MACHINE=alphapca56 ;;
- EV6) UNAME_MACHINE=alphaev6 ;;
- EV67) UNAME_MACHINE=alphaev67 ;;
- EV68*) UNAME_MACHINE=alphaev68 ;;
- esac
- objdump --private-headers /bin/sh | grep -q ld.so.1
- if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
- echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
- exit ;;
- arm*:Linux:*:*)
- eval $set_cc_for_build
- if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
- | grep -q __ARM_EABI__
- then
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- else
- echo ${UNAME_MACHINE}-unknown-linux-gnueabi
- fi
- exit ;;
- avr32*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- cris:Linux:*:*)
- echo cris-axis-linux-gnu
- exit ;;
- crisv32:Linux:*:*)
- echo crisv32-axis-linux-gnu
- exit ;;
- frv:Linux:*:*)
- echo frv-unknown-linux-gnu
- exit ;;
- i*86:Linux:*:*)
- LIBC=gnu
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #ifdef __dietlibc__
- LIBC=dietlibc
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
- echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
- exit ;;
- ia64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m32r*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- m68*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- mips:Linux:*:* | mips64:Linux:*:*)
- eval $set_cc_for_build
- sed 's/^ //' << EOF >$dummy.c
- #undef CPU
- #undef ${UNAME_MACHINE}
- #undef ${UNAME_MACHINE}el
- #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
- CPU=${UNAME_MACHINE}el
- #else
- #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
- CPU=${UNAME_MACHINE}
- #else
- CPU=
- #endif
- #endif
-EOF
- eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
- test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
- ;;
- or32:Linux:*:*)
- echo or32-unknown-linux-gnu
- exit ;;
- padre:Linux:*:*)
- echo sparc-unknown-linux-gnu
- exit ;;
- parisc64:Linux:*:* | hppa64:Linux:*:*)
- echo hppa64-unknown-linux-gnu
- exit ;;
- parisc:Linux:*:* | hppa:Linux:*:*)
- # Look for CPU level
- case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
- PA7*) echo hppa1.1-unknown-linux-gnu ;;
- PA8*) echo hppa2.0-unknown-linux-gnu ;;
- *) echo hppa-unknown-linux-gnu ;;
- esac
- exit ;;
- ppc64:Linux:*:*)
- echo powerpc64-unknown-linux-gnu
- exit ;;
- ppc:Linux:*:*)
- echo powerpc-unknown-linux-gnu
- exit ;;
- s390:Linux:*:* | s390x:Linux:*:*)
- echo ${UNAME_MACHINE}-ibm-linux
- exit ;;
- sh64*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sh*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- sparc:Linux:*:* | sparc64:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- vax:Linux:*:*)
- echo ${UNAME_MACHINE}-dec-linux-gnu
- exit ;;
- x86_64:Linux:*:*)
- echo x86_64-unknown-linux-gnu
- exit ;;
- xtensa*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux-gnu
- exit ;;
- i*86:DYNIX/ptx:4*:*)
- # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
- # earlier versions are messed up and put the nodename in both
- # sysname and nodename.
- echo i386-sequent-sysv4
- exit ;;
- i*86:UNIX_SV:4.2MP:2.*)
- # Unixware is an offshoot of SVR4, but it has its own version
- # number series starting with 2...
- # I am not positive that other SVR4 systems won't match this,
- # I just have to hope. -- rms.
- # Use sysv4.2uw... so that sysv4* matches it.
- echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
- exit ;;
- i*86:OS/2:*:*)
- # If we were able to find `uname', then EMX Unix compatibility
- # is probably installed.
- echo ${UNAME_MACHINE}-pc-os2-emx
- exit ;;
- i*86:XTS-300:*:STOP)
- echo ${UNAME_MACHINE}-unknown-stop
- exit ;;
- i*86:atheos:*:*)
- echo ${UNAME_MACHINE}-unknown-atheos
- exit ;;
- i*86:syllable:*:*)
- echo ${UNAME_MACHINE}-pc-syllable
- exit ;;
- i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
- echo i386-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- i*86:*DOS:*:*)
- echo ${UNAME_MACHINE}-pc-msdosdjgpp
- exit ;;
- i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
- UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
- if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
- echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
- else
- echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
- fi
- exit ;;
- i*86:*:5:[678]*)
- # UnixWare 7.x, OpenUNIX and OpenServer 6.
- case `/bin/uname -X | grep "^Machine"` in
- *486*) UNAME_MACHINE=i486 ;;
- *Pentium) UNAME_MACHINE=i586 ;;
- *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
- esac
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
- exit ;;
- i*86:*:3.2:*)
- if test -f /usr/options/cb.name; then
- UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
- elif /bin/uname -X 2>/dev/null >/dev/null ; then
- UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
- (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
- (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
- && UNAME_MACHINE=i586
- (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
- && UNAME_MACHINE=i686
- (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
- && UNAME_MACHINE=i686
- echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
- else
- echo ${UNAME_MACHINE}-pc-sysv32
- fi
- exit ;;
- pc:*:*:*)
- # Left here for compatibility:
- # uname -m prints for DJGPP always 'pc', but it prints nothing about
- # the processor, so we play safe by assuming i586.
- # Note: whatever this is, it MUST be the same as what config.sub
- # prints for the "djgpp" host, or else GDB configury will decide that
- # this is a cross-build.
- echo i586-pc-msdosdjgpp
- exit ;;
- Intel:Mach:3*:*)
- echo i386-pc-mach3
- exit ;;
- paragon:*:*:*)
- echo i860-intel-osf1
- exit ;;
- i860:*:4.*:*) # i860-SVR4
- if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
- echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
- else # Add other i860-SVR4 vendors below as they are discovered.
- echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
- fi
- exit ;;
- mini*:CTIX:SYS*5:*)
- # "miniframe"
- echo m68010-convergent-sysv
- exit ;;
- mc68k:UNIX:SYSTEM5:3.51m)
- echo m68k-convergent-sysv
- exit ;;
- M680?0:D-NIX:5.3:*)
- echo m68k-diab-dnix
- exit ;;
- M68*:*:R3V[5678]*:*)
- test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
- 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
- OS_REL=''
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
- 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4; exit; } ;;
- NCR*:*:4.2:* | MPRAS*:*:4.2:*)
- OS_REL='.3'
- test -r /etc/.relid \
- && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
- /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
- && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
- /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
- && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
- m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
- echo m68k-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- mc68030:UNIX_System_V:4.*:*)
- echo m68k-atari-sysv4
- exit ;;
- TSUNAMI:LynxOS:2.*:*)
- echo sparc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- rs6000:LynxOS:2.*:*)
- echo rs6000-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
- echo powerpc-unknown-lynxos${UNAME_RELEASE}
- exit ;;
- SM[BE]S:UNIX_SV:*:*)
- echo mips-dde-sysv${UNAME_RELEASE}
- exit ;;
- RM*:ReliantUNIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- RM*:SINIX-*:*:*)
- echo mips-sni-sysv4
- exit ;;
- *:SINIX-*:*:*)
- if uname -p 2>/dev/null >/dev/null ; then
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- echo ${UNAME_MACHINE}-sni-sysv4
- else
- echo ns32k-sni-sysv
- fi
- exit ;;
- PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
- # says <Richard.M.Bartel@ccMail.Census.GOV>
- echo i586-unisys-sysv4
- exit ;;
- *:UNIX_System_V:4*:FTX*)
- # From Gerald Hewes <hewes@openmarket.com>.
- # How about differentiating between stratus architectures? -djm
- echo hppa1.1-stratus-sysv4
- exit ;;
- *:*:*:FTX*)
- # From seanf@swdc.stratus.com.
- echo i860-stratus-sysv4
- exit ;;
- i*86:VOS:*:*)
- # From Paul.Green@stratus.com.
- echo ${UNAME_MACHINE}-stratus-vos
- exit ;;
- *:VOS:*:*)
- # From Paul.Green@stratus.com.
- echo hppa1.1-stratus-vos
- exit ;;
- mc68*:A/UX:*:*)
- echo m68k-apple-aux${UNAME_RELEASE}
- exit ;;
- news*:NEWS-OS:6*:*)
- echo mips-sony-newsos6
- exit ;;
- R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
- if [ -d /usr/nec ]; then
- echo mips-nec-sysv${UNAME_RELEASE}
- else
- echo mips-unknown-sysv${UNAME_RELEASE}
- fi
- exit ;;
- BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
- echo powerpc-be-beos
- exit ;;
- BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
- echo powerpc-apple-beos
- exit ;;
- BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
- echo i586-pc-beos
- exit ;;
- BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
- echo i586-pc-haiku
- exit ;;
- SX-4:SUPER-UX:*:*)
- echo sx4-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-5:SUPER-UX:*:*)
- echo sx5-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-6:SUPER-UX:*:*)
- echo sx6-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-7:SUPER-UX:*:*)
- echo sx7-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-8:SUPER-UX:*:*)
- echo sx8-nec-superux${UNAME_RELEASE}
- exit ;;
- SX-8R:SUPER-UX:*:*)
- echo sx8r-nec-superux${UNAME_RELEASE}
- exit ;;
- Power*:Rhapsody:*:*)
- echo powerpc-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Rhapsody:*:*)
- echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
- exit ;;
- *:Darwin:*:*)
- UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
- case $UNAME_PROCESSOR in
- i386)
- eval $set_cc_for_build
- if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
- if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
- (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
- grep IS_64BIT_ARCH >/dev/null
- then
- UNAME_PROCESSOR="x86_64"
- fi
- fi ;;
- unknown) UNAME_PROCESSOR=powerpc ;;
- esac
- echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
- exit ;;
- *:procnto*:*:* | *:QNX:[0123456789]*:*)
- UNAME_PROCESSOR=`uname -p`
- if test "$UNAME_PROCESSOR" = "x86"; then
- UNAME_PROCESSOR=i386
- UNAME_MACHINE=pc
- fi
- echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
- exit ;;
- *:QNX:*:4*)
- echo i386-pc-qnx
- exit ;;
- NSE-?:NONSTOP_KERNEL:*:*)
- echo nse-tandem-nsk${UNAME_RELEASE}
- exit ;;
- NSR-?:NONSTOP_KERNEL:*:*)
- echo nsr-tandem-nsk${UNAME_RELEASE}
- exit ;;
- *:NonStop-UX:*:*)
- echo mips-compaq-nonstopux
- exit ;;
- BS2000:POSIX*:*:*)
- echo bs2000-siemens-sysv
- exit ;;
- DS/*:UNIX_System_V:*:*)
- echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
- exit ;;
- *:Plan9:*:*)
- # "uname -m" is not consistent, so use $cputype instead. 386
- # is converted to i386 for consistency with other x86
- # operating systems.
- if test "$cputype" = "386"; then
- UNAME_MACHINE=i386
- else
- UNAME_MACHINE="$cputype"
- fi
- echo ${UNAME_MACHINE}-unknown-plan9
- exit ;;
- *:TOPS-10:*:*)
- echo pdp10-unknown-tops10
- exit ;;
- *:TENEX:*:*)
- echo pdp10-unknown-tenex
- exit ;;
- KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
- echo pdp10-dec-tops20
- exit ;;
- XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
- echo pdp10-xkl-tops20
- exit ;;
- *:TOPS-20:*:*)
- echo pdp10-unknown-tops20
- exit ;;
- *:ITS:*:*)
- echo pdp10-unknown-its
- exit ;;
- SEI:*:*:SEIUX)
- echo mips-sei-seiux${UNAME_RELEASE}
- exit ;;
- *:DragonFly:*:*)
- echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
- exit ;;
- *:*VMS:*:*)
- UNAME_MACHINE=`(uname -p) 2>/dev/null`
- case "${UNAME_MACHINE}" in
- A*) echo alpha-dec-vms ; exit ;;
- I*) echo ia64-dec-vms ; exit ;;
- V*) echo vax-dec-vms ; exit ;;
- esac ;;
- *:XENIX:*:SysV)
- echo i386-pc-xenix
- exit ;;
- i*86:skyos:*:*)
- echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
- exit ;;
- i*86:rdos:*:*)
- echo ${UNAME_MACHINE}-pc-rdos
- exit ;;
- i*86:AROS:*:*)
- echo ${UNAME_MACHINE}-pc-aros
- exit ;;
-esac
-
-#echo '(No uname command or uname output not recognized.)' 1>&2
-#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
-
-eval $set_cc_for_build
-cat >$dummy.c <<EOF
-#ifdef _SEQUENT_
-# include <sys/types.h>
-# include <sys/utsname.h>
-#endif
-main ()
-{
-#if defined (sony)
-#if defined (MIPSEB)
- /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed,
- I don't know.... */
- printf ("mips-sony-bsd\n"); exit (0);
-#else
-#include <sys/param.h>
- printf ("m68k-sony-newsos%s\n",
-#ifdef NEWSOS4
- "4"
-#else
- ""
-#endif
- ); exit (0);
-#endif
-#endif
-
-#if defined (__arm) && defined (__acorn) && defined (__unix)
- printf ("arm-acorn-riscix\n"); exit (0);
-#endif
-
-#if defined (hp300) && !defined (hpux)
- printf ("m68k-hp-bsd\n"); exit (0);
-#endif
-
-#if defined (NeXT)
-#if !defined (__ARCHITECTURE__)
-#define __ARCHITECTURE__ "m68k"
-#endif
- int version;
- version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
- if (version < 4)
- printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
- else
- printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
- exit (0);
-#endif
-
-#if defined (MULTIMAX) || defined (n16)
-#if defined (UMAXV)
- printf ("ns32k-encore-sysv\n"); exit (0);
-#else
-#if defined (CMU)
- printf ("ns32k-encore-mach\n"); exit (0);
-#else
- printf ("ns32k-encore-bsd\n"); exit (0);
-#endif
-#endif
-#endif
-
-#if defined (__386BSD__)
- printf ("i386-pc-bsd\n"); exit (0);
-#endif
-
-#if defined (sequent)
-#if defined (i386)
- printf ("i386-sequent-dynix\n"); exit (0);
-#endif
-#if defined (ns32000)
- printf ("ns32k-sequent-dynix\n"); exit (0);
-#endif
-#endif
-
-#if defined (_SEQUENT_)
- struct utsname un;
-
- uname(&un);
-
- if (strncmp(un.version, "V2", 2) == 0) {
- printf ("i386-sequent-ptx2\n"); exit (0);
- }
- if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
- printf ("i386-sequent-ptx1\n"); exit (0);
- }
- printf ("i386-sequent-ptx\n"); exit (0);
-
-#endif
-
-#if defined (vax)
-# if !defined (ultrix)
-# include <sys/param.h>
-# if defined (BSD)
-# if BSD == 43
- printf ("vax-dec-bsd4.3\n"); exit (0);
-# else
-# if BSD == 199006
- printf ("vax-dec-bsd4.3reno\n"); exit (0);
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# endif
-# else
- printf ("vax-dec-bsd\n"); exit (0);
-# endif
-# else
- printf ("vax-dec-ultrix\n"); exit (0);
-# endif
-#endif
-
-#if defined (alliant) && defined (i860)
- printf ("i860-alliant-bsd\n"); exit (0);
-#endif
-
- exit (1);
-}
-EOF
-
-$CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null && SYSTEM_NAME=`$dummy` &&
- { echo "$SYSTEM_NAME"; exit; }
-
-# Apollos put the system type in the environment.
-
-test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit; }
-
-# Convex versions that predate uname can use getsysinfo(1)
-
-if [ -x /usr/convex/getsysinfo ]
-then
- case `getsysinfo -f cpu_type` in
- c1*)
- echo c1-convex-bsd
- exit ;;
- c2*)
- if getsysinfo -f scalar_acc
- then echo c32-convex-bsd
- else echo c2-convex-bsd
- fi
- exit ;;
- c34*)
- echo c34-convex-bsd
- exit ;;
- c38*)
- echo c38-convex-bsd
- exit ;;
- c4*)
- echo c4-convex-bsd
- exit ;;
- esac
-fi
-
-cat >&2 <<EOF
-$0: unable to guess system type
-
-This script, last modified $timestamp, has failed to recognize
-the operating system you are using. It is advised that you
-download the most up to date version of the config scripts from
-
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
-and
- http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
-
-If the version you run ($0) is already up to date, please
-send the following data and any information you think might be
-pertinent to <config-patches@gnu.org> in order to provide the needed
-information to handle your system.
-
-config.guess timestamp = $timestamp
-
-uname -m = `(uname -m) 2>/dev/null || echo unknown`
-uname -r = `(uname -r) 2>/dev/null || echo unknown`
-uname -s = `(uname -s) 2>/dev/null || echo unknown`
-uname -v = `(uname -v) 2>/dev/null || echo unknown`
-
-/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
-/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
-
-hostinfo = `(hostinfo) 2>/dev/null`
-/bin/universe = `(/bin/universe) 2>/dev/null`
-/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
-/bin/arch = `(/bin/arch) 2>/dev/null`
-/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
-/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
-
-UNAME_MACHINE = ${UNAME_MACHINE}
-UNAME_RELEASE = ${UNAME_RELEASE}
-UNAME_SYSTEM = ${UNAME_SYSTEM}
-UNAME_VERSION = ${UNAME_VERSION}
-EOF
-
-exit 1
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
+++ /dev/null
-#! /bin/sh
-# Configuration validation subroutine script.
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
-# Free Software Foundation, Inc.
-
-timestamp='2010-01-22'
-
-# This file is (in principle) common to ALL GNU software.
-# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
-#
-# This file is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
-# 02110-1301, USA.
-#
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-
-# Please send patches to <config-patches@gnu.org>. Submit a context
-# diff and a properly formatted GNU ChangeLog entry.
-#
-# Configuration subroutine to validate and canonicalize a configuration type.
-# Supply the specified configuration type as an argument.
-# If it is invalid, we print an error message on stderr and exit with code 1.
-# Otherwise, we print the canonical config type on stdout and succeed.
-
-# You can get the latest version of this script from:
-# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
-
-# This file is supposed to be the same for all GNU packages
-# and recognize all the CPU types, system types and aliases
-# that are meaningful with *any* GNU software.
-# Each package is responsible for reporting which valid configurations
-# it does not support. The user should be able to distinguish
-# a failure to support a valid configuration from a meaningless
-# configuration.
-
-# The goal of this file is to map all the various variations of a given
-# machine specification into a single specification in the form:
-# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
-# or in some cases, the newer four-part form:
-# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
-# It is wrong to echo any other type of specification.
-
-me=`echo "$0" | sed -e 's,.*/,,'`
-
-usage="\
-Usage: $0 [OPTION] CPU-MFR-OPSYS
- $0 [OPTION] ALIAS
-
-Canonicalize a configuration name.
-
-Operation modes:
- -h, --help print this help, then exit
- -t, --time-stamp print date of last modification, then exit
- -v, --version print version number, then exit
-
-Report bugs and patches to <config-patches@gnu.org>."
-
-version="\
-GNU config.sub ($timestamp)
-
-Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free
-Software Foundation, Inc.
-
-This is free software; see the source for copying conditions. There is NO
-warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
-
-help="
-Try \`$me --help' for more information."
-
-# Parse command line
-while test $# -gt 0 ; do
- case $1 in
- --time-stamp | --time* | -t )
- echo "$timestamp" ; exit ;;
- --version | -v )
- echo "$version" ; exit ;;
- --help | --h* | -h )
- echo "$usage"; exit ;;
- -- ) # Stop option processing
- shift; break ;;
- - ) # Use stdin as input.
- break ;;
- -* )
- echo "$me: invalid option $1$help"
- exit 1 ;;
-
- *local*)
- # First pass through any local machine types.
- echo $1
- exit ;;
-
- * )
- break ;;
- esac
-done
-
-case $# in
- 0) echo "$me: missing argument$help" >&2
- exit 1;;
- 1) ;;
- *) echo "$me: too many arguments$help" >&2
- exit 1;;
-esac
-
-# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
-# Here we must recognize all the valid KERNEL-OS combinations.
-maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
-case $maybe_os in
- nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
- uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
- kopensolaris*-gnu* | \
- storm-chaos* | os2-emx* | rtmk-nova*)
- os=-$maybe_os
- basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
- ;;
- *)
- basic_machine=`echo $1 | sed 's/-[^-]*$//'`
- if [ $basic_machine != $1 ]
- then os=`echo $1 | sed 's/.*-/-/'`
- else os=; fi
- ;;
-esac
-
-### Let's recognize common machines as not being operating systems so
-### that things like config.sub decstation-3100 work. We also
-### recognize some manufacturers as not being operating systems, so we
-### can provide default operating systems below.
-case $os in
- -sun*os*)
- # Prevent following clause from handling this invalid input.
- ;;
- -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
- -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
- -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
- -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
- -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
- -apple | -axis | -knuth | -cray | -microblaze)
- os=
- basic_machine=$1
- ;;
- -bluegene*)
- os=-cnk
- ;;
- -sim | -cisco | -oki | -wec | -winbond)
- os=
- basic_machine=$1
- ;;
- -scout)
- ;;
- -wrs)
- os=-vxworks
- basic_machine=$1
- ;;
- -chorusos*)
- os=-chorusos
- basic_machine=$1
- ;;
- -chorusrdb)
- os=-chorusrdb
- basic_machine=$1
- ;;
- -hiux*)
- os=-hiuxwe2
- ;;
- -sco6)
- os=-sco5v6
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5)
- os=-sco3.2v5
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco4)
- os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2.[4-9]*)
- os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco3.2v[4-9]*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco5v6*)
- # Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -sco*)
- os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -udk*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -isc)
- os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -clix*)
- basic_machine=clipper-intergraph
- ;;
- -isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
- ;;
- -lynx*)
- os=-lynxos
- ;;
- -ptx*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
- ;;
- -windowsnt*)
- os=`echo $os | sed -e 's/windowsnt/winnt/'`
- ;;
- -psos*)
- os=-psos
- ;;
- -mint | -mint[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
-esac
-
-# Decode aliases for certain CPU-COMPANY combinations.
-case $basic_machine in
- # Recognize the basic CPU types without company name.
- # Some are omitted here because they have special meanings below.
- 1750a | 580 \
- | a29k \
- | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
- | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
- | am33_2.0 \
- | arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
- | bfin \
- | c4x | clipper \
- | d10v | d30v | dlx | dsp16xx \
- | fido | fr30 | frv \
- | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
- | i370 | i860 | i960 | ia64 \
- | ip2k | iq2000 \
- | lm32 \
- | m32c | m32r | m32rle | m68000 | m68k | m88k \
- | maxq | mb | microblaze | mcore | mep | metag \
- | mips | mipsbe | mipseb | mipsel | mipsle \
- | mips16 \
- | mips64 | mips64el \
- | mips64octeon | mips64octeonel \
- | mips64orion | mips64orionel \
- | mips64r5900 | mips64r5900el \
- | mips64vr | mips64vrel \
- | mips64vr4100 | mips64vr4100el \
- | mips64vr4300 | mips64vr4300el \
- | mips64vr5000 | mips64vr5000el \
- | mips64vr5900 | mips64vr5900el \
- | mipsisa32 | mipsisa32el \
- | mipsisa32r2 | mipsisa32r2el \
- | mipsisa64 | mipsisa64el \
- | mipsisa64r2 | mipsisa64r2el \
- | mipsisa64sb1 | mipsisa64sb1el \
- | mipsisa64sr71k | mipsisa64sr71kel \
- | mipstx39 | mipstx39el \
- | mn10200 | mn10300 \
- | moxie \
- | mt \
- | msp430 \
- | nios | nios2 \
- | ns16k | ns32k \
- | or32 \
- | pdp10 | pdp11 | pj | pjl \
- | powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
- | pyramid \
- | rx \
- | score \
- | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
- | sh64 | sh64le \
- | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
- | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
- | spu | strongarm \
- | tahoe | thumb | tic4x | tic80 | tron \
- | ubicom32 \
- | v850 | v850e \
- | we32k \
- | x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
- | z8k | z80)
- basic_machine=$basic_machine-unknown
- ;;
- m6811 | m68hc11 | m6812 | m68hc12 | picochip)
- # Motorola 68HC11/12.
- basic_machine=$basic_machine-unknown
- os=-none
- ;;
- m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
- ;;
- ms1)
- basic_machine=mt-unknown
- ;;
-
- # We use `pc' rather than `unknown'
- # because (1) that's what they normally are, and
- # (2) the word "unknown" tends to confuse beginning users.
- i*86 | x86_64)
- basic_machine=$basic_machine-pc
- ;;
- # Object if more than one company name word.
- *-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
- # Recognize the basic CPU types with company name.
- 580-* \
- | a29k-* \
- | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
- | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
- | alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
- | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
- | avr-* | avr32-* \
- | bfin-* | bs2000-* \
- | c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
- | clipper-* | craynv-* | cydra-* \
- | d10v-* | d30v-* | dlx-* \
- | elxsi-* \
- | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
- | h8300-* | h8500-* \
- | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
- | i*86-* | i860-* | i960-* | ia64-* \
- | ip2k-* | iq2000-* \
- | lm32-* \
- | m32c-* | m32r-* | m32rle-* \
- | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
- | m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
- | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
- | mips16-* \
- | mips64-* | mips64el-* \
- | mips64octeon-* | mips64octeonel-* \
- | mips64orion-* | mips64orionel-* \
- | mips64r5900-* | mips64r5900el-* \
- | mips64vr-* | mips64vrel-* \
- | mips64vr4100-* | mips64vr4100el-* \
- | mips64vr4300-* | mips64vr4300el-* \
- | mips64vr5000-* | mips64vr5000el-* \
- | mips64vr5900-* | mips64vr5900el-* \
- | mipsisa32-* | mipsisa32el-* \
- | mipsisa32r2-* | mipsisa32r2el-* \
- | mipsisa64-* | mipsisa64el-* \
- | mipsisa64r2-* | mipsisa64r2el-* \
- | mipsisa64sb1-* | mipsisa64sb1el-* \
- | mipsisa64sr71k-* | mipsisa64sr71kel-* \
- | mipstx39-* | mipstx39el-* \
- | mmix-* \
- | mt-* \
- | msp430-* \
- | nios-* | nios2-* \
- | none-* | np1-* | ns16k-* | ns32k-* \
- | orion-* \
- | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
- | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
- | pyramid-* \
- | romp-* | rs6000-* | rx-* \
- | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
- | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
- | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
- | sparclite-* \
- | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
- | tahoe-* | thumb-* \
- | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
- | tile-* | tilegx-* \
- | tron-* \
- | ubicom32-* \
- | v850-* | v850e-* | vax-* \
- | we32k-* \
- | x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
- | xstormy16-* | xtensa*-* \
- | ymp-* \
- | z8k-* | z80-*)
- ;;
- # Recognize the basic CPU types without company name, with glob match.
- xtensa*)
- basic_machine=$basic_machine-unknown
- ;;
- # Recognize the various machine names and aliases which stand
- # for a CPU type and a company and sometimes even an OS.
- 386bsd)
- basic_machine=i386-unknown
- os=-bsd
- ;;
- 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
- basic_machine=m68000-att
- ;;
- 3b*)
- basic_machine=we32k-att
- ;;
- a29khif)
- basic_machine=a29k-amd
- os=-udi
- ;;
- abacus)
- basic_machine=abacus-unknown
- ;;
- adobe68k)
- basic_machine=m68010-adobe
- os=-scout
- ;;
- alliant | fx80)
- basic_machine=fx80-alliant
- ;;
- altos | altos3068)
- basic_machine=m68k-altos
- ;;
- am29k)
- basic_machine=a29k-none
- os=-bsd
- ;;
- amd64)
- basic_machine=x86_64-pc
- ;;
- amd64-*)
- basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- amdahl)
- basic_machine=580-amdahl
- os=-sysv
- ;;
- amiga | amiga-*)
- basic_machine=m68k-unknown
- ;;
- amigaos | amigados)
- basic_machine=m68k-unknown
- os=-amigaos
- ;;
- amigaunix | amix)
- basic_machine=m68k-unknown
- os=-sysv4
- ;;
- apollo68)
- basic_machine=m68k-apollo
- os=-sysv
- ;;
- apollo68bsd)
- basic_machine=m68k-apollo
- os=-bsd
- ;;
- aros)
- basic_machine=i386-pc
- os=-aros
- ;;
- aux)
- basic_machine=m68k-apple
- os=-aux
- ;;
- balance)
- basic_machine=ns32k-sequent
- os=-dynix
- ;;
- blackfin)
- basic_machine=bfin-unknown
- os=-linux
- ;;
- blackfin-*)
- basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- bluegene*)
- basic_machine=powerpc-ibm
- os=-cnk
- ;;
- c90)
- basic_machine=c90-cray
- os=-unicos
- ;;
- cegcc)
- basic_machine=arm-unknown
- os=-cegcc
- ;;
- convex-c1)
- basic_machine=c1-convex
- os=-bsd
- ;;
- convex-c2)
- basic_machine=c2-convex
- os=-bsd
- ;;
- convex-c32)
- basic_machine=c32-convex
- os=-bsd
- ;;
- convex-c34)
- basic_machine=c34-convex
- os=-bsd
- ;;
- convex-c38)
- basic_machine=c38-convex
- os=-bsd
- ;;
- cray | j90)
- basic_machine=j90-cray
- os=-unicos
- ;;
- craynv)
- basic_machine=craynv-cray
- os=-unicosmp
- ;;
- cr16)
- basic_machine=cr16-unknown
- os=-elf
- ;;
- crds | unos)
- basic_machine=m68k-crds
- ;;
- crisv32 | crisv32-* | etraxfs*)
- basic_machine=crisv32-axis
- ;;
- cris | cris-* | etrax*)
- basic_machine=cris-axis
- ;;
- crx)
- basic_machine=crx-unknown
- os=-elf
- ;;
- da30 | da30-*)
- basic_machine=m68k-da30
- ;;
- decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
- basic_machine=mips-dec
- ;;
- decsystem10* | dec10*)
- basic_machine=pdp10-dec
- os=-tops10
- ;;
- decsystem20* | dec20*)
- basic_machine=pdp10-dec
- os=-tops20
- ;;
- delta | 3300 | motorola-3300 | motorola-delta \
- | 3300-motorola | delta-motorola)
- basic_machine=m68k-motorola
- ;;
- delta88)
- basic_machine=m88k-motorola
- os=-sysv3
- ;;
- dicos)
- basic_machine=i686-pc
- os=-dicos
- ;;
- djgpp)
- basic_machine=i586-pc
- os=-msdosdjgpp
- ;;
- dpx20 | dpx20-*)
- basic_machine=rs6000-bull
- os=-bosx
- ;;
- dpx2* | dpx2*-bull)
- basic_machine=m68k-bull
- os=-sysv3
- ;;
- ebmon29k)
- basic_machine=a29k-amd
- os=-ebmon
- ;;
- elxsi)
- basic_machine=elxsi-elxsi
- os=-bsd
- ;;
- encore | umax | mmax)
- basic_machine=ns32k-encore
- ;;
- es1800 | OSE68k | ose68k | ose | OSE)
- basic_machine=m68k-ericsson
- os=-ose
- ;;
- fx2800)
- basic_machine=i860-alliant
- ;;
- genix)
- basic_machine=ns32k-ns
- ;;
- gmicro)
- basic_machine=tron-gmicro
- os=-sysv
- ;;
- go32)
- basic_machine=i386-pc
- os=-go32
- ;;
- h3050r* | hiux*)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- h8300hms)
- basic_machine=h8300-hitachi
- os=-hms
- ;;
- h8300xray)
- basic_machine=h8300-hitachi
- os=-xray
- ;;
- h8500hms)
- basic_machine=h8500-hitachi
- os=-hms
- ;;
- harris)
- basic_machine=m88k-harris
- os=-sysv3
- ;;
- hp300-*)
- basic_machine=m68k-hp
- ;;
- hp300bsd)
- basic_machine=m68k-hp
- os=-bsd
- ;;
- hp300hpux)
- basic_machine=m68k-hp
- os=-hpux
- ;;
- hp3k9[0-9][0-9] | hp9[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k2[0-9][0-9] | hp9k31[0-9])
- basic_machine=m68000-hp
- ;;
- hp9k3[2-9][0-9])
- basic_machine=m68k-hp
- ;;
- hp9k6[0-9][0-9] | hp6[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hp9k7[0-79][0-9] | hp7[0-79][0-9])
- basic_machine=hppa1.1-hp
- ;;
- hp9k78[0-9] | hp78[0-9])
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
- # FIXME: really hppa2.0-hp
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][13679] | hp8[0-9][13679])
- basic_machine=hppa1.1-hp
- ;;
- hp9k8[0-9][0-9] | hp8[0-9][0-9])
- basic_machine=hppa1.0-hp
- ;;
- hppa-next)
- os=-nextstep3
- ;;
- hppaosf)
- basic_machine=hppa1.1-hp
- os=-osf
- ;;
- hppro)
- basic_machine=hppa1.1-hp
- os=-proelf
- ;;
- i370-ibm* | ibm*)
- basic_machine=i370-ibm
- ;;
-# I'm not sure what "Sysv32" means. Should this be sysv3.2?
- i*86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv32
- ;;
- i*86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv4
- ;;
- i*86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-sysv
- ;;
- i*86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
- os=-solaris2
- ;;
- i386mach)
- basic_machine=i386-mach
- os=-mach
- ;;
- i386-vsta | vsta)
- basic_machine=i386-unknown
- os=-vsta
- ;;
- iris | iris4d)
- basic_machine=mips-sgi
- case $os in
- -irix*)
- ;;
- *)
- os=-irix4
- ;;
- esac
- ;;
- isi68 | isi)
- basic_machine=m68k-isi
- os=-sysv
- ;;
- m68knommu)
- basic_machine=m68k-unknown
- os=-linux
- ;;
- m68knommu-*)
- basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- m88k-omron*)
- basic_machine=m88k-omron
- ;;
- magnum | m3230)
- basic_machine=mips-mips
- os=-sysv
- ;;
- merlin)
- basic_machine=ns32k-utek
- os=-sysv
- ;;
- microblaze)
- basic_machine=microblaze-xilinx
- ;;
- mingw32)
- basic_machine=i386-pc
- os=-mingw32
- ;;
- mingw32ce)
- basic_machine=arm-unknown
- os=-mingw32ce
- ;;
- miniframe)
- basic_machine=m68000-convergent
- ;;
- *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
- basic_machine=m68k-atari
- os=-mint
- ;;
- mips3*-*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
- ;;
- mips3*)
- basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
- ;;
- monitor)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- morphos)
- basic_machine=powerpc-unknown
- os=-morphos
- ;;
- msdos)
- basic_machine=i386-pc
- os=-msdos
- ;;
- ms1-*)
- basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
- ;;
- mvs)
- basic_machine=i370-ibm
- os=-mvs
- ;;
- ncr3000)
- basic_machine=i486-ncr
- os=-sysv4
- ;;
- netbsd386)
- basic_machine=i386-unknown
- os=-netbsd
- ;;
- netwinder)
- basic_machine=armv4l-rebel
- os=-linux
- ;;
- news | news700 | news800 | news900)
- basic_machine=m68k-sony
- os=-newsos
- ;;
- news1000)
- basic_machine=m68030-sony
- os=-newsos
- ;;
- news-3600 | risc-news)
- basic_machine=mips-sony
- os=-newsos
- ;;
- necv70)
- basic_machine=v70-nec
- os=-sysv
- ;;
- next | m*-next )
- basic_machine=m68k-next
- case $os in
- -nextstep* )
- ;;
- -ns2*)
- os=-nextstep2
- ;;
- *)
- os=-nextstep3
- ;;
- esac
- ;;
- nh3000)
- basic_machine=m68k-harris
- os=-cxux
- ;;
- nh[45]000)
- basic_machine=m88k-harris
- os=-cxux
- ;;
- nindy960)
- basic_machine=i960-intel
- os=-nindy
- ;;
- mon960)
- basic_machine=i960-intel
- os=-mon960
- ;;
- nonstopux)
- basic_machine=mips-compaq
- os=-nonstopux
- ;;
- np1)
- basic_machine=np1-gould
- ;;
- nsr-tandem)
- basic_machine=nsr-tandem
- ;;
- op50n-* | op60c-*)
- basic_machine=hppa1.1-oki
- os=-proelf
- ;;
- openrisc | openrisc-*)
- basic_machine=or32-unknown
- ;;
- os400)
- basic_machine=powerpc-ibm
- os=-os400
- ;;
- OSE68000 | ose68000)
- basic_machine=m68000-ericsson
- os=-ose
- ;;
- os68k)
- basic_machine=m68k-none
- os=-os68k
- ;;
- pa-hitachi)
- basic_machine=hppa1.1-hitachi
- os=-hiuxwe2
- ;;
- paragon)
- basic_machine=i860-intel
- os=-osf
- ;;
- parisc)
- basic_machine=hppa-unknown
- os=-linux
- ;;
- parisc-*)
- basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
- os=-linux
- ;;
- pbd)
- basic_machine=sparc-tti
- ;;
- pbb)
- basic_machine=m68k-tti
- ;;
- pc532 | pc532-*)
- basic_machine=ns32k-pc532
- ;;
- pc98)
- basic_machine=i386-pc
- ;;
- pc98-*)
- basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium | p5 | k5 | k6 | nexgen | viac3)
- basic_machine=i586-pc
- ;;
- pentiumpro | p6 | 6x86 | athlon | athlon_*)
- basic_machine=i686-pc
- ;;
- pentiumii | pentium2 | pentiumiii | pentium3)
- basic_machine=i686-pc
- ;;
- pentium4)
- basic_machine=i786-pc
- ;;
- pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
- basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumpro-* | p6-* | 6x86-* | athlon-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
- basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pentium4-*)
- basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- pn)
- basic_machine=pn-gould
- ;;
- power) basic_machine=power-ibm
- ;;
- ppc) basic_machine=powerpc-unknown
- ;;
- ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppcle | powerpclittle | ppc-le | powerpc-little)
- basic_machine=powerpcle-unknown
- ;;
- ppcle-* | powerpclittle-*)
- basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64) basic_machine=powerpc64-unknown
- ;;
- ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ppc64le | powerpc64little | ppc64-le | powerpc64-little)
- basic_machine=powerpc64le-unknown
- ;;
- ppc64le-* | powerpc64little-*)
- basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
- ;;
- ps2)
- basic_machine=i386-ibm
- ;;
- pw32)
- basic_machine=i586-unknown
- os=-pw32
- ;;
- rdos)
- basic_machine=i386-pc
- os=-rdos
- ;;
- rom68k)
- basic_machine=m68k-rom68k
- os=-coff
- ;;
- rm[46]00)
- basic_machine=mips-siemens
- ;;
- rtpc | rtpc-*)
- basic_machine=romp-ibm
- ;;
- s390 | s390-*)
- basic_machine=s390-ibm
- ;;
- s390x | s390x-*)
- basic_machine=s390x-ibm
- ;;
- sa29200)
- basic_machine=a29k-amd
- os=-udi
- ;;
- sb1)
- basic_machine=mipsisa64sb1-unknown
- ;;
- sb1el)
- basic_machine=mipsisa64sb1el-unknown
- ;;
- sde)
- basic_machine=mipsisa32-sde
- os=-elf
- ;;
- sei)
- basic_machine=mips-sei
- os=-seiux
- ;;
- sequent)
- basic_machine=i386-sequent
- ;;
- sh)
- basic_machine=sh-hitachi
- os=-hms
- ;;
- sh5el)
- basic_machine=sh5le-unknown
- ;;
- sh64)
- basic_machine=sh64-unknown
- ;;
- sparclite-wrs | simso-wrs)
- basic_machine=sparclite-wrs
- os=-vxworks
- ;;
- sps7)
- basic_machine=m68k-bull
- os=-sysv2
- ;;
- spur)
- basic_machine=spur-unknown
- ;;
- st2000)
- basic_machine=m68k-tandem
- ;;
- stratus)
- basic_machine=i860-stratus
- os=-sysv4
- ;;
- sun2)
- basic_machine=m68000-sun
- ;;
- sun2os3)
- basic_machine=m68000-sun
- os=-sunos3
- ;;
- sun2os4)
- basic_machine=m68000-sun
- os=-sunos4
- ;;
- sun3os3)
- basic_machine=m68k-sun
- os=-sunos3
- ;;
- sun3os4)
- basic_machine=m68k-sun
- os=-sunos4
- ;;
- sun4os3)
- basic_machine=sparc-sun
- os=-sunos3
- ;;
- sun4os4)
- basic_machine=sparc-sun
- os=-sunos4
- ;;
- sun4sol2)
- basic_machine=sparc-sun
- os=-solaris2
- ;;
- sun3 | sun3-*)
- basic_machine=m68k-sun
- ;;
- sun4)
- basic_machine=sparc-sun
- ;;
- sun386 | sun386i | roadrunner)
- basic_machine=i386-sun
- ;;
- sv1)
- basic_machine=sv1-cray
- os=-unicos
- ;;
- symmetry)
- basic_machine=i386-sequent
- os=-dynix
- ;;
- t3e)
- basic_machine=alphaev5-cray
- os=-unicos
- ;;
- t90)
- basic_machine=t90-cray
- os=-unicos
- ;;
- tic54x | c54x*)
- basic_machine=tic54x-unknown
- os=-coff
- ;;
- tic55x | c55x*)
- basic_machine=tic55x-unknown
- os=-coff
- ;;
- tic6x | c6x*)
- basic_machine=tic6x-unknown
- os=-coff
- ;;
- # This must be matched before tile*.
- tilegx*)
- basic_machine=tilegx-unknown
- os=-linux-gnu
- ;;
- tile*)
- basic_machine=tile-unknown
- os=-linux-gnu
- ;;
- tx39)
- basic_machine=mipstx39-unknown
- ;;
- tx39el)
- basic_machine=mipstx39el-unknown
- ;;
- toad1)
- basic_machine=pdp10-xkl
- os=-tops20
- ;;
- tower | tower-32)
- basic_machine=m68k-ncr
- ;;
- tpf)
- basic_machine=s390x-ibm
- os=-tpf
- ;;
- udi29k)
- basic_machine=a29k-amd
- os=-udi
- ;;
- ultra3)
- basic_machine=a29k-nyu
- os=-sym1
- ;;
- v810 | necv810)
- basic_machine=v810-nec
- os=-none
- ;;
- vaxv)
- basic_machine=vax-dec
- os=-sysv
- ;;
- vms)
- basic_machine=vax-dec
- os=-vms
- ;;
- vpp*|vx|vx-*)
- basic_machine=f301-fujitsu
- ;;
- vxworks960)
- basic_machine=i960-wrs
- os=-vxworks
- ;;
- vxworks68)
- basic_machine=m68k-wrs
- os=-vxworks
- ;;
- vxworks29k)
- basic_machine=a29k-wrs
- os=-vxworks
- ;;
- w65*)
- basic_machine=w65-wdc
- os=-none
- ;;
- w89k-*)
- basic_machine=hppa1.1-winbond
- os=-proelf
- ;;
- xbox)
- basic_machine=i686-pc
- os=-mingw32
- ;;
- xps | xps100)
- basic_machine=xps100-honeywell
- ;;
- ymp)
- basic_machine=ymp-cray
- os=-unicos
- ;;
- z8k-*-coff)
- basic_machine=z8k-unknown
- os=-sim
- ;;
- z80-*-coff)
- basic_machine=z80-unknown
- os=-sim
- ;;
- none)
- basic_machine=none-none
- os=-none
- ;;
-
-# Here we handle the default manufacturer of certain CPU types. It is in
-# some cases the only manufacturer, in others, it is the most popular.
- w89k)
- basic_machine=hppa1.1-winbond
- ;;
- op50n)
- basic_machine=hppa1.1-oki
- ;;
- op60c)
- basic_machine=hppa1.1-oki
- ;;
- romp)
- basic_machine=romp-ibm
- ;;
- mmix)
- basic_machine=mmix-knuth
- ;;
- rs6000)
- basic_machine=rs6000-ibm
- ;;
- vax)
- basic_machine=vax-dec
- ;;
- pdp10)
- # there are many clones, so DEC is not a safe bet
- basic_machine=pdp10-unknown
- ;;
- pdp11)
- basic_machine=pdp11-dec
- ;;
- we32k)
- basic_machine=we32k-att
- ;;
- sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
- basic_machine=sh-unknown
- ;;
- sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
- basic_machine=sparc-sun
- ;;
- cydra)
- basic_machine=cydra-cydrome
- ;;
- orion)
- basic_machine=orion-highlevel
- ;;
- orion105)
- basic_machine=clipper-highlevel
- ;;
- mac | mpw | mac-mpw)
- basic_machine=m68k-apple
- ;;
- pmac | pmac-mpw)
- basic_machine=powerpc-apple
- ;;
- *-unknown)
- # Make sure to match an already-canonicalized machine name.
- ;;
- *)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
- ;;
-esac
-
-# Here we canonicalize certain aliases for manufacturers.
-case $basic_machine in
- *-digital*)
- basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
- ;;
- *-commodore*)
- basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
- ;;
- *)
- ;;
-esac
-
-# Decode manufacturer-specific aliases for certain operating systems.
-
-if [ x"$os" != x"" ]
-then
-case $os in
- # First match some system type aliases
- # that might get confused with valid system types.
- # -solaris* is a basic system type, with this one exception.
- -auroraux)
- os=-auroraux
- ;;
- -solaris1 | -solaris1.*)
- os=`echo $os | sed -e 's|solaris1|sunos4|'`
- ;;
- -solaris)
- os=-solaris2
- ;;
- -svr4*)
- os=-sysv4
- ;;
- -unixware*)
- os=-sysv4.2uw
- ;;
- -gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
- ;;
- # First accept the basic system types.
- # The portable systems comes first.
- # Each alternative MUST END IN A *, to match a version number.
- # -sysv* is not here because it comes later, after sysvr4.
- -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
- | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
- | -sym* | -kopensolaris* \
- | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
- | -aos* | -aros* \
- | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
- | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
- | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
- | -openbsd* | -solidbsd* \
- | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
- | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
- | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
- | -chorusos* | -chorusrdb* | -cegcc* \
- | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
- | -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
- | -uxpv* | -beos* | -mpeix* | -udk* \
- | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
- | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
- | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
- | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
- | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
- | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
- | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es*)
- # Remember, each alternative MUST END IN *, to match a version number.
- ;;
- -qnx*)
- case $basic_machine in
- x86-* | i*86-*)
- ;;
- *)
- os=-nto$os
- ;;
- esac
- ;;
- -nto-qnx*)
- ;;
- -nto*)
- os=`echo $os | sed -e 's|nto|nto-qnx|'`
- ;;
- -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
- | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
- | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
- ;;
- -mac*)
- os=`echo $os | sed -e 's|mac|macos|'`
- ;;
- -linux-dietlibc)
- os=-linux-dietlibc
- ;;
- -linux*)
- os=`echo $os | sed -e 's|linux|linux-gnu|'`
- ;;
- -sunos5*)
- os=`echo $os | sed -e 's|sunos5|solaris2|'`
- ;;
- -sunos6*)
- os=`echo $os | sed -e 's|sunos6|solaris3|'`
- ;;
- -opened*)
- os=-openedition
- ;;
- -os400*)
- os=-os400
- ;;
- -wince*)
- os=-wince
- ;;
- -osfrose*)
- os=-osfrose
- ;;
- -osf*)
- os=-osf
- ;;
- -utek*)
- os=-bsd
- ;;
- -dynix*)
- os=-bsd
- ;;
- -acis*)
- os=-aos
- ;;
- -atheos*)
- os=-atheos
- ;;
- -syllable*)
- os=-syllable
- ;;
- -386bsd)
- os=-bsd
- ;;
- -ctix* | -uts*)
- os=-sysv
- ;;
- -nova*)
- os=-rtmk-nova
- ;;
- -ns2 )
- os=-nextstep2
- ;;
- -nsk*)
- os=-nsk
- ;;
- # Preserve the version number of sinix5.
- -sinix5.*)
- os=`echo $os | sed -e 's|sinix|sysv|'`
- ;;
- -sinix*)
- os=-sysv4
- ;;
- -tpf*)
- os=-tpf
- ;;
- -triton*)
- os=-sysv3
- ;;
- -oss*)
- os=-sysv3
- ;;
- -svr4)
- os=-sysv4
- ;;
- -svr3)
- os=-sysv3
- ;;
- -sysvr4)
- os=-sysv4
- ;;
- # This must come after -sysvr4.
- -sysv*)
- ;;
- -ose*)
- os=-ose
- ;;
- -es1800*)
- os=-ose
- ;;
- -xenix)
- os=-xenix
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- os=-mint
- ;;
- -aros*)
- os=-aros
- ;;
- -kaos*)
- os=-kaos
- ;;
- -zvmoe)
- os=-zvmoe
- ;;
- -dicos*)
- os=-dicos
- ;;
- -nacl*)
- ;;
- -none)
- ;;
- *)
- # Get rid of the `-' at the beginning of $os.
- os=`echo $os | sed 's/[^-]*-//'`
- echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
- exit 1
- ;;
-esac
-else
-
-# Here we handle the default operating systems that come with various machines.
-# The value should be what the vendor currently ships out the door with their
-# machine or put another way, the most popular os provided with the machine.
-
-# Note that if you're going to try to match "-MANUFACTURER" here (say,
-# "-sun"), then you have to tell the case statement up towards the top
-# that MANUFACTURER isn't an operating system. Otherwise, code above
-# will signal an error saying that MANUFACTURER isn't an operating
-# system, and we'll never get to this point.
-
-case $basic_machine in
- score-*)
- os=-elf
- ;;
- spu-*)
- os=-elf
- ;;
- *-acorn)
- os=-riscix1.2
- ;;
- arm*-rebel)
- os=-linux
- ;;
- arm*-semi)
- os=-aout
- ;;
- c4x-* | tic4x-*)
- os=-coff
- ;;
- # This must come before the *-dec entry.
- pdp10-*)
- os=-tops20
- ;;
- pdp11-*)
- os=-none
- ;;
- *-dec | vax-*)
- os=-ultrix4.2
- ;;
- m68*-apollo)
- os=-domain
- ;;
- i386-sun)
- os=-sunos4.0.2
- ;;
- m68000-sun)
- os=-sunos3
- # This also exists in the configure program, but was not the
- # default.
- # os=-sunos4
- ;;
- m68*-cisco)
- os=-aout
- ;;
- mep-*)
- os=-elf
- ;;
- mips*-cisco)
- os=-elf
- ;;
- mips*-*)
- os=-elf
- ;;
- or32-*)
- os=-coff
- ;;
- *-tti) # must be before sparc entry or we get the wrong os.
- os=-sysv3
- ;;
- sparc-* | *-sun)
- os=-sunos4.1.1
- ;;
- *-be)
- os=-beos
- ;;
- *-haiku)
- os=-haiku
- ;;
- *-ibm)
- os=-aix
- ;;
- *-knuth)
- os=-mmixware
- ;;
- *-wec)
- os=-proelf
- ;;
- *-winbond)
- os=-proelf
- ;;
- *-oki)
- os=-proelf
- ;;
- *-hp)
- os=-hpux
- ;;
- *-hitachi)
- os=-hiux
- ;;
- i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
- os=-sysv
- ;;
- *-cbm)
- os=-amigaos
- ;;
- *-dg)
- os=-dgux
- ;;
- *-dolphin)
- os=-sysv3
- ;;
- m68k-ccur)
- os=-rtu
- ;;
- m88k-omron*)
- os=-luna
- ;;
- *-next )
- os=-nextstep
- ;;
- *-sequent)
- os=-ptx
- ;;
- *-crds)
- os=-unos
- ;;
- *-ns)
- os=-genix
- ;;
- i370-*)
- os=-mvs
- ;;
- *-next)
- os=-nextstep3
- ;;
- *-gould)
- os=-sysv
- ;;
- *-highlevel)
- os=-bsd
- ;;
- *-encore)
- os=-bsd
- ;;
- *-sgi)
- os=-irix
- ;;
- *-siemens)
- os=-sysv4
- ;;
- *-masscomp)
- os=-rtu
- ;;
- f30[01]-fujitsu | f700-fujitsu)
- os=-uxpv
- ;;
- *-rom68k)
- os=-coff
- ;;
- *-*bug)
- os=-coff
- ;;
- *-apple)
- os=-macos
- ;;
- *-atari*)
- os=-mint
- ;;
- *)
- os=-none
- ;;
-esac
-fi
-
-# Here we handle the case where we know the os, and the CPU type, but not the
-# manufacturer. We pick the logical manufacturer.
-vendor=unknown
-case $basic_machine in
- *-unknown)
- case $os in
- -riscix*)
- vendor=acorn
- ;;
- -sunos*)
- vendor=sun
- ;;
- -cnk*|-aix*)
- vendor=ibm
- ;;
- -beos*)
- vendor=be
- ;;
- -hpux*)
- vendor=hp
- ;;
- -mpeix*)
- vendor=hp
- ;;
- -hiux*)
- vendor=hitachi
- ;;
- -unos*)
- vendor=crds
- ;;
- -dgux*)
- vendor=dg
- ;;
- -luna*)
- vendor=omron
- ;;
- -genix*)
- vendor=ns
- ;;
- -mvs* | -opened*)
- vendor=ibm
- ;;
- -os400*)
- vendor=ibm
- ;;
- -ptx*)
- vendor=sequent
- ;;
- -tpf*)
- vendor=ibm
- ;;
- -vxsim* | -vxworks* | -windiss*)
- vendor=wrs
- ;;
- -aux*)
- vendor=apple
- ;;
- -hms*)
- vendor=hitachi
- ;;
- -mpw* | -macos*)
- vendor=apple
- ;;
- -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
- vendor=atari
- ;;
- -vos*)
- vendor=stratus
- ;;
- esac
- basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
- ;;
-esac
-
-echo $basic_machine$os
-exit
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "timestamp='"
-# time-stamp-format: "%:y-%02m-%02d"
-# time-stamp-end: "'"
-# End:
+++ /dev/null
-AC_INIT(README)
-AM_INIT_AUTOMAKE(pve-manager,2.0)
-AM_MAINTAINER_MODE
-
-prefix=/usr
-
-PACKAGERELEASE=4
-AC_SUBST(PACKAGERELEASE)
-
-REPOID=`svnversion .`
-AC_SUBST(REPOID)
-
-PERL_LIBDIR="/usr/share/perl5"
-AC_SUBST(PERL_LIBDIR)
-
-PROXMOX_ETC="/etc/pve"
-AC_SUBST(PROXMOX_ETC)
-
-DOCDIR="/usr/share/doc/${PACKAGE}"
-AC_SUBST(DOCDIR)
-
-WWW_BASEDIR="/usr/share/${PACKAGE}"
-AC_SUBST(WWW_BASEDIR)
-
-WWW_ROOTDIR="${WWW_BASEDIR}/root"
-AC_SUBST(WWW_ROOTDIR)
-
-WWW_IMAGEDIR="${WWW_BASEDIR}/images"
-AC_SUBST(WWW_IMAGEDIR)
-
-WWW_CSSDIR="${WWW_BASEDIR}/css"
-AC_SUBST(WWW_CSSDIR)
-
-WWW_EXTDIR="${WWW_BASEDIR}/ext4"
-AC_SUBST(WWW_EXTDIR)
-
-#AM_GNU_GETTEXT
-AM_PO_SUBDIRS
-
-AC_PROG_CC()
-
-AC_OUTPUT([
-Makefile
-po/Makefile.in
-debian/control
-aplinfo/Makefile
-lib/PVE/pvecfg.pm
-lib/Makefile
-lib/PVE/Makefile
-lib/PVE/API2/Makefile
-bin/Makefile
-bin/test/Makefile
-bin/init.d/Makefile
-bin/cron/Makefile
-bin/cron/daily/Makefile
-www/Makefile
-www/templates/Makefile
-www/css/Makefile
-www/ext4/Makefile
-www/manager/Makefile
-www/images/Makefile
-www/templates/pve.conf
-www/templates/pve-redirect.conf
-])
-
-#www/root/Makefile
-#www/root/cluster/Makefile
-#www/root/vmlist/Makefile
-#www/root/openvz/Makefile
-#www/root/openvz/vmlogs/Makefile
-#www/root/qemu/Makefile
-#www/root/apl/Makefile
-#www/root/iso/Makefile
-#www/root/system/Makefile
-#www/root/server/Makefile
-#www/root/storage/Makefile
-#www/root/backup/Makefile
-#www/root/logs/Makefile
-
-
#!/usr/bin/perl -w
-use lib qw (./lib);
use strict;
use PVE::Tools;
--- /dev/null
+RELEASE=2.0
+
+VERSION=2.0
+PACKAGE=pve-manager
+PKGREL=4
+
+BINDIR=${DESTDIR}/usr/bin
+PERLLIBDIR=${DESTDIR}/usr/share/perl5
+MAN1DIR=${DESTDIR}/usr/share/man/man1
+CRONDAILYDIR=${DESTDIR}/etc/cron.daily
+INITDBINDIR=${DESTDIR}/etc/init.d/
+DOCDIR=${DESTDIR}/usr/share/doc/${PACKAGE}
+WWWBASEDIR=${DESTDIR}/usr/share/${PACKAGE}
+WWWROOTDIR=${WWWBASEDIR}/root
+WWWIMAGEDIR=${WWWBASEDIR}/images
+WWWEXT4DIR=${WWWBASEDIR}/ext4
+WWWCSSDIR=${WWWBASEDIR}/css
\ No newline at end of file
+++ /dev/null
-#!/bin/sh
-# install - install a program, script, or datafile
-
-scriptversion=2005-05-14.22
-
-# This originates from X11R5 (mit/util/scripts/install.sh), which was
-# later released in X11R6 (xc/config/util/install.sh) with the
-# following copyright and license.
-#
-# Copyright (C) 1994 X Consortium
-#
-# Permission is hereby granted, free of charge, to any person obtaining a copy
-# of this software and associated documentation files (the "Software"), to
-# deal in the Software without restriction, including without limitation the
-# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-# sell copies of the Software, and to permit persons to whom the Software is
-# furnished to do so, subject to the following conditions:
-#
-# The above copyright notice and this permission notice shall be included in
-# all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
-# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
-# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-#
-# Except as contained in this notice, the name of the X Consortium shall not
-# be used in advertising or otherwise to promote the sale, use or other deal-
-# ings in this Software without prior written authorization from the X Consor-
-# tium.
-#
-#
-# FSF changes to this file are in the public domain.
-#
-# Calling this script install-sh is preferred over install.sh, to prevent
-# `make' implicit rules from creating a file called install from it
-# when there is no Makefile.
-#
-# This script is compatible with the BSD install script, but was written
-# from scratch. It can only install one file at a time, a restriction
-# shared with many OS's install programs.
-
-# set DOITPROG to echo to test this script
-
-# Don't use :- since 4.3BSD and earlier shells don't like it.
-doit="${DOITPROG-}"
-
-# put in absolute paths if you don't have them in your path; or use env. vars.
-
-mvprog="${MVPROG-mv}"
-cpprog="${CPPROG-cp}"
-chmodprog="${CHMODPROG-chmod}"
-chownprog="${CHOWNPROG-chown}"
-chgrpprog="${CHGRPPROG-chgrp}"
-stripprog="${STRIPPROG-strip}"
-rmprog="${RMPROG-rm}"
-mkdirprog="${MKDIRPROG-mkdir}"
-
-chmodcmd="$chmodprog 0755"
-chowncmd=
-chgrpcmd=
-stripcmd=
-rmcmd="$rmprog -f"
-mvcmd="$mvprog"
-src=
-dst=
-dir_arg=
-dstarg=
-no_target_directory=
-
-usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
- or: $0 [OPTION]... SRCFILES... DIRECTORY
- or: $0 [OPTION]... -t DIRECTORY SRCFILES...
- or: $0 [OPTION]... -d DIRECTORIES...
-
-In the 1st form, copy SRCFILE to DSTFILE.
-In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
-In the 4th, create DIRECTORIES.
-
-Options:
--c (ignored)
--d create directories instead of installing files.
--g GROUP $chgrpprog installed files to GROUP.
--m MODE $chmodprog installed files to MODE.
--o USER $chownprog installed files to USER.
--s $stripprog installed files.
--t DIRECTORY install into DIRECTORY.
--T report an error if DSTFILE is a directory.
---help display this help and exit.
---version display version info and exit.
-
-Environment variables override the default commands:
- CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG
-"
-
-while test -n "$1"; do
- case $1 in
- -c) shift
- continue;;
-
- -d) dir_arg=true
- shift
- continue;;
-
- -g) chgrpcmd="$chgrpprog $2"
- shift
- shift
- continue;;
-
- --help) echo "$usage"; exit $?;;
-
- -m) chmodcmd="$chmodprog $2"
- shift
- shift
- continue;;
-
- -o) chowncmd="$chownprog $2"
- shift
- shift
- continue;;
-
- -s) stripcmd=$stripprog
- shift
- continue;;
-
- -t) dstarg=$2
- shift
- shift
- continue;;
-
- -T) no_target_directory=true
- shift
- continue;;
-
- --version) echo "$0 $scriptversion"; exit $?;;
-
- *) # When -d is used, all remaining arguments are directories to create.
- # When -t is used, the destination is already specified.
- test -n "$dir_arg$dstarg" && break
- # Otherwise, the last argument is the destination. Remove it from $@.
- for arg
- do
- if test -n "$dstarg"; then
- # $@ is not empty: it contains at least $arg.
- set fnord "$@" "$dstarg"
- shift # fnord
- fi
- shift # arg
- dstarg=$arg
- done
- break;;
- esac
-done
-
-if test -z "$1"; then
- if test -z "$dir_arg"; then
- echo "$0: no input file specified." >&2
- exit 1
- fi
- # It's OK to call `install-sh -d' without argument.
- # This can happen when creating conditional directories.
- exit 0
-fi
-
-for src
-do
- # Protect names starting with `-'.
- case $src in
- -*) src=./$src ;;
- esac
-
- if test -n "$dir_arg"; then
- dst=$src
- src=
-
- if test -d "$dst"; then
- mkdircmd=:
- chmodcmd=
- else
- mkdircmd=$mkdirprog
- fi
- else
- # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
- # might cause directories to be created, which would be especially bad
- # if $src (and thus $dsttmp) contains '*'.
- if test ! -f "$src" && test ! -d "$src"; then
- echo "$0: $src does not exist." >&2
- exit 1
- fi
-
- if test -z "$dstarg"; then
- echo "$0: no destination specified." >&2
- exit 1
- fi
-
- dst=$dstarg
- # Protect names starting with `-'.
- case $dst in
- -*) dst=./$dst ;;
- esac
-
- # If destination is a directory, append the input filename; won't work
- # if double slashes aren't ignored.
- if test -d "$dst"; then
- if test -n "$no_target_directory"; then
- echo "$0: $dstarg: Is a directory" >&2
- exit 1
- fi
- dst=$dst/`basename "$src"`
- fi
- fi
-
- # This sed command emulates the dirname command.
- dstdir=`echo "$dst" | sed -e 's,/*$,,;s,[^/]*$,,;s,/*$,,;s,^$,.,'`
-
- # Make sure that the destination directory exists.
-
- # Skip lots of stat calls in the usual case.
- if test ! -d "$dstdir"; then
- defaultIFS='
- '
- IFS="${IFS-$defaultIFS}"
-
- oIFS=$IFS
- # Some sh's can't handle IFS=/ for some reason.
- IFS='%'
- set x `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
- shift
- IFS=$oIFS
-
- pathcomp=
-
- while test $# -ne 0 ; do
- pathcomp=$pathcomp$1
- shift
- if test ! -d "$pathcomp"; then
- $mkdirprog "$pathcomp"
- # mkdir can fail with a `File exist' error in case several
- # install-sh are creating the directory concurrently. This
- # is OK.
- test -d "$pathcomp" || exit
- fi
- pathcomp=$pathcomp/
- done
- fi
-
- if test -n "$dir_arg"; then
- $doit $mkdircmd "$dst" \
- && { test -z "$chowncmd" || $doit $chowncmd "$dst"; } \
- && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } \
- && { test -z "$stripcmd" || $doit $stripcmd "$dst"; } \
- && { test -z "$chmodcmd" || $doit $chmodcmd "$dst"; }
-
- else
- dstfile=`basename "$dst"`
-
- # Make a couple of temp file names in the proper directory.
- dsttmp=$dstdir/_inst.$$_
- rmtmp=$dstdir/_rm.$$_
-
- # Trap to clean up those temp files at exit.
- trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
- trap '(exit $?); exit' 1 2 13 15
-
- # Copy the file name to the temp name.
- $doit $cpprog "$src" "$dsttmp" &&
-
- # and set any options; do chmod last to preserve setuid bits.
- #
- # If any of these fail, we abort the whole thing. If we want to
- # ignore errors from any of these, just make sure not to ignore
- # errors from the above "$doit $cpprog $src $dsttmp" command.
- #
- { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \
- && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \
- && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \
- && { test -z "$chmodcmd" || $doit $chmodcmd "$dsttmp"; } &&
-
- # Now rename the file to the real destination.
- { $doit $mvcmd -f "$dsttmp" "$dstdir/$dstfile" 2>/dev/null \
- || {
- # The rename failed, perhaps because mv can't rename something else
- # to itself, or perhaps because mv is so ancient that it does not
- # support -f.
-
- # Now remove or move aside any old file at destination location.
- # We try this two ways since rm can't unlink itself on some
- # systems and the destination file might be busy for other
- # reasons. In this case, the final cleanup might fail but the new
- # file should still install successfully.
- {
- if test -f "$dstdir/$dstfile"; then
- $doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null \
- || $doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null \
- || {
- echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
- (exit 1); exit 1
- }
- else
- :
- fi
- } &&
-
- # Now rename the file to the real destination.
- $doit $mvcmd "$dsttmp" "$dstdir/$dstfile"
- }
- }
- fi || { (exit 1); exit 1; }
-done
-
-# The final little trick to "correctly" pass the exit status to the exit trap.
-{
- (exit 0); exit 0
-}
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
+++ /dev/null
-include $(top_builddir)/common.mk
-
-SUBDIRS = PVE
+++ /dev/null
-package PVE::Cluster;
-
-use strict;
-use Socket;
-use IO::File;
-use PVE::Config;
-use PVE::Utils;
-use PVE::I18N;
-use PVE::SafeSyslog;
-use Time::HiRes qw (gettimeofday);
-
-my $hostrsapubkey;
-my $rootrsapubkey;
-
-# x509 certificate utils
-
-my $basedir = "/etc/pve";
-my $pveca_key_fn = "$basedir/priv/pve-root-ca.key";
-my $pveca_srl_fn = "$basedir/priv/pve-root-ca.srl";
-my $pveca_cert_fn = "$basedir/pve-root-ca.pem";
-my $pvessl_key_fn = "$basedir/local/pve-ssl.key";
-my $pvessl_cert_fn = "$basedir/local/pve-ssl.pem";
-
-sub gen_local_dirs {
- my ($nodename) = @_;
-
- (-l "$basedir/local" ) || die "pve configuration filesystem not mounted\n";
-
- my $dir = "$basedir/nodes/$nodename";
- if (! -d $dir) {
- mkdir($dir) || die "unable to create directory '$dir' - $!\n";
- }
- $dir = "$dir/priv";
- if (! -d $dir) {
- mkdir($dir) || die "unable to create directory '$dir' - $!\n";
- }
-}
-
-sub gen_pveca_key {
-
- return if -f $pveca_key_fn;
-
- eval {
- PVE::Utils::run_command (['openssl', 'genrsa', '-out', $pveca_key_fn, '1024']);
- };
-
- die "unable to generate pve ca key:\n$@" if $@;
-}
-
-sub gen_pveca_cert {
-
- if (-f $pveca_key_fn && -f $pveca_cert_fn) {
- return 0;
- }
-
- 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();
-
- eval {
- PVE::Utils::run_command (['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/"]);
- };
-
- die "generating pve root certificate failed:\n$@" if $@;
-
- return 1;
-}
-
-sub gen_pve_ssl_key {
-
- return if -f $pvessl_key_fn;
-
- eval {
- PVE::Utils::run_command (['openssl', 'genrsa', '-out', $pvessl_key_fn, '1024']);
- };
-
- die "unable to generate pve ssl key:\n$@" if $@;
-}
-
-sub update_serial {
- my ($serial) = @_;
-
- PVE::Tools::file_set_contents($pveca_srl_fn, $serial);
-}
-
-sub gen_pve_ssl_cert {
- my ($force, $nodename) = @_;
-
- return if !$force && -f $pvessl_cert_fn;
-
- my $names = "IP:127.0.0.1,DNS:localhost";
-
- my $rc = PVE::Config::read_file ('resolvconf');
-
- my $packed_ip = gethostbyname($nodename);
- if (defined $packed_ip) {
- my $ip = inet_ntoa($packed_ip);
- $names .= ",IP:" . $ip;
- }
-
- my $fqdn = $nodename;
-
- $names .= ",DNS:" . $nodename;
-
- if ($rc && $rc->{search}) {
- $fqdn = $nodename . "." . $rc->{search};
- $names .= ",DNS:$fqdn";
- }
-
-
- my $sslconf = <<__EOD;
-RANDFILE = /root/.rnd
-extensions = v3_req
-
-[ req ]
-default_bits = 1024
-distinguished_name = req_distinguished_name
-req_extensions = v3_req
-prompt = no
-string_mask = nombstr
-
-[ req_distinguished_name ]
-organizationalUnitName = PVE Cluster Node
-organizationName = Proxmox Virtual Environment
-commonName = $fqdn
-
-[ v3_req ]
-basicConstraints = CA:FALSE
-nsCertType = server
-keyUsage = nonRepudiation, digitalSignature, keyEncipherment
-subjectAltName = $names
-__EOD
-
- my $cfgfn = "/tmp/pvesslconf-$$.tmp";
- my $fh = IO::File->new ($cfgfn, "w");
- print $fh $sslconf;
- close ($fh);
-
- my $reqfn = "/tmp/pvecertreq-$$.tmp";
- unlink $reqfn;
-
- eval {
- PVE::Utils::run_command (['openssl', 'req', '-batch', '-new', '-config', $cfgfn,
- '-key', $pvessl_key_fn, '-out', $reqfn]);
- };
-
- if (my $err = $@) {
- unlink $reqfn;
- unlink $cfgfn;
- die "unable to generate pve certificate request:\n$err";
- }
-
- update_serial ("0000000000000000") if ! -f $pveca_srl_fn;
-
- eval {
- PVE::Utils::run_command (['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 = $@) {
- unlink $reqfn;
- unlink $cfgfn;
- die "unable to generate pve ssl certificate:\n$err";
- }
-
- unlink $cfgfn;
- unlink $reqfn;
-}
-
-sub clusterinfo {
- my ($filename) = @_;
-
- $filename = "/etc/pve/cluster.cfg" if !$filename;
-
- my $ifaces = PVE::Config::read_file ("interfaces");
- my $hostname = PVE::Config::read_file ("hostname");
- my $ccfg = PVE::Config::read_file ($filename);
-
- my $localip = $ifaces->{vmbr0}->{address} || $ifaces->{eth0}->{address};
-
- my $cinfo;
-
- if ($ccfg) {
- $cinfo = $ccfg;
- $cinfo->{exists} = 1;
- }
-
- $cinfo->{local} = {
- role => '-',
- cid => 0,
- ip => $localip,
- name => $hostname,
- };
-
- my $found = 0;
- foreach my $ni (@{$cinfo->{nodes}}) {
- if ($ni->{ip} eq $localip || $ni->{name} eq $hostname) {
- $cinfo->{local} = $ni;
- $found = 1;
- last;
- }
- }
-
- if (!$found) {
- push @{$cinfo->{nodes}}, $cinfo->{local};
- $cinfo->{"CID_0"} = $cinfo->{local};
- }
-
- # fixme: assign fixed ports instead?
- # fixme: $ni->{configport} = 50000 + $ni->{cid};
- my $ind = 0;
- foreach my $ni (sort {$a->{cid} <=> $b->{cid}} @{$cinfo->{nodes}}) {
- if ($ni->{cid} == $cinfo->{local}->{cid}) {
- $ni->{configport} = 83;
- } else {
- $ni->{configport} = 50000 + $ind;
- $ind++;
- }
- }
-
- return $cinfo;
-}
-
-sub save_clusterinfo {
- my ($cinfo) = @_;
-
- my $filename = "/etc/pve/cluster.cfg";
-
- my $fh = PVE::AtomicFile->open($filename, "w");
-
- eval {
-
- return if !$cinfo->{nodes} || scalar (@{$cinfo->{nodes}}) == 0;
-
- printf ($fh "maxcid $cinfo->{maxcid}\n\n");
-
- foreach my $ni (@{$cinfo->{nodes}}) {
-
- my $cid = $ni->{cid};
- die "missing cluster id\n" if !$cid;
- die "missing ip address for node '$cid'\n" if !$ni->{ip};
- die "missing name for node '$cid'\n" if !$ni->{name};
- die "missing host RSA key for node '$cid'\n" if !$ni->{hostrsapubkey};
- die "missing user RSA key for node '$cid'\n" if !$ni->{rootrsapubkey};
-
- if ($ni->{role} eq 'M') {
- printf ($fh "master $ni->{cid} {\n");
- printf ($fh " IP: $ni->{ip}\n");
- printf ($fh " NAME: $ni->{name}\n");
- printf ($fh " HOSTRSAPUBKEY: $ni->{hostrsapubkey}\n");
- printf ($fh " ROOTRSAPUBKEY: $ni->{rootrsapubkey}\n");
- printf ($fh "}\n\n");
- } elsif ($ni->{role} eq 'N') {
- printf ($fh "node $ni->{cid} {\n");
- printf ($fh " IP: $ni->{ip}\n");
- printf ($fh " NAME: $ni->{name}\n");
- printf ($fh " HOSTRSAPUBKEY: $ni->{hostrsapubkey}\n");
- printf ($fh " ROOTRSAPUBKEY: $ni->{rootrsapubkey}\n");
- printf ($fh "}\n\n");
- }
- }
- };
-
- my $err = $@;
- $fh->detach() if $err;
- $fh->close(1);
-
- die $err if $err;
-}
-
-sub rewrite_keys {
- my ($cinfo) = @_;
-
- mkdir '/root/.ssh/';
-
- # rewrite authorized hosts files
-
- my $filename = '/root/.ssh/authorized_keys';
- my $fh;
- my $changes;
-
- eval {
-
- $fh = PVE::AtomicFile->open ($filename, "w");
-
- my $done = {};
-
- eval {
- if (open (ORG, "$filename")) {
- while (my $line = <ORG>) {
- if ($line =~ m/^\s*ssh-rsa\s+(\S+)\s+root\@(\S+)\s*$/) {
- my ($key, $ip) = ($1, $2);
- my $new;
-
- foreach my $ni (@{$cinfo->{nodes}}) {
- $new = $ni if $ni->{ip} eq $ip;
- }
-
- if ($new) {
- if (!$done->{$ip}) {
- $changes = 1 if $key ne $new->{rootrsapubkey};
- printf ($fh "ssh-rsa %s root\@%s\n", $new->{rootrsapubkey}, $new->{ip});
- $done->{$ip} = 1;
- }
- } else {
- print $fh $line; # copy line to new file
- }
- } else {
- print $fh $line; # copy line to new file
- }
- }
- close (ORG);
- }
- };
-
- foreach my $ni (@{$cinfo->{nodes}}) {
- if (!$done->{$ni->{ip}}) {
- $changes = 1;
- printf ($fh "ssh-rsa %s root\@%s\n", $ni->{rootrsapubkey}, $ni->{ip});
- $done->{$ni->{ip}} = 1;
- }
- }
- };
-
- $fh->close() if $fh;
-
- chmod (0600, $filename);
-
- # rewrite known hosts files
-
- $filename = '/root/.ssh/known_hosts';
-
- eval {
-
- $fh = PVE::AtomicFile->open($filename, "w");
-
- my $done = {};
-
- eval {
- if (open (ORG, "$filename")) {
- while (my $line = <ORG>) {
- if ($line =~ m/^\s*(\S+)\s+ssh-rsa\s+(\S+)\s*$/) {
- my ($ip, $key) = ($1, $2);
- my $new;
-
- foreach my $ni (@{$cinfo->{nodes}}) {
- $new = $ni if $ni->{ip} eq $ip;
- }
-
- if ($new) {
- if (!$done->{$ip}) {
- $changes = 1 if $key ne $new->{hostrsapubkey};
- printf ($fh "%s ssh-rsa %s\n", $new->{ip}, $new->{hostrsapubkey});
- $done->{$ip} = 1;
- }
- } else {
- print $fh $line; # copy line to new file
- }
- } else {
- print $fh $line; # copy line to new file
- }
- }
- close (ORG);
- }
- };
-
- foreach my $ni (@{$cinfo->{nodes}}) {
- if (!$done->{$ni->{ip}}) {
- $changes = 1;
- printf ($fh "%s ssh-rsa %s\n", $ni->{ip}, $ni->{hostrsapubkey});
- $done->{$ni->{ip}} = 1;
- }
- }
- };
-
- $fh->close() if $fh;
-
- return $changes;
-}
-
-sub cluster_sync_mastercfg {
- my ($cinfo, $syncip, $noreload) = @_;
-
- my $lip = $cinfo->{local}->{ip};
- my $lname = $cinfo->{local}->{name};
-
- my $cmpccfg;
- my $cmppvecfg;
- my $cmpqemucfg;
- my $cmpvzdump;
- my $cmpstoragecfg;
-
- my $storagecfg_old = PVE::Config::read_file ('storagecfg');
-
- if ($syncip ne $lip) {
-
- mkdir '/etc/pve/master';
- unlink </etc/pve/master/*>;
-
- my $cmd = ['rsync', '--rsh=ssh -l root -o BatchMode=yes', '-lpgoq',
- "$syncip:/etc/pve/* /etc/cron.d/vzdump", '/etc/pve/master/',
- '--exclude', '*~' ];
-
- eval {
- my $out = PVE::Utils::run_command ($cmd);
- };
-
- my $err = $@;
-
- if ($err) {
- my $cmdtxt = join (' ', @$cmd);
- die "syncing master configuration from '$syncip' failed ($cmdtxt) : $err\n";
- }
-
- # verify that the remote host is cluster master
-
- my $newcinfo = clusterinfo ('/etc/pve/master/cluster.cfg');
-
- if (!$newcinfo->{master} || ($newcinfo->{master}->{ip} ne $syncip)) {
- die "host '$syncip' is not cluster master\n";
- }
-
- if ($newcinfo->{local}->{role} ne 'N') {
- syslog ('info', "local host is no longer part of cluster '$syncip'");
- rename '/etc/pve/master/cluster.cfg', '/etc/pve/cluster.cfg';
- die "local host is no node of cluster '$syncip' " .
- "(role = $newcinfo->{local}->{role})\n";
- }
-
- # we are part of the cluster
-
- $cmpccfg = (system ("cmp -s /etc/pve/master/cluster.cfg /etc/pve/cluster.cfg") != 0)
- if -f '/etc/pve/master/cluster.cfg';
-
- rename '/etc/pve/master/cluster.cfg', '/etc/pve/cluster.cfg' if $cmpccfg;
-
- # check for storage changes
-
- if (-f '/etc/pve/master/storage.cfg') {
- $cmpstoragecfg = (system ("cmp -s /etc/pve/master/storage.cfg /etc/pve/storage.cfg") != 0);
- rename '/etc/pve/master/storage.cfg', '/etc/pve/storage.cfg' if $cmpstoragecfg;
- } else {
- unlink '/etc/pve/storage.cfg';
- }
-
- # check for vzdump crontab changes
-
- $cmpvzdump = (system ("cmp -s /etc/pve/master/vzdump /etc/cron.d/vzdump") != 0)
- if -f '/etc/pve/master/vzdump';
-
- # check for CA cerificate change
- if ((-f '/etc/pve/master/pve-root-ca.pem') && (-f '/etc/pve/master/pve-root-ca.key') &&
- (system ("cmp -s /etc/pve/master/pve-root-ca.pem /etc/pve/pve-root-ca.pem") != 0)) {
- rename '/etc/pve/master/pve-root-ca.pem', '/etc/pve/pve-root-ca.pem';
- rename '/etc/pve/master/pve-root-ca.key', '/etc/pve/pve-root-ca.key';
- my $serial = sprintf ("%04X000000000000", $newcinfo->{local}->{cid});
- update_serial ($serial);
- eval {
- # make sure we have a private key
- gen_pve_ssl_key();
- # force key rewrite
- gen_pve_ssl_cert (1, $newcinfo);
- };
- my $err = $@;
- if ($err) {
- syslog ('err', "pve key generation failed - try 'pcecert' manually");
- }
- }
-
- $cmppvecfg = (system ("cmp -s /etc/pve/master/pve.cfg /etc/pve/pve.cfg") != 0)
- if -f '/etc/pve/master/pve.cfg';
-
- rename '/etc/pve/master/pve.cfg', '/etc/pve/pve.cfg' if $cmppvecfg;
-
- $cmpqemucfg = (system ("cmp -s /etc/pve/master/qemu-server.cfg /etc/pve/qemu-server.cfg") != 0)
- if -f '/etc/pve/master/qemu-server.cfg';
-
- rename '/etc/pve/master/qemu-server.cfg', '/etc/pve/qemu-server.cfg' if $cmpqemucfg;
-
- #fixme: store/remove additional files
-
- }
-
- if ($cmpccfg || # cluster info changed
- ($syncip eq $lip)) { # or forced sync withe proxca -s
-
- if ($cmpccfg) {
- syslog ('info', "detected changed cluster config");
- }
-
- $cinfo = clusterinfo ();
-
- my $changes = rewrite_keys ($cinfo);
-
- if ($changes) {
- PVE::Utils::service_cmd ('sshd', 'reload');
- }
-
- PVE::Utils::service_cmd ('pvetunnel', 'reload') if !$noreload;
- }
-
- if ($cmppvecfg) { # pve.cfg settings changed
-
- # fixme: implement me
-
- }
-
- if ($cmpqemucfg) { # qemu-server.cfg settings changed
- # nothing to do
- }
-
- if ($cmpvzdump) {
- syslog ('info', "installing new vzdump crontab");
- rename '/etc/pve/master/vzdump', '/etc/cron.d/vzdump';
- }
-
- if ($cmpstoragecfg) {
- my $storagecfg_new = PVE::Config::read_file ('storagecfg');
-
- foreach my $sid (PVE::Storage::storage_ids ($storagecfg_old)) {
- my $ocfg = PVE::Storage::storage_config ($storagecfg_old, $sid);
- if (my $ncfg = PVE::Storage::storage_config ($storagecfg_new, $sid, 1)) {
- if (!$ocfg->{disable} && $ncfg->{disable}) {
- syslog ('info', "deactivate storage '$sid'");
- eval { PVE::Storage::deactivate_storage ($storagecfg_new, $sid); };
- syslog ('err', $@) if $@;
- }
- } else {
- if (!$ocfg->{disable}) {
- syslog ('info', "deactivate removed storage '$sid'");
- eval { PVE::Storage::deactivate_storage ($storagecfg_old, $sid); };
- syslog ('err', $@) if $@;
- }
- }
- }
- }
-}
-
-sub vzlist_update {
- my ($cid, $ticket) = @_;
-
- my $cinfo = clusterinfo ();
-
- my $vzlist;
-
- my $cvzl;
-
- my $conn = PVE::ConfigClient::connect ($ticket);
-
- my $ni;
- if (($ni = $cinfo->{"CID_$cid"})) {
- my $rcon = PVE::ConfigClient::connect ($ticket, $cinfo, $cid);
- $vzlist = $rcon->vzlist()->result;
- }
-
- if ($vzlist) {
- $cvzl = $conn->cluster_vzlist($cid, $vzlist)->result;
- }
-
- return $cvzl;
-}
-
-sub load_vmconfig {
- my ($cinfo, $cid, $veid, $type, $ticket) = @_;
-
- my $remcon = PVE::ConfigClient::connect ($ticket, $cinfo, $cid);
- my $vminfo = $remcon->vmconfig ($veid, $type)->result;
-
- if (!$vminfo) {
- die "unable to get configuration data for VEID '$veid'";
- }
-
- $vminfo->{ni} = $cinfo->{"CID_$cid"};
-
- return $vminfo;
-}
-
-sub sync_templates {
- my ($cinfo) = @_;
-
- if ($cinfo->{master} && ($cinfo->{master}->{cid} != $cinfo->{local}->{cid})) {
-
- my $remip = $cinfo->{master}->{ip};
-
- my $cmd = ['rsync', '--rsh=ssh -l root -o BatchMode=yes', '-aq',
- '--delete', '--bwlimit=10240',
- "$remip:/var/lib/vz/template", "/var/lib/vz" ];
-
- eval { PVE::Utils::run_command ($cmd); };
-
- my $err = $@;
-
- if ($err) {
- my $cmdtxt = join (' ', @$cmd);
- die "syncing template from master '$remip' failed ($cmdtxt) : $err\n";
- }
- }
-}
-
-sub get_nextid {
- my ($vzlist, $vmops) = @_;
-
- my $veexist = {};
-
- PVE::Utils::foreach_vmrec ($vzlist, sub {
- my ($cid, $vmid) = @_;
- $veexist->{$1} = 1;
- });
-
- PVE::Utils::foreach_vmrec ($vmops, sub {
- my ($cid, $vmid, $d) = @_;
- next if $d->{command} ne 'create';
- $veexist->{$1} = 1;
- });
-
- my $nextveid;
- for (my $i = 101; $i < 10000; $i++) {
- if (!$veexist->{$i}) {
- $nextveid = $i;
- last;
- }
- }
-
- return $nextveid;
-}
-
-1;
+++ /dev/null
-package PVE::Config;
-
-use strict;
-use IO::File;
-use IO::Dir;
-use PVE::AtomicFile;
-use File::stat;
-use File::Basename;
-use PVE::Utils;
-use Fcntl ':flock';
-use PVE::SafeSyslog;
-use Storable qw(dclone);
-use Getopt::Long;
-use Digest::SHA1;
-use Linux::Inotify2;
-use PVE::QemuServer;
-use PVE::Storage;
-use PVE::AccessControl;
-
-my $ccache;
-my $ccachemap;
-my $inotify;
-my $inotify_pid = 0;
-my $versions;
-
-# to enable cached operation, you need to call 'inotify_init'
-# inotify handles are a limited resource, so use with care (only
-# enable the cache if you really need it)
-
-# Note: please close the inotify handle after you fork
-
-my $shadowfiles = {
- '/etc/network/interfaces' => '/etc/network/interfaces.new',
-};
-
-
-sub soap_host_port {
- return ('127.0.0.1', 83);
-}
-
-my @zoneinfo;
-
-sub zoneinfo {
- if (@zoneinfo) {
- return @zoneinfo;
- }
-
- my $line;
-
- open (TMP, "</usr/share/zoneinfo/zone.tab");
-
- while ($line = <TMP>) {
- chomp $line;
- if (!($line =~ m|^[A-Z][A-Z]\s+\S+\s+(\S+)/(\S+).*|)) {
- next;
- }
-
- if ($1 && $2) {
- push @zoneinfo, "$1/$2";
- }
- }
-
- close (TMP);
-
- @zoneinfo = sort (@zoneinfo);
-
- return @zoneinfo;
-}
-
-my $bond_modes = { 'balance-rr' => 0,
- 'active-backup' => 1,
- 'balance-xor' => 2,
- 'broadcast' => 3,
- '802.3ad' => 4,
- 'balance-tlb' => 5,
- 'balance-alb' => 6,
- };
-
-sub get_bond_modes {
- return $bond_modes;
-}
-
-sub parse_netif {
- my $data = shift;
-
- my $res = {};
- foreach my $iface (split (/;/, $data)) {
- my $d = {};
- foreach my $pv (split (/,/, $iface)) {
- if ($pv =~ m/^(ifname|mac|bridge|host_ifname|host_mac)=(.+)$/) {
- $d->{$1} = $2;
- }
- }
- if ($d->{ifname}) {
- $d->{raw} = $data;
- $res->{$d->{ifname}} = $d;
- } else {
- die "unable to parse --netif value";
- }
- }
-
- return $res;
-}
-
-sub read_aplinfo {
- my ($filename, $fh, $update) = @_;
-
- local $/ = "";
-
- my $list = {};
-
- while (my $rec = <$fh>) {
- chomp $rec;
-
- my $res = {};
-
- while ($rec) {
-
- if ($rec =~ s/^Description:\s*([^\n]*)(\n\s+.*)*$//si) {
- $res->{headline} = $1;
- my $long = $2;
- $long =~ s/\n\s+/ /g;
- $long =~ s/^\s+//g;
- $long =~ s/\s+$//g;
- $res->{description} = $long;
- } elsif ($rec =~ s/^Version:\s*(.*\S)\s*\n//i) {
- my $version = $1;
- if ($version =~ m/^(\d[a-zA-Z0-9\.\+\-\:\~]*)-(\d+)$/) {
- $res->{version} = $version;
- } else {
- my $msg = "unable to parse appliance record: version = '$version'";
- $update ? die "$msg\n" : syslog ('err', $msg);
- }
- } elsif ($rec =~ s/^Type:\s*(.*\S)\s*\n//i) {
- my $type = $1;
- if ($type =~ m/^(openvz)$/) {
- $res->{type} = $type;
- } else {
- my $msg = "unable to parse appliance record: unknown type '$type'";
- $update ? die "$msg\n" : syslog ('err', $msg);
- }
- } elsif ($rec =~ s/^([^:]+):\s*(.*\S)\s*\n//) {
- $res->{lc $1} = $2;
- } else {
- my $msg = "unable to parse appliance record: $rec";
- $update ? die "$msg\n" : syslog ('err', $msg);
- $res = {};
- last;
- }
- }
-
- if ($res->{'package'} eq 'pve-web-news' && $res->{description}) {
- $list->{'all'}->{$res->{'package'}} = $res;
- next;
- }
-
- $res->{section} = 'unknown' if !$res->{section};
-
- if ($res->{'package'} && $res->{type} && $res->{os} && $res->{version} &&
- $res->{infopage}) {
- my $template;
- if ($res->{location}) {
- $template = $res->{location};
- $template =~ s|.*/([^/]+.tar.gz)|$1|;
- } else {
- $template = "$res->{os}-$res->{package}_$res->{version}_i386.tar.gz";
- $template =~ s/$res->{os}-$res->{os}-/$res->{os}-/;
- }
- $res->{template} = $template;
- $list->{$res->{section}}->{$template} = $res;
- $list->{'all'}->{$template} = $res;
- } else {
- my $msg = "found incomplete appliance records";
- $update ? die "$msg\n" : syslog ('err', $msg);
- }
- }
-
- return $list;
-}
-
-# we write /etc/host at startup - see pvesetup (we do not
-# dynamically update this file).
-# we use an host alias 'pvelocalhost' to mark the line we write/update.
-sub update_etc_hosts {
-
- my $hostname = PVE::Config::read_file ("hostname");
- my $rconf = PVE::Config::read_file ('resolvconf');
- my $ifaces = PVE::Config::read_file ("interfaces");
- my $localip = $ifaces->{vmbr0}->{address} || $ifaces->{eth0}->{address};
-
- my $domain = $rconf->{search};
-
- my $filename = "/etc/hosts";
- my $fh = IO::File->new($filename, "r") ||
- die "unable to open file '$filename' - $! :ERROR";
-
- my $outfh = PVE::AtomicFile->open($filename, "w") ||
- die "unable to open file '$filename' for writing - $! :ERROR";
-
- eval {
- my $line;
- while (defined ($line = <$fh>)) {
- chomp $line;
- if ($line =~ m/^\s*127.0.0.1\s/) {
- print $outfh "$line\n";
- print $outfh "$localip $hostname.$domain $hostname pvelocalhost\n";
- next;
- }
-
- if ($line =~ m/^\s*(\d+\.\d+\.\d+\.\d+\s+.*\S)\s*/) {
- my $found = 0;
- foreach my $n (split (/\s+/, $1)) {
- my $e = lc ($n);
- if ($e eq lc ($hostname) ||
- $e eq lc ($localip) ||
- $e eq 'pvelocalhost') {
- $found = 1;
- last;
- }
- }
- next if $found;
- }
-
- print $outfh "$line\n";
- }
-
- $fh->close();
-
- $outfh->close(1);
- };
-
- my $err = $@;
-
- die $err if $err;
-}
-
-sub get_qmconfig {
- my $vmid = shift;
-
- return read_file ("/etc/qemu-server/$vmid.conf");
-}
-
-sub get_veconfig {
- my $veid = shift;
-
- return read_file ("/etc/vz/conf/$veid.conf");
-}
-
-sub read_qmconfig {
- my ($filename, $fh) = @_;
-
- $filename =~ m|/(\d+)\.conf$|
- || die "got strange filename '$filename'";
-
- my $storecfg = read_file ("storagecfg");
-
- return PVE::QemuServer::parse_config ($filename, $fh, $storecfg);
-}
-
-sub read_vzconfig {
- my ($filename, $fh) = @_;
-
- $filename =~ m|/(\d+)\.conf$|
- || die "got strange filename '$filename'";
-
- my $data = {};
- while (defined (my $line = <$fh>)) {
- next if $line =~ m/^#/;
- next if $line =~ m/^\s*$/;
-
- if ($line =~ m/^\s*([A-Z][A-Z0-9_]*)\s*=\s*\"(.*)\"\s*$/i) {
- my $name = lc ($1);
- my $text = $2;
-
- if ($text =~ m/^(\d+):(\d+)$/) {
- my $bar = $1;
- my $lim = $2;
-
- $data->{$name}->{bar} = $bar;
- $data->{$name}->{lim} = $lim;
- } else {
- $data->{$name}->{value} = $text;
- }
- } else {
- die "unable to parse config line: $line\n";
- }
- }
-
- return $data;
-}
-
-sub read_rsapubkey {
- my ($filename, $fh) = @_;
-
- my $line;
-
- 1 while (defined ($line = <$fh>) && ($line !~ m/^.*ssh-rsa\s/));
-
- my $rsapubkey = $line;
-
- $rsapubkey =~ s/^.*ssh-rsa\s+//i;
- $rsapubkey =~ s/\s+root\@\S+\s*$//i;
- $rsapubkey =~ s/\s+$//;
-
- die "strange key format - not base64 encoded"
- if $rsapubkey !~ m/^[A-Za-z0-9\+\/]+={0,2}$/;
-
- die "unable to read '$filename'" if !$rsapubkey;
-
- return $rsapubkey;
-}
-
-sub read_pcounter {
- my ($filename, $fh) = @_;
-
- my $res = {};
-
- my $line;
-
- while (defined ($line = <$fh>)) {
- chomp $line;
- next if $line =~ m/^\s*$/;
-
- if ($line =~ m/^counter:(\S+):(\d+):$/) {
- $res->{$1} = $2;
- } else {
- syslog ('err', "warning: unable to parse file '$filename'");
- }
- }
-
- return $res;
-}
-
-sub write_pcounter {
- my ($filename, $fh, $data) = @_;
-
- foreach my $cn (keys %$data) {
- print $fh "counter:$cn:$data->{$cn}:\n";
- }
-
- return $data;
-}
-
-sub update_pcounter {
- my ($filename, $data, $counter) = @_;
-
- $data->{$counter}++;
-
- return $data;
-}
-
-sub read_var_lib_vmops {
- my ($filename, $fh) = @_;
-
- my $line;
-
- my $res = {};
-
- while (defined ($line = <$fh>)) {
- chomp $line;
-
- my $upid_hash;
-
- if (($upid_hash = PVE::Utils::upid_decode ($line)) &&
- $upid_hash->{type} eq 'vmops') {
- my $cid = $upid_hash->{cid};
- my $veid = $upid_hash->{veid};
- $res->{"CID_$cid"}->{"VEID_$veid"} = $upid_hash;
- }
- }
-
- return $res;
-}
-
-sub write_var_lib_vmops {
- my ($filename, $fh, $data) = @_;
-
- foreach my $ckey (sort keys %$data) {
- next if $ckey !~ m/^CID_(\d+)$/;
- my $cid = $1;
- my $vzl = $data->{$ckey};
-
- foreach my $vekey (sort keys %$vzl) {
- next if $vekey !~ m/^VEID_(\d+)$/;
- my $veid = $1;
-
- my $upid = PVE::Utils::upid_encode ($vzl->{$vekey});
- print $fh "$upid\n";
- }
- }
-
- return $data;
-}
-
-sub update_var_lib_vmops {
- my ($filename, $vmops, $upid) = @_;
-
- if (my $upid_hash = PVE::Utils::upid_decode ($upid)) {
- my $cid = $upid_hash->{cid};
- my $veid = $upid_hash->{veid};
- $vmops->{"CID_$cid"}->{"VEID_$veid"} = $upid_hash;
- }
-
- return $vmops;
-}
-
-sub read_var_lib_vzlist {
- my ($filename, $fh) = @_;
-
- my $line;
-
- my $res = {};
-
- my $cid;
-
- while (defined ($line = <$fh>)) {
- chomp $line;
-
- next if $line =~ m/^\#/; # skip comments
- next if $line =~ m/^\s*$/; # skip empty lines
-
- if ($line =~ m/^CID:(\d+):(\d+):(\d+):\S*$/) {
- $cid = $1;
- $res->{"CID_$cid"}->{lasttime} = $2;
- $res->{"CID_$cid"}->{version} = $3;
- next;
- }
-
- if (!defined ($cid)) {
- warn "unable to parse line - undefined cluster ID: $line";
- }
-
- if ($line =~ m/^(\d+):([a-z]+):(\d+):(\S+):(\S+):(\S+):(\d+):(\d+):(\d+):(\d+):(\d+):(\d+):(\d+):$/) {
- my $d = {};
- $d->{type} = $2;
- $d->{nproc} = $3;
- $d->{status} = $4;
- $d->{ip} = $5;
- $d->{name} = $6;
- $d->{mem} = $7;
- $d->{maxmem} = $8;
- $d->{disk} = $9;
- $d->{maxdisk} = $10;
- $d->{pctcpu} = $11;
- $d->{uptime} = $12;
- $d->{relcpu} = $13;
-
- $res->{"CID_$cid"}->{"VEID_$1"} = $d;
- } else {
- warn "unable to parse line: $line";
- }
- }
-
- return $res;
-}
-
-sub write_var_lib_vzlist {
- my ($filename, $fh, $data) = @_;
-
- print $fh "# Cluster wide VZ status\n\n";
-
- foreach my $ckey (sort keys %$data) {
- next if $ckey !~ m/^CID_(\d+)$/;
- my $cid = $1;
- my $vzl = $data->{$ckey};
-
- print $fh "CID:$cid:$vzl->{lasttime}:$vzl->{version}:\n";
-
- foreach my $vekey (sort keys %$vzl) {
- my $d = $vzl->{$vekey};
- next if $vekey !~ m/^VEID_(\d+)$/;
- my $veid = $1;
-
- print $fh "$veid:$d->{type}:$d->{nproc}:$d->{status}:$d->{ip}:$d->{name}:" .
- "$d->{mem}:$d->{maxmem}:$d->{disk}:$d->{maxdisk}:$d->{pctcpu}:$d->{uptime}:$d->{relcpu}:\n";
- }
-
- print $fh "\n";
- }
-
- return $data;
-}
-
-sub update_var_lib_vzlist {
- my ($filename, $vzlist, $data, $cid) = @_;
-
- my $old = $vzlist->{"CID_$cid"};
-
- if ($old) {
-
- # only update if record is newer:
- # record is considered newer if either version or lastime is newer
- # (skip update when version is older and lastime ins older)
-
- if (($old->{version} > $data->{version}) &&
- ($old->{lasttime} >= $data->{lasttime})) {
- return;
- }
- }
-
- my $ckey = "CID_$cid";
-
- if (!$data->{qemu}) {
- # record does not contain info about qemu, so copy them
- my $vzl = $vzlist->{$ckey};
- foreach my $vekey (keys %$vzl) {
- my $d = $vzl->{$vekey};
- next if $vekey !~ m/^VEID_(\d+)$/;
- next if $d->{type} ne 'qemu';
- next if defined ($data->{$vekey}); # already defined ?
- $data->{$vekey} = $d;
- }
- }
-
- if (!$data->{openvz}) {
- # record does not contain info about openvz, so copy them
- my $vzl = $vzlist->{$ckey};
- foreach my $vekey (keys %$vzl) {
- my $d = $vzl->{$vekey};
- next if $vekey !~ m/^VEID_(\d+)$/;
- next if $d->{type} ne 'openvz';
- next if defined ($data->{$vekey}); # already defined ?
- $data->{$vekey} = $d;
- }
- }
-
- $vzlist->{$ckey} = $data;
-
- # remove non-existing cluster nodes
- my $ccfg = read_file ("clustercfg");
- PVE::Utils::foreach_cid ($vzlist, sub {
- my ($cid, undef, $ckey) = @_;
- if ($ccfg) {
- delete $vzlist->{$ckey} if !defined ($ccfg->{$ckey});
- } else {
- delete $vzlist->{$ckey} if $cid != 0;
- }
- });
-
- return $vzlist;
-}
-
-
-sub read_var_lib_syncstatus {
- my ($filename, $fh) = @_;
-
- my $line;
-
- my $res = {};
-
- while (defined ($line = <$fh>)) {
- chomp $line;
-
- next if $line =~ m/^\#/; # skip comments
- next if $line =~ m/^\s*$/; # skip empty lines
-
- if ($line =~ m/^(\d+):(\d+):$/) {
- $res->{$1}->{lastsync} = $2;
- }
- }
-
- return $res;
-}
-
-sub write_var_lib_syncstatus {
- my ($filename, $fh, $data) = @_;
-
- print $fh "# Cluster sync status (CID:TIME:)\n\n";
-
- foreach my $cid (keys %$data) {
- my $stime = $data->{$cid}->{lastsync};
- print $fh "$cid:$stime:\n";
- }
-
- return $data;
-}
-
-sub read_etc_hostname {
- my ($filename, $fd) = @_;
-
- my $hostname = <$fd>;
-
- chomp $hostname;
-
- return $hostname;
-}
-
-sub write_etc_hostname {
- my ($filename, $fh, $hostname) = @_;
-
- print $fh "$hostname\n";
-
- return $hostname;
-}
-
-sub read_root_dotforward {
- my ($filename, $fh) = @_;
-
- my $line;
- while (defined ($line = <$fh>)) {
- chomp $line;
- next if $line =~ m/^\s*$/;
- return $line;
- }
-
- return undef;
-}
-
-sub write_root_dotforward {
- my ($filename, $fh, $mailto) = @_;
-
- print $fh "$mailto\n";
-
- return $mailto;
-}
-
-sub read_etc_pve_cfg {
- my ($filename, $fh) = @_;
-
- my $line;
-
- my $res = {};
-
- while (defined ($line = <$fh>)) {
- chomp $line;
- next if $line =~ m/^\#/; # skip comments
- next if $line =~ m/^\s*$/; # skip empty lines
-
- if ($line =~ m/^([^\s:]+):\s*(.*\S)\s*$/) {
- $res->{lc($1)} = $2;
- }
-
- }
-
- return $res;
-}
-
-sub write_etc_pve_cfg {
- my ($filename, $fh, $data) = @_;
-
- return if !$data;
-
- foreach my $k (keys %$data) {
- print $fh "$k: $data->{$k}\n";
- }
-
- return $data;
-}
-
-sub read_etc_pve_storagecfg {
- my ($filename, $fh) = @_;
-
- return PVE::Storage::parse_config ($filename, $fh);
-}
-
-sub read_etc_pve_qemu_server_cfg {
- my ($filename, $fh) = @_;
-
- my $line;
-
- my $res = {};
-
- while (defined ($line = <$fh>)) {
- chomp $line;
- next if $line =~ m/^\#/; # skip comments
- next if $line =~ m/^\s*$/; # skip empty lines
-
- if ($line =~ m/^([^\s:]+):\s*(.*\S)\s*$/) {
- $res->{lc($1)} = $2;
- }
-
- }
-
- return $res;
-}
-
-sub write_etc_pve_qemu_server_cfg {
- my ($filename, $fh, $data) = @_;
-
- return if !$data;
-
- foreach my $k (keys %$data) {
- print $fh "$k: $data->{$k}\n";
- }
-
- return $data;
-}
-
-sub read_etc_timezone {
- my ($filename, $fd) = @_;
-
- my $timezone = <$fd>;
-
- chomp $timezone;
-
- return $timezone;
-}
-
-sub write_etc_timezone {
- my ($filename, $fh, $timezone) = @_;
-
- print $fh "$timezone\n";
-
- unlink ("/etc/localtime");
- symlink ("/usr/share/zoneinfo/$timezone", "/etc/localtime");
-
- return $timezone;
-}
-
-sub __dowhash_to_dow {
- my ($d, $num) = @_;
-
- my @da = ();
- push @da, $num ? 1 : 'mon' if $d->{mon};
- push @da, $num ? 2 : 'tue' if $d->{tue};
- push @da, $num ? 3 : 'wed' if $d->{wed};
- push @da, $num ? 4 : 'thu' if $d->{thu};
- push @da, $num ? 5 : 'fri' if $d->{fri};
- push @da, $num ? 6 : 'sat' if $d->{sat};
- push @da, $num ? 7 : 'sun' if $d->{sun};
-
- return join ',', @da;
-}
-
-sub update_etc_crond_vzdump {
- my ($filename, $jobs, $data) = @_;
-
- my $digest = $data->{digest};
-
- my $verify = 0;
- foreach my $jid (keys %$data) {
- next if $jid !~ m/^JOB\d+$/;
- $verify = 1 if defined ($jobs->{$jid});
- my $d = $data->{$jid};
- if (!$d) {
- delete $jobs->{$jid};
- } else {
- $jobs->{$jid} = $d;
- }
- }
- if ($verify && (!$digest || ($digest ne $jobs->{digest}))) {
- die "unable to update a modified file '$filename'\n";
- }
-
- return $jobs;
-}
-
-sub read_etc_crond_vzdump {
- my ($filename, $fh) = @_;
-
- my $line;
-
- my $jid = 1; # we start at 1
- my $ejid = 0;
-
- my $sha1 = Digest::SHA1->new;
-
- my $res = {};
-
- my $dowmap = {mon => 1, tue => 2, wed => 3, thu => 4,
- fri => 5, sat => 6, sun => 7};
- my $rdowmap = { '1' => 'mon', '2' => 'tue', '3' => 'wed', '4' => 'thu',
- '5' => 'fri', '6' => 'sat', '7' => 'sun', '0' => 'sun'};
-
- while (defined ($line = <$fh>)) {
- $sha1->add ($line); # compute digest
- chomp $line;
- next if $line =~ m/^\s*$/;
- next if $line =~ m/^\#/;
- next if $line =~ m/^PATH\s*=/; # we always overwrite path
-
- my $d;
- my $err;
-
- if ($line =~ m|^(\d+)\s+(\d+)\s+\*\s+\*\s+(\S+)\s+root\s+(/\S+/)?vzdump(\s+(.*))?$|) {
-
- eval {
- $d->{minute} = $1;
- $d->{hour} = $2;
- my $dow = $3;
- my $param = $6;
-
- # convenient startime can be used to sort jobs
- $d->{starttime} = sprintf ("%02d:%02d", $d->{hour}, $d->{minute});
-
- $dow = '1,2,3,4,5,6,7' if $dow eq '*';
-
- foreach my $day (split (/,/, $dow)) {
- if ($day =~ m/^(mon|tue|wed|thu|fri|sat|sun)-(mon|tue|wed|thu|fri|sat|sun)$/i) {
- for (my $i = $dowmap->{lc($1)}; $i <= $dowmap->{lc($2)}; $i++) {
- my $r = $rdowmap->{$i};
- $d->{$r} = 1;
- }
-
- } elsif ($day =~ m/^(mon|tue|wed|thu|fri|sat|sun|[0-7])$/i) {
- $day = $rdowmap->{$day} if $day =~ m/\d/;
- $d->{lc($day)} = 1;
- } else {
- die "unable to parse day of week '$dow' in '$filename'\n";
- $err = 1;
- }
- }
-
- my $opt_all;
- my $opt_exclude_path;
- my $opt_compress = 0;
- my $opt_dumpdir;
- my $opt_storage;
- my $opt_mailto;
- my $opt_stop;
- my $opt_suspend;
- my $opt_snap;
- my $opt_node;
- my $opt_quiet;
-
- local @ARGV = split /\s+/, $param;
- if (!GetOptions ('all' => \$opt_all,
- 'compress' => \$opt_compress,
- 'mailto=s@' => \$opt_mailto,
- 'stop' =>\$opt_stop,
- 'suspend' =>\$opt_suspend,
- 'snapshot' =>\$opt_snap,
- 'quiet' =>\$opt_quiet,
- 'node=i' =>\$opt_node,
- 'storage=s' =>\$opt_storage,
- 'dumpdir=s' => \$opt_dumpdir)) {
-
- die "unable to parse vzdump options in '$filename'\n";
- } else {
- if ($opt_snap) {
- $d->{mode} = 'snapshot';
- } elsif ($opt_suspend) {
- $d->{mode} = 'suspend';
- } elsif ($opt_stop) {
- $d->{mode} = 'stop';
- }
-
- $d->{compress} = $opt_compress;
- $d->{dumpdir} = $opt_dumpdir;
- $d->{storage} = $opt_storage;
- $d->{includeall} = $opt_all;
- $d->{mailto} = $opt_mailto ? join (' ', @$opt_mailto) : '';
- $d->{node} = $opt_node || 0;
-
- my $vmlist = '';
- foreach my $vmid (@ARGV) {
- if ($vmid =~ m/^\d+$/) {
- $vmlist .= $vmlist ? " $vmid" : $vmid;
- } else {
- die "unable to parse vzdump options in '$filename'\n";
- }
-
- }
-
- $d->{vmlist} = $vmlist;
- }
-
- $d->{param} = $param;
-
- $d->{dow} = __dowhash_to_dow ($d);
-
- $res->{"JOB$jid"} = $d;
- };
-
- my $err = $@;
-
-
- if ($err) {
- syslog ('err', "warning: $err");
-
- $res->{"EJOB$ejid"} = { line => $line };
- $ejid++;
-
- } else {
- $jid++;
- }
- } elsif ($line =~ m|^\S+\s+(\S+)\s+\S+\s+\S+\s+\S+\s+\S+\s+(\S.*)$|) {
- syslog ('err', "warning: malformed line in '$filename'");
- $res->{"EJOB$ejid"} = { line => $line };
- $ejid++;
- } else {
- syslog ('err', "ignoring malformed line in '$filename'");
- }
- }
-
- $res->{digest} = $sha1->hexdigest;
-
- return $res;
-}
-
-sub write_etc_crond_vzdump {
- my ($filename, $fh, $data) = @_;
-
- print $fh "# Atomatically generated file - do not edit\n\n";
-
- print $fh "PATH=\"/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin\"\n\n";
-
- my @jids;
-
- foreach my $jid (keys %$data) {
- next if $jid !~ m/^JOB\d+$/;
- my $d = $data->{$jid};
- next if !$d;
- push @jids, $jid;
- $d->{starttime} = sprintf ("%02d:%02d", $d->{hour}, $d->{minute}); # used to sort
-
- my $dow;
- if ($d->{mon} && $d->{tue} && $d->{wed} && $d->{thu} &&
- $d->{fri} && $d->{sat} && $d->{sun}) {
- $dow = '*';
- } else {
- $dow = __dowhash_to_dow ($d, 1);
- }
-
- $dow = '*' if !$dow;
-
- $d->{dow} = $dow;
-
- my $param = '--quiet';
- $param .= " --node $d->{node}" if $d->{node};
- $param .= " --$d->{mode}" if $d->{mode};
- $param .= " --compress" if $d->{compress};
- $param .= " --dumpdir $d->{dumpdir}" if $d->{dumpdir};
- $param .= " --storage $d->{storage}" if $d->{storage};
-
- if (my $mailto = $d->{mailto}) {
- $mailto =~ s/[,;]/ /g;
- foreach my $ma (split (/\s+/, $mailto)) {
- $param .= " --mailto $ma";
- }
- }
-
- $param .= " --all" if $d->{includeall};
- $param .= " $d->{vmlist}" if $d->{vmlist};
-
- $d->{param} = $param;
- }
-
- my $found = 0;
- foreach my $jid (sort { ($data->{$a}->{node} <=> $data->{$b}->{node}) ||
- ($data->{$a}->{starttime} cmp $data->{$b}->{starttime}) ||
- ($data->{$a}->{dow} cmp $data->{$b}->{dow}) ||
- ($data->{$a}->{param} cmp $data->{$b}->{param})} @jids) {
-
- my $d = $data->{$jid};
-
- printf $fh "$d->{minute} $d->{hour} * * %-11s root vzdump $d->{param}\n", $d->{dow};
- $found = 1;
- }
-
- print $fh "\n" if $found;
-
- $found = 0;
- foreach my $jid (keys %$data) {
- next if $jid !~ m/^EJOB\d+$/;
- my $d = $data->{$jid};
- next if !$d || !$d->{line};
- print $fh "$d->{line}\n";
- $found = 1;
- }
-
- print $fh "\n" if $found;
-
- return $data;
-}
-
-sub read_etc_network_interfaces {
- my ($filename, $fh) = @_;
-
- my $ifaces = {};
-
- my $line;
-
- my $fd2;
-
- if ($fd2 = IO::File->new ("/proc/net/dev", "r")) {
- while (defined ($line = <$fd2>)) {
- chomp ($line);
- if ($line =~ m/^\s*(eth[0-9]):.*/) {
- $ifaces->{$1}->{exists} = 1;
- }
- }
- close ($fd2);
- }
-
- # always add the vmbr0 bridge device
- $ifaces->{vmbr0}->{exists} = 1;
-
- if ($fd2 = IO::File->new ("/proc/net/if_inet6", "r")) {
- while (defined ($line = <$fd2>)) {
- chomp ($line);
- if ($line =~ m/^[a-f0-9]{32}\s+[a-f0-9]{2}\s+[a-f0-9]{2}\s+[a-f0-9]{2}\s+[a-f0-9]{2}\s+(eth\d+|vmbr\d+|bond\d+)$/) {
- $ifaces->{$1}->{active} = 1;
- }
- }
- close ($fd2);
- }
-
- my $gateway = 0;
-
- while (defined ($line = <$fh>)) {
- chomp ($line);
- next if $line =~ m/^#/;
-
- if ($line =~ m/^auto\s+(.*)$/) {
- my @aa = split (/\s+/, $1);
-
- foreach my $a (@aa) {
- $ifaces->{$a}->{autostart} = 1;
- }
-
- } elsif ($line =~ m/^iface\s+(\S+)\s+inet\s+(\S+)\s*$/) {
- my $i = $1;
- $ifaces->{$i}->{type} = $2;
- while (defined ($line = <$fh>) && ($line =~ m/^\s+((\S+)\s+(.+))$/)) {
- my $option = $1;
- my ($id, $value) = ($2, $3);
- if (($id eq 'address') || ($id eq 'netmask') || ($id eq 'broadcast')) {
- $ifaces->{$i}->{$id} = $value;
- } elsif ($id eq 'gateway') {
- $ifaces->{$i}->{$id} = $value;
- $gateway = 1;
- } elsif ($id eq 'slaves') {
- foreach my $p (split (/\s+/, $value)) {
- next if $p eq 'none';
- $ifaces->{$i}->{$id}->{$p} = 1;
- }
- } elsif ($id eq 'bridge_ports') {
- foreach my $p (split (/\s+/, $value)) {
- next if $p eq 'none';
- $ifaces->{$i}->{$id}->{$p} = 1;
- }
- } elsif ($id eq 'bridge_stp') {
- if ($value =~ m/^\s*(on|yes)\s*$/i) {
- $ifaces->{$i}->{$id} = 'on';
- } else {
- $ifaces->{$i}->{$id} = 'off';
- }
- } elsif ($id eq 'bridge_fd') {
- $ifaces->{$i}->{$id} = $value;
- } elsif ($id eq 'bond_miimon') {
- $ifaces->{$i}->{$id} = $value;
- } elsif ($id eq 'bond_mode') {
- # always use names
- foreach my $bm (keys %$bond_modes) {
- my $id = $bond_modes->{$bm};
- if ($id eq $value) {
- $value = $bm;
- last;
- }
- }
- $ifaces->{$i}->{$id} = $value;
- } else {
- push @{$ifaces->{$i}->{options}}, $option;
- }
- }
- }
- }
-
- if (!$gateway) {
- $ifaces->{vmbr0}->{gateway} = '';
- }
-
- if (!$ifaces->{lo}) {
- $ifaces->{lo}->{type} = 'loopback';
- $ifaces->{lo}->{autostart} = 1;
- }
-
- foreach my $iface (keys %$ifaces) {
- if ($iface =~ m/^bond\d+$/) {
-
- } elsif ($iface =~ m/^vmbr\d+$/) {
- if (!defined ($ifaces->{$iface}->{bridge_fd})) {
- $ifaces->{$iface}->{bridge_fd} = 0;
- }
- if (!defined ($ifaces->{$iface}->{bridge_stp})) {
- $ifaces->{$iface}->{bridge_stp} = 'off';
- }
- } elsif ($iface =~ m/^(\S+):\d+$/) {
- if (defined ($ifaces->{$1})) {
- $ifaces->{$iface}->{exists} = $ifaces->{$1}->{exists};
- } else {
- $ifaces->{$1}->{exists} = 0;
- $ifaces->{$iface}->{exists} = 0;
- }
- }
-
- $ifaces->{$iface}->{type} = 'manual' if !$ifaces->{$iface}->{type};
- }
-
- return $ifaces;
-}
-
-sub __print_interface {
- my ($fh, $ifaces, $iface) = @_;
-
- return if !$ifaces->{$iface}->{type};
-
- if ($ifaces->{$iface}->{autostart}) {
- print $fh "auto $iface\n";
- }
- print $fh "iface $iface inet $ifaces->{$iface}->{type}\n";
- print $fh "\taddress $ifaces->{$iface}->{address}\n" if $ifaces->{$iface}->{address};
- print $fh "\tnetmask $ifaces->{$iface}->{netmask}\n" if $ifaces->{$iface}->{netmask};
- print $fh "\tgateway $ifaces->{$iface}->{gateway}\n" if $ifaces->{$iface}->{gateway};
- print $fh "\tbroadcast $ifaces->{$iface}->{broadcast}\n" if $ifaces->{$iface}->{broadcast};
-
- if ($ifaces->{$iface}->{bridge_ports} || ($iface =~ m/^vmbr\d+$/)) {
- my $ports;
- if ($ifaces->{$iface}->{bridge_ports}) {
- $ports = join (' ', sort keys %{$ifaces->{$iface}->{bridge_ports}});
- }
- $ports = 'none' if !$ports;
- print $fh "\tbridge_ports $ports\n";
- }
-
- if ($ifaces->{$iface}->{bridge_stp} || ($iface =~ m/^vmbr\d+$/)) {
- my $v = $ifaces->{$iface}->{bridge_stp};
- $v = defined ($v) ? $v : 'off';
- print $fh "\tbridge_stp $v\n";
- }
-
- if (defined ($ifaces->{$iface}->{bridge_fd}) || ($iface =~ m/^vmbr\d+$/)) {
- my $v = $ifaces->{$iface}->{bridge_fd};
- $v = defined ($v) ? $v : 0;
- print $fh "\tbridge_fd $v\n";
- }
-
- if ($ifaces->{$iface}->{slaves} || ($iface =~ m/^bond\d+$/)) {
- my $slaves;
- if ($ifaces->{$iface}->{slaves}) {
- $slaves = join (' ', sort keys %{$ifaces->{$iface}->{slaves}});
- }
- $slaves = 'none' if !$slaves;
- print $fh "\tslaves $slaves\n";
- }
-
- if (defined ($ifaces->{$iface}->{'bond_miimon'}) || ($iface =~ m/^bond\d+$/)) {
- my $v = $ifaces->{$iface}->{'bond_miimon'};
- $v = defined ($v) ? $v : 100;
- print $fh "\tbond_miimon $v\n";
- }
-
- if (defined ($ifaces->{$iface}->{'bond_mode'}) || ($iface =~ m/^bond\d+$/)) {
- my $v = $ifaces->{$iface}->{'bond_mode'};
- $v = defined ($v) ? $v : 'balance-rr';
- print $fh "\tbond_mode $v\n";
- }
-
- foreach my $option (@{$ifaces->{$iface}->{options}}) {
- print $fh "\t$option\n";
- }
-
- print $fh "\n";
-}
-
-sub write_etc_network_interfaces {
- my ($filename, $fh, $ifaces) = @_;
-
- print $fh "# network interface settings\n";
-
- foreach my $iface (keys %$ifaces) {
- delete ($ifaces->{$iface}->{printed});
- }
-
- foreach my $t (('lo', 'eth', '')) {
- foreach my $iface (sort keys %$ifaces) {
- next if $ifaces->{$iface}->{printed};
- next if $iface !~ m/^$t/;
- $ifaces->{$iface}->{printed} = 1;
- __print_interface ($fh, $ifaces, $iface);
- }
- }
-
- return $ifaces;
-}
-
-sub read_etc_resolv_conf {
- my ($filename, $fh) = @_;
-
- my $res = {};
-
- while (my $line = <$fh>) {
- chomp $line;
- if ($line =~ m/^search\s+(\S+)\s*/) {
- $res->{search} = $1;
- } elsif ($line =~ m/^nameserver\s+(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\s*/) {
- push @{$res->{nameservers}}, $1;
- }
- }
-
- return $res;
-}
-
-sub write_etc_resolv_conf {
- my ($filename, $fh, $resolv) = @_;
-
- print $fh "search $resolv->{search}\n";
-
- my $written = {};
- my $nslist = [];
-
- foreach my $ns (@{$resolv->{nameservers}}) {
- if ($ns ne '0.0.0.0' && !$written->{$ns}) {
- $written->{$ns} = 1;
- print $fh "nameserver $ns\n";
- push @$nslist, $ns;
- }
- }
-
- $resolv->{nameservers} = $nslist;
- return $resolv;
-}
-
-sub ccache_default_writer {
- my ($filename, $data) = @_;
-
- die "undefined config writer for '$filename' :ERROR";
-}
-
-sub ccache_default_parser {
- my ($filename, $srcfd) = @_;
-
- die "undefined config reader for '$filename' :ERROR";
-}
-
-sub ccache_compute_diff {
- my ($filename, $shadow) = @_;
-
- my $diff = '';
-
- open (TMP, "diff -b -N -u '$filename' '$shadow'|");
-
- while (my $line = <TMP>) {
- $diff .= $line;
- }
-
- close (TMP);
-
- $diff = undef if !$diff;
-
- return $diff;
-}
-
-sub write_file {
- my ($filename, $data, $full) = @_;
-
- $filename = $ccachemap->{$filename} if defined ($ccachemap->{$filename});
-
- die "file '$filename' not added :ERROR" if !defined ($ccache->{$filename});
-
- my $writer = $ccache->{$filename}->{writer};
-
- my $realname = $filename;
-
- my $shadow;
- if ($shadow = $shadowfiles->{$filename}) {
- $realname = $shadow;
- }
-
- my $fh = PVE::AtomicFile->open($realname, "w") ||
- die "unable to open file '$realname' for writing - $! :ERROR";
-
- my $res;
-
- eval {
- $res = &$writer ($filename, $fh, $data);
- };
-
- $ccache->{$filename}->{version} = undef;
-
- my $err = $@;
- $fh->detach() if $err;
- $fh->close(1);
-
- die $err if $err;
-
- my $diff;
- if ($shadow && $full) {
- $diff = ccache_compute_diff ($filename, $shadow);
- }
-
- if ($full) {
- return { data => $res, changes => $diff };
- }
-
- return $res;
-}
-
-sub update_file {
- my ($filename, $data, @args) = @_;
-
- $filename = $ccachemap->{$filename} if defined ($ccachemap->{$filename});
-
- my $update = $ccache->{$filename}->{update};
-
- die "unable to update/merge data" if !$update;
-
- my $lkfn = "$filename.lock";
-
- if (!open (FLCK, ">>$lkfn")) {
- die "unable to open lock file '$lkfn' - $?";
- }
-
- if (!flock (FLCK, LOCK_EX)) {
- close (FLCK);
- die "unable to aquire lock for file '$lkfn' - $?";
- }
-
- my $newdata;
-
- eval {
-
- my $olddata = read_file ($filename);
-
- if ($data) {
- my $res = &$update ($filename, $olddata, $data, @args);
- if (defined ($res)) {
- $newdata = write_file ($filename, $res);
- } else {
- $newdata = $olddata;
- }
- } else {
- $newdata = $olddata;
- }
- };
-
- my $err = $@;
-
- close (FLCK);
-
- die $err if $err;
-
- return $newdata;
-}
-
-sub discard_changes {
- my ($filename, $full) = @_;
-
- $filename = $ccachemap->{$filename} if defined ($ccachemap->{$filename});
-
- die "file '$filename' not added :ERROR" if !defined ($ccache->{$filename});
-
- if (my $copy = $shadowfiles->{$filename}) {
- unlink $copy;
- }
-
- return read_file ($filename, $full);
-}
-
-sub read_file {
- my ($filename, $full) = @_;
-
- my $parser;
-
- if ($filename =~ m|^/etc/qemu-server/\d+\.conf$|) {
- $parser = \&read_qmconfig;
- } elsif ($filename =~ m|^/etc/vz/conf/\d+\.conf$|) {
- $parser = \&read_vzconfig;
- } else {
- $filename = $ccachemap->{$filename} if defined ($ccachemap->{$filename});
-
- die "file '$filename' not added :ERROR" if !defined ($ccache->{$filename});
-
- $parser = $ccache->{$filename}->{parser};
- }
-
- my $fd;
- my $shadow;
-
- poll() if $inotify; # read new inotify events
-
- $versions->{$filename} = 0 if !defined ($versions->{$filename});
-
- my $cver = $versions->{$filename};
-
- if (my $copy = $shadowfiles->{$filename}) {
- if ($fd = IO::File->new ($copy, "r")) {
- $shadow = $copy;
- } else {
- $fd = IO::File->new ($filename, "r");
- }
- } else {
- $fd = IO::File->new ($filename, "r");
- }
-
- my $acp = $ccache->{$filename}->{always_call_parser};
-
- if (!$fd) {
- $ccache->{$filename}->{version} = undef;
- $ccache->{$filename}->{data} = undef;
- $ccache->{$filename}->{diff} = undef;
- return undef if !$acp;
- }
-
- my $noclone = $ccache->{$filename}->{noclone};
-
- # file unchanged?
- if (!$ccache->{$filename}->{nocache} &&
- $inotify && $versions->{$filename} &&
- defined ($ccache->{$filename}->{data}) &&
- defined ($ccache->{$filename}->{version}) &&
- ($ccache->{$filename}->{readonce} ||
- ($ccache->{$filename}->{version} == $versions->{$filename}))) {
-
- my $ret;
- if (!$noclone && ref ($ccache->{$filename}->{data})) {
- $ret->{data} = dclone ($ccache->{$filename}->{data});
- } else {
- $ret->{data} = $ccache->{$filename}->{data};
- }
- $ret->{changes} = $ccache->{$filename}->{diff};
-
- return $full ? $ret : $ret->{data};
- }
-
- my $diff;
-
- if ($shadow) {
- $diff = ccache_compute_diff ($filename, $shadow);
- }
-
- my $res = &$parser ($filename, $fd);
-
- if (!$ccache->{$filename}->{nocache}) {
- $ccache->{$filename}->{version} = $cver;
- }
-
- # we cache data with references, so we always need to
- # dclone this data. Else the original data may get
- # modified.
- $ccache->{$filename}->{data} = $res;
-
- # also store diff
- $ccache->{$filename}->{diff} = $diff;
-
- my $ret;
- if (!$noclone && ref ($ccache->{$filename}->{data})) {
- $ret->{data} = dclone ($ccache->{$filename}->{data});
- } else {
- $ret->{data} = $ccache->{$filename}->{data};
- }
- $ret->{changes} = $ccache->{$filename}->{diff};
-
- return $full ? $ret : $ret->{data};
-}
-
-sub add_file {
- my ($id, $filename, $parser, $writer, $update, %options) = @_;
-
- die "file '$filename' already added :ERROR" if defined ($ccache->{$filename});
- die "ID '$id' already used :ERROR" if defined ($ccachemap->{$id});
-
- $ccachemap->{$id} = $filename;
- $ccache->{$filename}->{id} = $id;
-
- $ccache->{$filename}->{parser} = $parser || \&ccache_default_parser;
- $ccache->{$filename}->{writer} = $writer || \&ccache_default_writer;
- $ccache->{$filename}->{update} = $update;
-
- foreach my $opt (keys %options) {
- my $v = $options{$opt};
- if ($opt eq 'readonce') {
- $ccache->{$filename}->{$opt} = $v;
- } elsif ($opt eq 'nocache') {
- $ccache->{$filename}->{$opt} = $v;
- } elsif ($opt eq 'noclone') {
- # noclone flag for large read-only data chunks like aplinfo
- $ccache->{$filename}->{$opt} = $v;
- } elsif ($opt eq 'always_call_parser') {
- # when set, we call parser even when the file does not exists.
- # this allows the parser to return some default
- $ccache->{$filename}->{$opt} = $v;
- } else {
- die "internal error - unsupported option '$opt'";
- }
- }
-
-
-}
-
-sub poll {
- return if !$inotify;
-
- if ($inotify_pid != $$) {
- syslog ('err', "got inotify poll request in wrong process - disabling inotify");
- $inotify = undef;
- } else {
- 1 while $inotify && $inotify->poll;
- }
-}
-
-sub flushcache {
- foreach my $filename (keys %$ccache) {
- $ccache->{$filename}->{version} = undef;
- $ccache->{$filename}->{data} = undef;
- $ccache->{$filename}->{diff} = undef;
- }
-}
-
-sub inotify_close {
- $inotify = undef;
-}
-
-sub inotify_init {
-
- die "only one inotify instance allowed" if $inotify;
-
- $inotify = Linux::Inotify2->new()
- || die "Unable to create new inotify object: $!";
-
- $inotify->blocking (0);
-
- $versions = {};
-
- my $dirhash = {};
- foreach my $fn (keys %$ccache) {
- my $dir = dirname ($fn);
- my $base = basename ($fn);
-
- $dirhash->{$dir}->{$base} = $fn;
-
- if (my $sf = $shadowfiles->{$fn}) {
- $base = basename ($sf);
- $dir = dirname ($sf);
- $dirhash->{$dir}->{$base} = $fn; # change version of original file!
- }
- }
-
- # also get versions of qemu and openvz config files
- $dirhash->{"/etc/qemu-server"}->{_regex} = '\d+\.conf';
- $dirhash->{"/etc/vz/conf"}->{_regex} = '\d+\.conf';
-
- $inotify_pid = $$;
-
- foreach my $dir (keys %$dirhash) {
-
- my $evlist = IN_MODIFY|IN_ATTRIB|IN_MOVED_FROM|IN_MOVED_TO|IN_DELETE|IN_CREATE;
- $inotify->watch ($dir, $evlist, sub {
- my $e = shift;
- my $name = $e->name;
-
- if ($inotify_pid != $$) {
- syslog ('err', "got inotify event in wrong process");
- }
-
- if ($e->IN_ISDIR || !$name) {
- return;
- }
-
- if ($e->IN_Q_OVERFLOW) {
- syslog ('info', "got inotify overflow - flushing cache");
- flushcache();
- return;
- }
-
- if ($e->IN_UNMOUNT) {
- syslog ('err', "got 'unmount' event on '$name' - disabling inotify");
- $inotify = undef;
- }
- if ($e->IN_IGNORED) {
- syslog ('err', "got 'ignored' event on '$name' - disabling inotify");
- $inotify = undef;
- }
-
- my $re = $dirhash->{$dir}->{_regex};
- if ($re && ($name =~ m|^$re$|)) {
-
- my $fn = "$dir/$name";
- $versions->{$fn}++;
- #print "VERSION:$fn:$versions->{$fn}\n";
-
- } elsif (my $fn = $dirhash->{$dir}->{$name}) {
-
- $versions->{$fn}++;
- #print "VERSION:$fn:$versions->{$fn}\n";
- }
- });
- }
-
- foreach my $dir (keys %$dirhash) {
- foreach my $name (keys %{$dirhash->{$dir}}) {
- if ($name eq '_regex') {
- my $re = $dirhash->{$dir}->{_regex};
- if (my $fd = IO::Dir->new ($dir)) {
- while (defined(my $de = $fd->read)) {
- if ($de =~ m/^$re$/) {
- my $fn = "$dir/$de";
- $versions->{$fn}++; # init with version
- #print "init:$fn:$versions->{$fn}\n";
- }
- }
- }
- } else {
- my $fn = $dirhash->{$dir}->{$name};
- $versions->{$fn}++; # init with version
- #print "init:$fn:$versions->{$fn}\n";
- }
- }
- }
-
-}
-
-add_file ('hostname', "/etc/hostname",
- \&read_etc_hostname,
- \&write_etc_hostname);
-
-add_file ('syncstatus', "/var/lib/pve-manager/syncstatus",
- \&read_var_lib_syncstatus,
- \&write_var_lib_syncstatus);
-
-add_file ('vzlist', "/var/lib/pve-manager/vzlist",
- \&read_var_lib_vzlist,
- \&write_var_lib_vzlist,
- \&update_var_lib_vzlist);
-
-add_file ('vmops', "/var/lib/pve-manager/vmops",
- \&read_var_lib_vmops,
- \&write_var_lib_vmops,
- \&update_var_lib_vmops);
-
-add_file ('interfaces', "/etc/network/interfaces",
- \&read_etc_network_interfaces,
- \&write_etc_network_interfaces);
-
-add_file ('resolvconf', "/etc/resolv.conf",
- \&read_etc_resolv_conf,
- \&write_etc_resolv_conf);
-
-add_file ('timezone', "/etc/timezone",
- \&read_etc_timezone,
- \&write_etc_timezone);
-
-add_file ('pvecfg', "/etc/pve/pve.cfg",
- \&read_etc_pve_cfg,
- \&write_etc_pve_cfg);
-
-add_file ('storagecfg', "/etc/pve/storage.cfg",
- \&read_etc_pve_storagecfg, undef, undef,
- always_call_parser => 1);
-
-add_file ('rootrsapubkey', "/root/.ssh/id_rsa.pub",
- \&read_rsapubkey);
-
-add_file ('hostrsapubkey', "/etc/ssh/ssh_host_rsa_key.pub",
- \&read_rsapubkey);
-
-add_file ('clustercfg', "/etc/pve/cluster.cfg",
- \&PVE::Storage::read_cluster_config);
-
-add_file ('newclustercfg', "/etc/pve/master/cluster.cfg",
- \&PVE::Storage::read_cluster_config);
-
-add_file ('qemuservercfg', "/etc/pve/qemu-server.cfg",
- \&read_etc_pve_qemu_server_cfg,
- \&write_etc_pve_qemu_server_cfg);
-
-add_file ('vzdump', "/etc/cron.d/vzdump",
- \&read_etc_crond_vzdump,
- \&write_etc_crond_vzdump,
- \&update_etc_crond_vzdump);
-
-add_file ('aplinfo', "/var/lib/pve-manager/apl-available",
- \&read_aplinfo, undef, undef,
- noclone => 1);
-
-add_file ('dotforward', "/root/.forward",
- \&read_root_dotforward,
- \&write_root_dotforward);
-
-add_file ('usercfg', "/etc/pve/user.cfg",
- \&PVE::AccessControl::parse_config);
-
-# persistent counter implementation
-add_file ('pcounter', "/var/lib/pve-manager/pcounter",
- \&read_pcounter,
- \&write_pcounter,
- \&update_pcounter,
- nocache => 1);
-
-1;
+++ /dev/null
-use PVE::SourceFilter;
-
-package PVE::ConfigServer;
-
-use strict;
-use vars qw(@ISA);
-use Carp;
-use PVE::SafeSyslog;
-use File::stat;
-use IO::File;
-use Fcntl qw(:flock);
-use MIME::Base64;
-use PVE::Cluster;
-use PVE::Utils;
-use PVE::Config;
-use IO::Socket::INET;
-use Digest::SHA1;
-use PVE::QemuServer;
-use PVE::APLInfo;
-use IPC::Open2;
-use PVE::OpenVZ;
-use PVE::Qemu;
-use PVE::Storage;
-
-use base 'Exporter';
-our @EXPORT = qw($pve_config_daemon);
-our $pve_config_daemon;
-
-my $get_userid = sub { # private method
- my ($class) = @_;
-
- if ($pve_config_daemon) {
- return $pve_config_daemon->{pve}->{username};
- }
-
- die "internal error";
-};
-
-my $get_ticket = sub { # private method
- my ($class) = @_;
-
- if ($pve_config_daemon) {
- return $pve_config_daemon->{pve}->{ticket};
- }
-
- die "internal error";
-};
-
-sub alive { ##SOAP_EXPORT##
- my ($class) = @_;
-
- return 1;
-}
-
-sub update_ticket { ##SOAP_EXPORT##
- my ($class) = @_;
-
- # ticket is magically updated by the server before
- # this function is called.
- my $ticket = $class->$get_ticket();
-
- return $ticket;
-}
-
-sub ping { ##SOAP_EXPORT##
- my ($class) = @_;
-
- my $userid = $class->$get_userid();
-
- my $cinfo = PVE::Cluster::clusterinfo ();
-
- my $status = { time => time (), insync => 1 };
-
- $status->{uptime} = PVE::Utils::get_uptime ();
- $status->{cpuinfo} = PVE::Utils::get_cpu_info ();
- $status->{meminfo} = PVE::Utils::get_memory_info ();
- $status->{hdinfo}->{root} = PVE::Utils::get_hd_info ('/');
-
- my $procstat = PVE::Utils::read_proc_stat();
- $status->{cpu} = $procstat->{cpu};
- $status->{wait} = $procstat->{wait};
-
- my $syncstatus = PVE::Config::read_file ("syncstatus");
-
- foreach my $ni (@{$cinfo->{nodes}}) {
- my $cid = $ni->{cid};
- next if $cinfo->{local}->{cid} == $cid; # skip local CID
- my $lastsync = defined ($syncstatus->{$cid}) ?
- $syncstatus->{$cid}->{lastsync} : 0;
- $status->{"lastsync_$cid"} = $lastsync;
- my $sdiff = time() - $lastsync;
- $sdiff = 0 if $sdiff < 0;
- $status->{insync} = 0 if ($sdiff > (60*3));
- }
-
- return $status;
-}
-
-sub vzlist { ##SOAP_EXPORT##
- my ($class) = @_;
-
- my $userid = $class->$get_userid();
-
- my $res = {};
-
- # openvz
- eval {
- $res = PVE::OpenVZ::vmlist();
- };
-
- my $err = $@;
-
- if ($err) {
- syslog ('err', "ERROR: $err");
- } else {
- $res->{openvz} = 1;
- }
-
- # qemu
- eval {
-
- my $qmlist = PVE::Qemu::vmlist();
-
- foreach my $vekey (keys %$qmlist) {
- if (!$res->{$vekey}) {
- $res->{$vekey} = $qmlist->{$vekey};
- } else {
- syslog ('err', "found duplicated ID '$vekey' - ignoring qemu instance\n");
- }
- }
- };
-
- $err = $@;
-
- if ($err) {
- syslog ('err', "ERROR: $err");
- } else {
- $res->{qemu} = 1;
- }
-
- $res->{lasttime} = time();
-
- my $pc = PVE::Config::update_file ('pcounter', 'vzlist');
- $res->{version} = $pc->{vzlist};
-
- return $res;
-}
-
-sub vmlogview { ##SOAP_EXPORT##
- my ($class, $cid, $veid, $service) = @_;
-
- my $userid = $class->$get_userid();
-
- my $filename = "/var/lib/vz/private/$veid/var/log/syslog";
-
- if ($service eq 'init') {
- $filename = "/var/lib/vz/private/$veid/var/log/init.log";
- } elsif ($service eq 'syslog') {
- # some systems (rh,centos) logs to messages instead
- my $msglog = "/var/lib/vz/private/$veid/var/log/messages";
- if ((! -f $filename) && (-f $msglog)) {
- $filename = $msglog;
- }
- }
-
- my $lines = [];
-
- my $limit = 200;
-
- open (TMP, "tail -$limit $filename|");
- while (my $line = <TMP>) {
- chomp $line;
- push @$lines, $line;
- }
- close (TMP);
-
- return $lines;
-}
-
-sub vmconfig { ##SOAP_EXPORT##
- my ($class, $veid, $type) = @_;
-
- my $userid = $class->$get_userid();
-
- die "unknown virtualization type '$type'\n" if !($type eq 'openvz' || $type eq 'qemu');
-
- my $res;
-
- $res->{vzlist} = $class->vzlist();
-
- if (($type eq 'qemu') && !$res->{vzlist}->{qemu}) {
- die "unable to get qemu-server vm list - server not running?\n";
- }
- if (($type eq 'openvz') && !$res->{vzlist}->{openvz}) {
- die "unable to get openvz vm list?\n";
- }
-
- if (my $d = $res->{vzlist}->{"VEID_$veid"}) {
- die "virtualization type mismatch" if $type ne $d->{type};
-
- if ($d->{type} eq 'openvz') {
- $res->{config} = PVE::Config::get_veconfig ($veid);
- } elsif ($d->{type} eq 'qemu') {
- $res->{config} = PVE::Config::get_qmconfig ($veid);
- } else {
- die "internal error";
- }
- } else {
- die "unable to get configuration data for VEID '$veid'";
- }
-
- return $res;
-}
-
-sub cluster_vzlist { ##SOAP_EXPORT##
- my ($class, $cid, $vzlist) = @_;
-
- my $userid = $class->$get_userid();
-
- my $newlist = PVE::Config::update_file ('vzlist', $vzlist, $cid);
-
- my $vmops = PVE::Config::read_file ("vmops");
-
- PVE::Utils::foreach_vmrec ($vmops, sub {
- my ($cid, $vmid, $d, $ckey, $vmkey) = @_;
- my $old = $newlist->{$ckey}->{$vmkey};
-
- # command still running ?
- my $pstart;
- if ($old && PVE::Utils::check_process ($d->{pid}, $d->{pstart})) {
-
- $old->{status} = $d->{command};
-
- if ($d->{command} eq 'migrate') {
- PVE::Utils::foreach_vmrec ($newlist, sub {
- my ($ncid, $nvmid, $nd) = @_;
- $nd->{status} = 'migrate' if ($nvmid eq $vmid);
- });
- }
- }
- });
-
- return $newlist;
-}
-
-# start long running workers
-# $data append to the returned uniquely identifier, which
-# has the following format: "UPID:$pid-$pstart:$startime:$dtype:$data"
-# STDIN is redirected to /dev/null
-# STDOUT,STDERR are redirected to the filename returned by upid_decode
-# that file is locked wit flock to make sure only one process
-# is writing it
-
-my $fork_worker = sub { # private method
- my ($class, $dtype, $data, $function) = @_;
-
- my $cpid;
-
- $dtype = 'unknown' if !defined ($dtype);
-
- $data = '' if !defined ($data);
-
- my $starttime = time ();
-
- my @psync = POSIX::pipe();
-
- # detect filename with faked PID
- my $tmp = PVE::Utils::upid_decode ("UPID:0-0:0:$dtype:$data");
- my $filename = $tmp->{filename};
-
- my $lockfh;
- # lock output file
- if ($filename) {
-
- $lockfh = IO::File->new ($filename, O_WRONLY|O_CREAT) ||
- die "unable to open output file - $!\n";
-
- my $wwwid = getpwnam('www-data');
- chown $wwwid, $filename;
-
- if (!flock ($lockfh, LOCK_EX|LOCK_NB)) {
- undef $lockfh; # close
- die "unable to lock output file\n";
- }
-
- if (!truncate ($lockfh, 0)) {
- die "unable to truncate output file - $!\n";
- }
- }
-
- if (($cpid = fork()) == 0) {
-
- $SIG{INT} = $SIG{QUIT} = $SIG{TERM} = sub { die "received interrupt\n"; };
-
- $SIG{CHLD} = $SIG{PIPE} = 'DEFAULT';
-
- # set sess/process group - we want to be able to kill the
- # whole process group
- POSIX::setsid();
-
- POSIX::close ($psync[0]);
-
- PVE::Config::inotify_close();
-
- # we close the socket
- my $httpd = $pve_config_daemon->{_daemon};
- $httpd->close();
-
- # same algorythm as used inside SA
-
- # STDIN = /dev/null
- my $fd = fileno (STDIN);
- close STDIN;
- POSIX::close(0) if $fd != 0;
-
- if (!open (STDIN, "</dev/null")) {
- POSIX::_exit (1);
- kill ('KILL', $$);
- }
-
- # redirect STDOUT
- $fd = fileno(STDOUT);
- close STDOUT;
- POSIX::close (1) if $fd != 1;
-
- if ($filename) {
- if (!open (STDOUT, ">&", $lockfh)) {
- POSIX::_exit (1);
- kill ('KILL', $$);
- }
-
- STDOUT->autoflush (1);
- } else {
- if (!open (STDOUT, ">/dev/null")) {
- POSIX::_exit (1);
- kill ('KILL', $$);
- }
- }
-
- # redirect STDERR to STDOUT
- $fd = fileno (STDERR);
- close STDERR;
- POSIX::close(2) if $fd != 2;
-
- if (!open (STDERR, ">&1")) {
- POSIX::_exit (1);
- kill ('KILL', $$);
- }
-
- STDERR->autoflush (1);
-
- my $pstart = PVE::Utils::read_proc_starttime ($$) ||
- die "unable to read process starttime";
-
- my $upid = PVE::Utils::upid_encode ({
- pid => $$, pstart => $pstart, starttime => $starttime,
- type => $dtype, data => $data });
-
- # sync with parent
- POSIX::write ($psync[1], $upid, length ($upid));
- POSIX::close ($psync[1]);
-
- &$function ($upid);
-
- die "should not be reached";
- }
-
- POSIX::close ($psync[1]);
-
- # sync with child (wait until child starts)
- my $upid = '';
- POSIX::read($psync[0], $upid, 4096);
- POSIX::close ($psync[0]);
-
- if ($lockfh) {
- undef $lockfh; # close
- }
-
- my $uh = PVE::Utils::upid_decode ($upid);
- if (!$uh ||
- !($uh->{pid} == $cpid && $uh->{starttime} == $starttime &&
- $uh->{type} eq $dtype && $uh->{data} eq $data)) {
- syslog ('err', "got strange upid - $upid\n");
- }
-
- PVE::Utils::register_worker ($cpid);
-
- return $upid;
-};
-
-# UPID: unique worker process descriptor
-#
-# general format used by fork_worker is
-# UPID:$pid-$pstart:$start:$type:$data
-#
-# $pid ... process id of worker
-# $pstart ... process start time from /proc/pid/stat
-# $start ... time (epoch) when process started
-# $type ... string to identity format of $data
-# $data ... arbitrary text
-#
-# speicalized format we use is
-# UPID:$pid-$pstart:$start:vmops:$command:$cid:$veid
-#
-# $command ... create, start, stop, destroy
-# $cid,$veid ... cluster identity of VE
-#
-# Note: PIDs are recycled, so to test if a process is still running
-# we use (PID,PSTART) pair.
-
-my $vmcommand = sub { # private method
- my ($class, $userid, $command, $cid, $veid, $code) = @_;
-
- my $remip;
- my $remcmd = [];
-
- $userid = 'unknown' if !$userid;
-
- my $cinfo = PVE::Cluster::clusterinfo ();
-
- if ($cid != $cinfo->{local}->{cid}) {
- $remip = $cinfo->{"CID_$cid"}->{ip};
- # we force tty allocation in order to tranfer signals (kill)
- $remcmd = ['/usr/bin/ssh', '-t', '-t', '-n', '-o', 'BatchMode=yes', $remip];
- }
-
- my $realcmd = sub {
- my $upid = shift;
-
- print "$upid\n";
-
- my $res = -1;
-
- eval {
- $res = &$code ($upid, $remip, $remcmd, $cinfo);
-
- my $ticket = $class->$get_ticket();
-
- my $rcon = PVE::ConfigClient::connect ($ticket, $cinfo, $cid);
- if (my $vzlist = $rcon->vzlist()->result) {
- PVE::Config::update_file ('vzlist', $vzlist, $cid);
- }
- };
-
- my $err = $@;
-
- if ($err) {
- syslog ('err', $err);
- print STDERR "\n$err";
- exit (-1);
- }
-
- print STDERR "\n"; # flush
- exit ($res);
- };
-
- if (my $uid = $class->$fork_worker ('vmops', "$command:$cid:$veid:$userid", $realcmd)) {
-
- PVE::Config::update_file ("vmops", $uid);
-
- return $uid; ;
- }
-
- return undef;
-};
-
-sub apl_start_download { ##SOAP_EXPORT##
- my ($class, $aplname) = @_;
-
- my $userid = $class->$get_userid();
-
- my $pkglist = PVE::APLInfo::load_data();
-
- my $data;
-
- if (!$pkglist || !$aplname || !($data = $pkglist->{'all'}->{$aplname})) {
- syslog ('err', "download failed: no aplinfo for appliance '$aplname'");
- return;
- }
-
- my $realcmd = sub {
- my $upid = shift;
-
- print "$upid\n";
-
- my $tmp = "/tmp/apldownload-$$-tmp.dat";
-
- eval {
- my $msg = "starting download: $aplname";
- syslog ('info', $msg);
- print STDERR "$msg\n";
-
- my $src = $data->{location};
- my $dest = "/var/lib/vz/template/cache/$aplname";
-
- if (-f $dest) {
- my $md5 = (split (/\s/, `md5sum '$dest'`))[0];
-
- if ($md5 && (lc($md5) eq lc($data->{md5sum}))) {
- $msg = "file already exists $md5 - no need to download";
- syslog ('info', $msg);
- print STDERR "$msg\n";
- return;
- }
- }
-
- local %ENV;
- my $pvecfg = PVE::Config::read_file('pvecfg');
- if ($pvecfg && $pvecfg->{http_proxy}) {
- $ENV{http_proxy} = $pvecfg->{http_proxy};
- }
-
- my @cmd = ('/usr/bin/wget', '--progress=dot:mega', '-O', $tmp, $src);
- if (system (@cmd) != 0) {
- die "download failed - $!\n";
- }
-
- my $md5 = (split (/\s/, `md5sum '$tmp'`))[0];
-
- if (!$md5 || (lc($md5) ne lc($data->{md5sum}))) {
- die "wrong checksum: $md5 != $data->{md5sum}\n";
- }
-
- if (system ('mv', $tmp, $dest) != 0) {
- die "unable to save file - $!\n";
- }
- };
-
- my $err = $@;
-
- unlink $tmp;
-
- if ($err) {
- syslog ('err', $err);
- print STDERR "\n\ndownload failed: $err";
- exit (-1);
- }
-
- syslog ('info', "download finished");
- print STDERR "download finished\n";
-
- exit (0);
- };
-
- if (my $uid = $class->$fork_worker ('apldownload', "$userid:$aplname", $realcmd)) {
- return $uid;
- }
-
- return undef;
-}
-
-sub vmconfig_set { ##SOAP_EXPORT##
- my ($class, $cid, $veid, $type, $settings) = @_;
-
- die "unknown virtualization type '$type'\n" if !($type eq 'openvz' || $type eq 'qemu');
-
- my $userid = $class->$get_userid();
-
- my $cinfo = PVE::Cluster::clusterinfo ();
-
- my $remip;
- my $remcmd = [];
-
- if ($cid != $cinfo->{local}->{cid}) {
- $remip = $cinfo->{"CID_$cid"}->{ip};
- $remcmd = ['/usr/bin/ssh', '-n', '-o', 'BatchMode=yes', $remip];
- }
-
- return if !$settings;
-
- my $param;
-
- foreach my $key (keys %$settings) {
- die "invalid key '$key'" if $key !~ m/^\w+$/;
- my $v = $settings->{$key};
- next if !defined ($v);
- if (ref ($v) eq 'ARRAY') {
- foreach my $v1 (@$v) {
- push @$param, "--$key", $remip ? PVE::Utils::shellquote ($v1) : $v1;
- }
- } else {
- push @$param, "--$key", $remip ? PVE::Utils::shellquote ($v) : $v;
- }
- }
-
- return if scalar (@$param) == 0;
-
- $remip = 'localhost' if !$remip;
-
- syslog ('info', "apply settings to VM $veid on node $cid ($remip)");
-
- my @cmd;
-
- if ($type eq 'openvz') {
- @cmd = (@$remcmd, '/usr/bin/pvectl', 'vzset', $veid, @$param);
- } else {
- @cmd = (@$remcmd, '/usr/sbin/qm', 'set', $veid, @$param);
- }
-
- if (system (@cmd) != 0) {
- my $cmdstr = join (' ', @cmd);
- my $msg = "unable to apply VM settings, command failed: $cmdstr\n";
- syslog ('err', $msg);
- die "$msg\n";
- }
-
- my $msg = "VM $veid settings applied";
- syslog ('info', $msg);
-}
-
-# set cdrom for qemu/kvm
-sub vmconfig_setcdrom { ##SOAP_EXPORT##
- my ($class, $cid, $veid, $device, $volid) = @_;
-
- my $userid = $class->$get_userid();
-
- my $cinfo = PVE::Cluster::clusterinfo ();
-
- my $remip;
- my $remcmd = [];
-
- if ($cid != $cinfo->{local}->{cid}) {
- $remip = $cinfo->{"CID_$cid"}->{ip};
- $remcmd = ['/usr/bin/ssh', '-n', '-o', 'BatchMode=yes', $remip];
- }
-
- my $param;
-
- die "invalid device name '$device'" if $device !~ m/^\w+$/;
-
- push @$param, "--$device", $remip ? PVE::Utils::shellquote ($volid) : $volid;
-
- return if scalar (@$param) == 0;
-
- $remip = 'localhost' if !$remip;
-
- syslog ('info', "setting cdrom on VM $veid on node $cid ($remip)");
-
- my @cmd = (@$remcmd, '/usr/sbin/qm', 'cdrom', $veid, @$param);
-
- if (system (@cmd) != 0) {
- my $cmdstr = join (' ', @cmd);
- my $msg = "unable to set cdrom, command failed: $cmdstr\n";
- syslog ('err', $msg);
- die "$msg\n";
- }
-
- my $msg = "VM $veid set cdrom";
- syslog ('info', $msg);
-}
-
-# delete unused qemu/kvm disk images
-sub qemu_unlink_disk { ##SOAP_EXPORT##
- my ($class, $cid, $veid, $filename) = @_;
-
- my $userid = $class->$get_userid();
-
- my $cinfo = PVE::Cluster::clusterinfo ();
-
- my $remip;
- my $remcmd = [];
-
- if ($cid != $cinfo->{local}->{cid}) {
- $remip = $cinfo->{"CID_$cid"}->{ip};
- $remcmd = ['/usr/bin/ssh', '-n', '-o', 'BatchMode=yes', $remip];
- }
-
- $remip = 'localhost' if !$remip;
-
- syslog ('info', "delete image '$filename' on VM $veid on node $cid ($remip)");
-
- my @cmd = (@$remcmd, '/usr/sbin/qm', 'unlink', $veid, $filename);
-
- if (system (@cmd) != 0) {
- my $cmdstr = join (' ', @cmd);
- my $msg = "unable to delete image, command failed: $cmdstr\n";
- syslog ('err', $msg);
- die "$msg\n";
- }
-
- my $msg = "VM $veid image '$filename' successfuly deleted";
- syslog ('info', $msg);
-}
-
-sub vmcommand_create { ##SOAP_EXPORT##
- my ($class, $cid, $veid, $type, $settings) = @_;
-
- die "unknown virtualization type '$type'\n" if !($type eq 'openvz' || $type eq 'qemu');
-
- my $userid = $class->$get_userid();
-
- return $class->$vmcommand ($userid, 'create', $cid, $veid, sub {
- my ($upid, $remip, $remcmd, $cinfo) = @_;
-
-
- my @cmd;
-
- if ($type eq 'openvz') {
- @cmd = (@$remcmd, '/usr/bin/pvectl', 'vzcreate', $veid);
- } else {
- @cmd = (@$remcmd, '/usr/sbin/qm', 'create', $veid);
- }
-
- foreach my $key (keys %$settings) {
- die "invalid key '$key'" if $key !~ m/^\w+$/;
- my $v = $settings->{$key};
- next if !defined ($v);
- if (ref ($v) eq 'ARRAY') {
- foreach my $v1 (@$v) {
- push @cmd, "--$key", $remip ? PVE::Utils::shellquote ($v1) : $v1;
- }
- } else {
- push @cmd, "--$key", $remip ? PVE::Utils::shellquote ($v) : $v;
- }
- }
-
- $remip = 'localhost' if !$remip;
-
- syslog ('info', "creating new VM $veid on node $cid ($remip)");
-
- my $cmdstr = join (' ', @cmd);
- print "$cmdstr\n";
-
- if (system (@cmd) != 0) {
-
- my $msg = "unable to apply VM settings - $!";
- syslog ('err', $msg);
- print "$msg\n";
- return -1;
- }
-
- my $msg = "VM $veid created";
- syslog ('info', $msg);
- print "$msg\n";
-
- return 0;
- });
-}
-
-sub vmcommand_destroy { ##SOAP_EXPORT##
- my ($class, $cid, $veid, $type) = @_;
-
- die "unknown virtualization type '$type'\n" if !($type eq 'openvz' || $type eq 'qemu');
-
- my $userid = $class->$get_userid();
-
- return $class->$vmcommand ($userid, 'destroy', $cid, $veid, sub {
- my ($upid, $remip, $remcmd, $cinfo) = @_;
-
- $remip = 'localhost' if !$remip;
-
- syslog ('info', "destroying VM $veid on node $cid ($remip)");
-
- my @cmd;
-
- if ($type eq 'openvz') {
- @cmd = (@$remcmd, '/usr/sbin/vzctl', 'destroy', $veid);
- } else {
- @cmd = (@$remcmd, '/usr/sbin/qm', 'destroy', $veid);
- }
-
- my $cmdstr = join (' ', @cmd);
-
- print "$cmdstr\n";
-
- if (system (@cmd) != 0) {
- my $msg = "VM $veid destroy failed - $!";
- syslog ('err', $msg);
- print "$msg\n";
- return -1;
- }
-
- my $msg = "VM $veid destroyed";
- syslog ('info', $msg);
- print "$msg\n";
-
- return 0;
- });
-}
-
-sub vmcommand_stop { ##SOAP_EXPORT##
- my ($class, $cid, $veid, $type, $force) = @_;
-
- my $userid = $class->$get_userid();
-
- die "unknown virtualization type '$type'\n" if !($type eq 'openvz' || $type eq 'qemu');
-
- return $class->$vmcommand ($userid, 'stop', $cid, $veid, sub {
- my ($upid, $remip, $remcmd, $cinfo) = @_;
-
- $remip = 'localhost' if !$remip;
-
- syslog ('info', "stopping VM $veid on node $cid ($remip)");
-
- my @cmd;
-
- if ($type eq 'openvz') {
- @cmd = (@$remcmd, '/usr/sbin/vzctl', 'stop', $veid);
- push @cmd, '--fast' if $force;
- } else {
- @cmd = (@$remcmd, '/usr/sbin/qm', $force ? 'stop' : 'shutdown', $veid);
- }
-
- my $cmdstr = join (' ', @cmd);
-
- print "$cmdstr\n";
-
- if (system (@cmd) != 0) {
- my $msg = "VM $veid stop failed - $!";
- syslog ('err', $msg);
- print "$msg\n";
- return -1;
- }
-
- my $msg = "VM $veid stopped";
- syslog ('info', $msg);
- print "$msg\n";
-
- return 0;
- });
-}
-
-sub vmcommand_umount { ##SOAP_EXPORT##
- my ($class, $cid, $veid, $type) = @_;
-
- die "unknown virtualization type '$type'\n" if $type ne 'openvz';
-
- my $userid = $class->$get_userid();
-
- return $class->$vmcommand ($userid, 'umount', $cid, $veid, sub {
- my ($upid, $remip, $remcmd, $cinfo) = @_;
-
- $remip = 'localhost' if !$remip;
-
- syslog ('info', "unmounting VM $veid on node $cid ($remip)");
-
- my @cmd;
-
- @cmd = (@$remcmd, '/usr/sbin/vzctl', 'umount', $veid);
-
- my $cmdstr = join (' ', @cmd);
-
- print "$cmdstr\n";
-
- if (system (@cmd) != 0) {
- my $msg = "VM $veid umount failed - $!";
- syslog ('err', $msg);
- print "$msg\n";
- return -1;
- }
-
- my $msg = "VM $veid unmounted";
- syslog ('info', $msg);
- print "$msg\n";
-
- return 0;
- });
-}
-
-sub vmcommand_start { ##SOAP_EXPORT##
- my ($class, $cid, $veid, $type) = @_;
-
- die "unknown virtualization type '$type'\n" if !($type eq 'openvz' || $type eq 'qemu');
-
- my $userid = $class->$get_userid();
-
- return $class->$vmcommand ($userid, 'start', $cid, $veid, sub {
- my ($upid, $remip, $remcmd, $cinfo) = @_;
-
- $remip = 'localhost' if !$remip;
-
- syslog ('info', "starting VM $veid on node $cid ($remip)");
-
- my @cmd;
-
- if ($type eq 'openvz') {
- @cmd = (@$remcmd, '/usr/sbin/vzctl', 'start', $veid);
- } else {
- @cmd = (@$remcmd, '/usr/sbin/qm', 'start', $veid);
- }
-
- my $cmdstr = join (' ', @cmd);
-
- print "$cmdstr\n";
-
- if (system (@cmd) != 0) {
- my $msg = "VM $veid start failed - $!";
- syslog ('err', $msg);
- print "$msg\n";
- return -1;
- }
-
- my $msg = "VM $veid started";
- syslog ('info', $msg);
- print "$msg\n";
-
- return 0;
- });
-}
-
-sub vmcommand_restart { ##SOAP_EXPORT##
- my ($class, $cid, $veid, $type) = @_;
-
- die "unknown virtualization type '$type'\n" if !($type eq 'openvz' || $type eq 'qemu');
-
- my $userid = $class->$get_userid();
-
- return $class->$vmcommand ($userid, 'restart', $cid, $veid, sub {
- my ($upid, $remip, $remcmd, $cinfo) = @_;
-
- $remip = 'localhost' if !$remip;
-
- syslog ('info', "restarting VM $veid on node $cid ($remip)");
-
- my @cmd;
-
- if ($type eq 'openvz') {
- @cmd = (@$remcmd, '/usr/sbin/vzctl', 'restart', $veid);
- } else {
- @cmd = (@$remcmd, '/usr/sbin/qm', 'reset', $veid);
- }
- my $cmdstr = join (' ', @cmd);
-
- print "$cmdstr\n";
-
- if (system (@cmd) != 0) {
- my $msg = "VM $veid restart failed - $!";
- syslog ('err', $msg);
- print "$msg\n";
- return -1;
- }
-
- my $msg = "VM $veid restarted";
- syslog ('info', $msg);
- print "$msg\n";
-
- return 0;
- });
-}
-
-sub vmcommand_migrate { ##SOAP_EXPORT##
- my ($class, $cid, $veid, $type, $target, $online) = @_;
-
- die "unknown virtualization type '$type'\n" if !($type eq 'openvz' || $type eq 'qemu');
-
- my $userid = $class->$get_userid();
-
- my $cinfo = PVE::Cluster::clusterinfo ();
-
- return $class->$vmcommand ($userid, 'migrate', $cid, $veid, sub {
- my ($upid, $remip, $remcmd, $cinfo) = @_;
-
- $remip = 'localhost' if !$remip;
-
- my $targetip = $cinfo->{"CID_$target"}->{ip};
-
- syslog ('info', "migrating VM $veid from node $cid ($remip) to node $target ($targetip)");
-
- my @cmd;
-
- if ($type eq 'openvz') {
- @cmd = (@$remcmd, '/usr/sbin/vzmigrate');
- push @cmd, '--online' if $online;
- push @cmd, $targetip;
- push @cmd, $veid;
- } else {
- @cmd = (@$remcmd, '/usr/sbin/qmigrate');
- push @cmd, '--online' if $online;
- push @cmd, $targetip;
- push @cmd, $veid;
- }
-
- my $cmdstr = join (' ', @cmd);
-
- print "$cmdstr\n";
-
- if (system (@cmd) != 0) {
- my $msg = "VM $veid migration failed - $!";
- syslog ('err', $msg);
- print "$msg\n";
- return -1;
- }
-
- my $msg = "VM $veid migration done";
- syslog ('info', $msg);
- print "$msg\n";
-
- return 0;
- });
-}
-
-my $next_vnc_port = sub { # private method
-
- for (my $p = 5900; $p < 6000; $p++) {
-
- my $sock = IO::Socket::INET->new (Listen => 5,
- LocalAddr => 'localhost',
- LocalPort => $p,
- ReuseAddr => 1,
- Proto => 0);
-
- if ($sock) {
- close ($sock);
- return $p;
- }
- }
-
- die "unable to find free vnc port";
-};
-
-sub create_vnc_proxy { ##SOAP_EXPORT##
- my ($class, $cid, $veid) = @_;
-
- my $remip;
- my $remcmd = [];
-
- my $userid = $class->$get_userid();
-
- my $cinfo = PVE::Cluster::clusterinfo ();
-
- if ($cid != $cinfo->{local}->{cid}) {
- $remip = $cinfo->{"CID_$cid"}->{ip};
- $remcmd = ['/usr/bin/ssh', '-T', '-o', 'BatchMode=yes', $remip];
- }
-
- my $port = $class->$next_vnc_port();
- # generate ticket, olny first 8 character used by vnc
- my $ticket = Digest::SHA1::sha1_base64 ($userid, rand(), time());
-
- my $timeout = 30;
-
- my $realcmd = sub {
- my $upid = shift;
-
- syslog ('info', "starting vnc proxy $upid\n");
-
- my $qmcmd = [@$remcmd, "/usr/sbin/qm", 'vncproxy', $veid , $ticket];
-
- my $qmstr = join (' ', @$qmcmd);
-
- # also redirect stderr (else we get RFB protocol errors)
- my @cmd = ('/bin/nc', '-l', '-p', $port, '-w', $timeout, '-c', "$qmstr 2>/dev/null");
-
- my $cmdstr = join (' ', @cmd);
- syslog ('info', "CMD: $cmdstr");
-
- if (system (@cmd) != 0) {
- my $msg = "VM $veid vnc proxy failed - $?";
- syslog ('err', $msg);
- exit (-1);
- }
-
- exit (0);
- };
-
- if (my $uid = $class->$fork_worker ('vncproxy', "$cid:$veid:$userid:$port:$ticket", $realcmd)) {
- return { port => $port, ticket => $ticket};
- }
-
- return undef;
-
-}
-
-sub create_vnc_console { ##SOAP_EXPORT##
- my ($class, $cid, $veid, $type, $status) = @_;
-
- my $userid = $class->$get_userid();
-
- my $remip;
- my $remcmd = [];
-
- $userid = 'unknown' if !$userid;
-
- my $cinfo = PVE::Cluster::clusterinfo ();
-
- if ($cid != $cinfo->{local}->{cid}) {
- $remip = $cinfo->{"CID_$cid"}->{ip};
- $remcmd = ['/usr/bin/ssh', '-t', $remip];
- }
-
- my $port = $class->$next_vnc_port();
- # generate ticket, olny first 8 character used by vnc
- my $ticket = Digest::SHA1::sha1_base64 ($userid, rand(), time());
-
- my $timeout = 1; # immediately exit when last client disconnects
-
- my $realcmd = sub {
- my $upid = shift;
-
- syslog ('info', "starting vnc console $upid\n");
-
- # fixme: use ssl
-
- my $pwfile = "/tmp/.vncpwfile.$$";
-
- my $vzcmd;
-
- if ($type eq 'openvz') {
- if ($status eq 'running') {
- $vzcmd = [ '/usr/sbin/vzctl', 'enter', $veid ];
- } elsif ($status eq 'mounted') {
- $vzcmd = [ "/usr/bin/pvebash", $veid, 'root'];
- } else {
- $vzcmd = [ "/usr/bin/pvebash", $veid, 'private'];
- }
- } elsif ($type eq 'qemu') {
- $vzcmd = [ "/usr/sbin/qm", 'monitor', $veid ];
- } else {
- $vzcmd = [ '/bin/true' ]; # should not be reached
- }
-
- my @cmd = ('/usr/bin/vncterm', '-rfbport', $port,
- '-passwdfile', "rm:$pwfile",
- '-timeout', $timeout, '-c', @$remcmd, @$vzcmd);
-
- my $cmdstr = join (' ', @cmd);
- syslog ('info', "CMD: $cmdstr");
-
- my $fh = IO::File->new ($pwfile, "w", 0600);
- print $fh "$ticket\n";
- $fh->close;
-
- if (system (@cmd) != 0) {
- my $msg = "VM $veid console viewer failed - $?";
- syslog ('err', $msg);
- exit (-1);
- }
-
- exit (0);
- };
-
- if (my $uid = $class->$fork_worker ('vncview', "$cid:$veid:$userid:$port:$ticket", $realcmd)) {
-
- #PVE::Config::update_file ("vncview", $uid);
-
- return { port => $port, ticket => $ticket};
- }
-
- return undef;
-
-}
-
-sub service_cmd { ##SOAP_EXPORT##
- my ($class, $service, $cmd) = @_;
-
- my $userid = $class->$get_userid();
-
- eval {
- my $res = PVE::Utils::service_cmd ($service, $cmd);
- syslog ('info', $res) if $res;
- syslog ('info', "service command '$service $cmd' successful");
- };
-
- if (my $err = $@) {
- syslog ('err', "service command '$service $cmd' failed : $err");
- }
-}
-
-my $service_list = {
- apache => { short => 'WWW', long => 'Web Server' },
- pvetunnel => { short => 'ClusterTunnel',
- long => 'PVE Cluster Tunnel Daemon' },
- pvemirror => { short => 'ClusterSync',
- long => 'PVE Cluster Synchronization Daemon' },
- postfix => { short => 'SMTP', long => 'Simple Mail Tranfer Protocol' },
- ntpd => { short => 'NTP', long => 'Network Time Protocol' },
- sshd => { short => 'SSH', long => 'Secure Shell Daemon' },
- # bind => { short => 'BIND', long => 'Local DNS Cache' },
- # pvedaemon => { short => 'NodeManager', long => 'PVE Node Manager Daemon' },
-};
-
-sub service_state_all { ##SOAP_EXPORT##
- my ($class) = @_;
-
- my $userid = $class->$get_userid();
-
- my $res = {};
-
- foreach my $s (keys %{$service_list}) {
- $res->{$s} = $service_list->{$s};
- $res->{$s}->{status} = PVE::Utils::service_state ($s);
- }
-
- return $res;
-}
-
-sub restart_server { ##SOAP_EXPORT##
- my ($class, $poweroff) = @_;
-
- my $userid = $class->$get_userid();
-
- if ($poweroff) {
- system ("(sleep 2;/sbin/poweroff)&");
- } else {
- system ("(sleep 2;shutdown -r now)&");
- }
-}
-
-sub check_worker { ##SOAP_EXPORT##
- my ($class, $upid, $killit) = @_;
-
- my $userid = $class->$get_userid();
-
- if (my $upid_hash = PVE::Utils::upid_decode ($upid)) {
-
- my $pid = $upid_hash->{pid};
-
- # test if still running
- return 0 if !PVE::Utils::check_process ($pid, $upid_hash->{pstart});
-
- if ($killit) {
-
- # send kill to process group (negative pid)
- my $kpid = -$pid;
-
- kill (15, $kpid); # send TERM signal
-
- # give max 5 seconds to shut down
- # note: waitpid only work for child processes, but not
- # for processes spanned by other processes, so we use
- # kill to detect if the worker is still running
- for (my $i = 0; $i < 5; $i++) {
- last if !kill (0, $kpid);
- sleep (1);
- }
-
- if (kill (0, $kpid)) {
- kill (9, $kpid); # kill if still alive
- }
-
- return 0; # killed, not running
- } else {
- return 1; # running
- }
- }
-
- return 0;
-}
-
-sub kvm_version { ##SOAP_EXPORT##
- my ($class) = @_;
-
- my $userid = $class->$get_userid();
-
- return PVE::QemuServer::kvm_version();
-}
-
-sub install_template { ##SOAP_EXPORT##
- my ($class, $storeid, $type, $tmpname, $filename) = @_;
-
- my $userid = $class->$get_userid();
-
- my $cfg = PVE::Config::read_file ("storagecfg");
-
- PVE::Storage::install_template ($cfg, $storeid, $type, $tmpname, $filename);
-}
-
-sub delete_volume { ##SOAP_EXPORT##
- my ($class, $volid) = @_;
-
- my $userid = $class->$get_userid();
-
- my $cfg = PVE::Config::read_file ("storagecfg");
-
- PVE::Storage::vdisk_free ($cfg, $volid);
-}
-
-sub get_config_data { ##SOAP_EXPORT##
- my ($class, $id, $full) = @_;
-
- my $userid = $class->$get_userid();
-
- return PVE::Config::read_file ($id, $full);
-}
-
-sub set_config_data { ##SOAP_EXPORT##
- my ($class, $id, $data, $full) = @_;
-
- my $userid = $class->$get_userid();
-
- return PVE::Config::write_file ($id, $data, $full);
-}
-
-sub update_config_data { ##SOAP_EXPORT##
- my ($class, $id, $data, @param) = @_;
-
- my $userid = $class->$get_userid();
-
- return PVE::Config::update_file ($id, $data, @param);
-}
-
-sub discard_config_changes { ##SOAP_EXPORT##
- my ($class, $id, $full) = @_;
-
- my $userid = $class->$get_userid();
-
- return PVE::Config::discard_changes ($id, $full);
-}
-
-sub modify_user { ##SOAP_EXPORT##
- my ($class, $username, $group, $pw, $comment) = @_;
-
- my $userid = $class->$get_userid();
-
- return PVE::Utils::modify_user ($username, $group, $pw, $comment);
-}
-
-sub storage_list_volumes { ##SOAP_EXPORT##
- my ($class, $storeid) = @_;
-
- my $userid = $class->$get_userid();
-
- my $cfg = PVE::Config::read_file ("storagecfg");
-
- return PVE::Storage::vdisk_list ($cfg, $storeid);
-}
-
-sub storage_list_iso { ##SOAP_EXPORT##
- my ($class, $storeid) = @_;
-
- my $userid = $class->$get_userid();
-
- my $cfg = PVE::Config::read_file ("storagecfg");
-
- return PVE::Storage::template_list ($cfg, $storeid, 'iso');
-}
-
-sub storage_list_vztmpl { ##SOAP_EXPORT##
- my ($class, $storeid) = @_;
-
- my $userid = $class->$get_userid();
-
- my $cfg = PVE::Config::read_file ("storagecfg");
-
- return PVE::Storage::template_list ($cfg, $storeid, 'vztmpl');
-}
-
-sub storage_list_backups { ##SOAP_EXPORT##
- my ($class, $storeid) = @_;
-
- my $userid = $class->$get_userid();
-
- my $cfg = PVE::Config::read_file ("storagecfg");
-
- return PVE::Storage::template_list ($cfg, $storeid, 'backup');
-}
-
-sub storage_list_vgs { ##SOAP_EXPORT##
- my ($class) = @_;
-
- my $userid = $class->$get_userid();
-
- my $cfg = PVE::Config::read_file ("storagecfg");
-
- return PVE::Storage::lvm_vgs ();
-}
-
-sub storage_add { ##SOAP_EXPORT##
- my ($class, $storeid, $type, $param) = @_;
-
- my $userid = $class->$get_userid();
-
- PVE::Storage::storage_add ($storeid, $type, $param);
-}
-
-sub storage_set { ##SOAP_EXPORT##
- my ($class, $storeid, $param, $digest) = @_;
-
- my $userid = $class->$get_userid();
-
- PVE::Storage::storage_set ($storeid, $param, $digest);
-}
-
-sub storage_remove { ##SOAP_EXPORT##
- my ($class, $storeid, $digest) = @_;
-
- my $userid = $class->$get_userid();
-
- PVE::Storage::storage_remove ($storeid, $digest);
-}
-
-sub storage_enable { ##SOAP_EXPORT##
- my ($class, $storeid, $digest) = @_;
-
- my $userid = $class->$get_userid();
-
- PVE::Storage::storage_enable ($storeid, $digest);
-}
-
-sub storage_disable { ##SOAP_EXPORT##
- my ($class, $storeid, $digest) = @_;
-
- my $userid = $class->$get_userid();
-
- PVE::Storage::storage_disable ($storeid, $digest);
-}
-
-sub storage_scan_nfs { ##SOAP_EXPORT##
- my ($class, $server) = @_;
-
- my $userid = $class->$get_userid();
-
- return PVE::Storage::scan_nfs ($server);
-}
-
-sub storage_scan_iscsi { ##SOAP_EXPORT##
- my ($class, $portal, $skip_used) = @_;
-
- my $userid = $class->$get_userid();
-
- my $res = PVE::Storage::scan_iscsi ($portal);
-
- return $res if !$skip_used;
-
- my $cfg = PVE::Config::read_file ("storagecfg");
-
- my $unused = {};
- foreach my $target (keys %$res) {
- if (!PVE::Storage::target_is_used ($cfg, $target)) {
- $unused->{$target} = $res->{target}
- }
- }
- return $unused;
-}
-
-sub storage_user_info { ##SOAP_EXPORT##
- my ($class, $vmid) = @_;
-
- my $userid = $class->$get_userid();
-
- my $cfg = PVE::Config::read_file ("storagecfg");
-
- my $info = PVE::Storage::storage_info ($cfg);
-
- my $res = { cfg => $cfg };
-
- foreach my $storeid (PVE::Storage::storage_ids ($cfg)) {
- my $scfg = PVE::Storage::storage_config ($cfg, $storeid);
-
- next if $scfg->{disable};
-
- # fixme: check user access rights - pass username with connection?
-
- $res->{info}->{$storeid} = $info->{$storeid};
-
- if ($scfg->{content}->{rootdir}) {
- $res->{rootdir}->{$storeid} = 1;
- $res->{rootdir_default} = $storeid
- if !$res->{rootdir_default};
- }
-
- if ($scfg->{content}->{vztmpl}) {
- $res->{vztmpl}->{$storeid} = 1;
- $res->{vztmpl_default} = $storeid
- if !$res->{vztmpl_default};
- }
-
- if ($scfg->{content}->{images}) {
- $res->{images}->{$storeid} = 1;
- $res->{images_default} = $storeid
- if !$res->{images_default};
- }
-
- if ($scfg->{content}->{iso}) {
- $res->{iso}->{$storeid} = 1;
- $res->{iso_default} = $storeid
- if !$res->{iso_default};
- }
-
- if ($scfg->{content}->{backup}) {
- $res->{backup}->{$storeid} = 1;
- $res->{backup_default} = $storeid
- if !$res->{backup_default};
- }
- }
-
- # include disk list
- if ($vmid) {
- $res->{imagelist} = PVE::Storage::vdisk_list ($cfg, undef, $vmid);
- }
-
-
- return $res;
-}
-
-sub get_storage_status { ##SOAP_EXPORT##
- my ($class) = @_;
-
- my $userid = $class->$get_userid();
-
- # fixme: check user access rights
-
- my $cfg = PVE::Config::read_file ("storagecfg");
-
- my $info = PVE::Storage::storage_info ($cfg);
-
- return { cfg => $cfg, info => $info };
-}
-
-##FILTER_DATA## do not remove this line
-
-package PVE::SOAPSerializer;
-
-use strict;
-use SOAP::Lite;
-use vars qw(@ISA);
-use HTML::Entities;
-
-@ISA = qw (SOAP::Serializer);
-
-sub new {
- my $class = shift;
-
- my $self = $class->SUPER::new (@_);
-
-# SOAP Serializer bug fix:
-# "a string with embeded URI 'http://exsample.com'" is encoded as URI!
-# should be a string instead
-# 'anyURI' =>
-# [95, sub { $_[0] =~ /^(urn:)|(http:\/\/)/i; }, 'as_anyURI'],
-# regex should be: /^((urn:)|(http:\/\/))/i;
-# so we disbale that
- delete $self->{_typelookup}->{'anyURI'};
-
-# SOAP Serializer bug fix:
-# by default utf8 strings are serialized as base64Binary - unfortunately
-# that way the utf8 flags gets lost, so we provide our own encoding
-# see bug #2860559 on sourgeforge project page
- $self->{_typelookup}->{'utf8string'} =
- [5, sub { Encode::is_utf8($_[0]) }, 'as_utf8string'],
-
- return $self;
-}
-
-sub as_utf8string {
- my ($self, $value, $name, $type, $attr) = @_;
-
- return [
- $name,
- {'xsi:type' => 'xsd:string', %$attr},
- HTML::Entities::encode_entities_numeric ($value)
- ];
-}
-
-package PVE::SOAPTransport;
-
-use strict;
-use vars qw(@ISA);
-use SOAP::Transport::HTTP;
-use MIME::Base64;
-use PVE::SafeSyslog;
-use PVE::Config;
-use POSIX qw(EINTR);
-use POSIX ":sys_wait_h";
-use IO::Handle;
-use IO::Select;
-use vars qw(@ISA);
-
-# This is a quite simple pre-fork server
-
-@ISA = qw(SOAP::Transport::HTTP::Daemon);
-
-my $workers = {};
-
-my $max_workers = 2; # pre-forked worker processes
-my $max_requests = 500; # max requests per worker
-
-sub worker_finished {
- my $cpid = shift;
-
- syslog ('info', "worker $cpid finished");
-}
-
-sub finish_workers {
- local $!; local $?;
- foreach my $cpid (keys %$workers) {
- my $waitpid = waitpid ($cpid, WNOHANG);
- if (defined($waitpid) && ($waitpid == $cpid)) {
- delete ($workers->{$cpid});
- worker_finished ($cpid);
- }
- }
-}
-
-sub test_workers {
- foreach my $cpid (keys %$workers) {
- if (!kill(0, $cpid)) {
- waitpid($cpid, POSIX::WNOHANG());
- delete $workers->{$cpid};
- worker_finished ($cpid);
- }
- }
-}
-
-sub start_workers {
- my $self = shift;
-
- my $count = 0;
- foreach my $cpid (keys %$workers) {
- $count++;
- }
-
- my $need = $max_workers - $count;
-
- return if $need <= 0;
-
- syslog ('info', "starting $need worker(s)");
-
- while ($need > 0) {
- my $pid = fork;
-
- if (!defined ($pid)) {
- syslog ('err', "can't fork worker");
- sleep (1);
- } elsif ($pid) { #parent
- $workers->{$pid} = 1;
- $0 = 'pvedaemon worker';
- syslog ('info', "worker $pid started");
- $need--;
- } else {
- $SIG{TERM} = $SIG{QUIT} = 'DEFAULT';
-
- $SIG{USR1} = sub {
- $self->{reload_config} = 1;
- };
-
- eval {
- # try to init inotify
- PVE::Config::inotify_init();
-
- $self->handle_requests ();
- };
- syslog ('err', $@) if $@;
-
-
- exit (0);
- }
- }
-}
-
-sub terminate_server {
-
- foreach my $cpid (keys %$workers) {
- kill (15, $cpid); # TERM childs
- }
-
- # nicely shutdown childs (give them max 10 seconds to shut down)
- my $previous_alarm = alarm (10);
- eval {
- local $SIG{ALRM} = sub { die "Timed Out!\n" };
-
- 1 while ((my $pid = waitpid (-1, 0)) > 0);
-
- };
- alarm ($previous_alarm);
-
- foreach my $cpid (keys %$workers) {
- !kill (0, $cpid) || kill (9, $cpid); # KILL childs still alive!
- }
-}
-
-sub handle {
- my $self = shift;
- my $daemon = $self->new;
-
- $self->{httpdaemon} = $daemon;
-
- eval {
- my $old_sig_chld = $SIG{CHLD};
- local $SIG{CHLD} = sub {
- finish_workers ();
- &$old_sig_chld(@_);
- };
-
- my $old_sig_term = $SIG{TERM};
- local $SIG{TERM} = sub {
- terminate_server ();
- &$old_sig_term(@_);
- };
- local $SIG{QUIT} = sub {
- terminate_server();
- &$old_sig_term(@_);
- };
-
- local $SIG{USR1} = 'IGNORE';
-
- local $SIG{HUP} = sub {
- syslog ("info", "received reload request");
- foreach my $cpid (keys %$workers) {
- kill (10, $cpid); # SIGUSR1 childs
- }
- };
-
- for (;;) { # forever
- $self->start_workers ();
- sleep (5);
- $self->test_workers ();
- }
- };
- my $err = $@;
-
- if ($err) {
- syslog ('err', "ERROR: $err");
- }
-}
-
-sub send_basic_auth_request {
- my ($c) = @_;
-
- my $realm = 'PVE SOAP Server';
- my $auth_request_res = HTTP::Response->new(401, 'Unauthorized');
- $auth_request_res->header('WWW-Authenticate' => qq{Basic realm="$realm"});
- $auth_request_res->is_error(1);
- $auth_request_res->error_as_HTML(1);
- $c->send_response($auth_request_res);
-}
-
-sub send_error {
- my ($c, $code, $msg) = @_;
-
- $c->send_response(HTTP::Response->new($code, $msg));
-}
-
-sub decode_basic_auth {
- my ($h) = @_;
-
- my $authtxt = $h->header('Authorization');
- return undef if !$authtxt;
- my ($test, $auth) = split /\s+/, $authtxt;
- return undef if !$auth;
-
- my $enc = MIME::Base64::decode ($auth);
-
- return $enc;
-}
-
-sub extract_auth_cookie {
- my ($h) = @_;
-
- my $txt = $h->header('Cookie') || '';
-
- return ($txt =~ /(?:^|\s)PVEAuthTicket=([^;]*)/)[0];
-}
-
-sub ident_user {
- my ($peerport, $sockport) = @_;
-
- my $filename = "/proc/net/tcp";
-
- my $fh = IO::File->new($filename, "r") ||
- die "unable to open file '$filename'\n";
-
- my $user;
-
- my $remoteaddr = sprintf "0100007F:%04X", $sockport;
- my $localaddr = sprintf "0100007F:%04X", $peerport;
-
- while (defined (my $line = <$fh>)) {
- $line =~ s/^\s+//;
- my @data = split (/\s+/, $line);
- if ($data[1] eq $localaddr &&
- $data[2] eq $remoteaddr) {
- my $uid = $data[7];
- $user = getpwuid ($uid);
- last;
- }
- }
-
- close ($fh);
-
- die "unable to identify user connection\n" if !$user;
-
- return $user;
-}
-
-sub handle_login {
- my ($daemon, $c, $r) = @_;
-
- # my $cuser = ident_user ($c->peerport, $c->sockport);
-
- my $h = $r->headers;
- my $action = $h->header('SOAPAction');
- if ($action !~ m|^(\"?)http://proxmox.com/PVE/ConfigServer\#(\w+)(\"?)$|) {
- send_error($c, 400, "Invalid SOAPAction");
- return undef;
- }
- my $method = $2;
- my $ticket = extract_auth_cookie($h);
- my $authheader = $h->header('Authorization');
-
- if (!$ticket) {
- if (!$authheader || $authheader !~ m/^Basic\s+\S+$/) {
- send_basic_auth_request ($c);
- return undef;
- }
- }
-
- my ($user, $group);
-
- $daemon->request($r);
-
- my $update;
-
- if ($authheader) {
- my $auth = (split /\s+/, $authheader)[1];
- my $enc = MIME::Base64::decode ($auth);
- my $pw;
- ($user, $pw) = split (/:/, $enc, 2);
- if ($group = PVE::Utils::is_valid_user ($user, $pw)) {
- $ticket = PVE::Utils::create_auth_ticket ($daemon->{pve}->{secret}, $user, $group);
- $update = 1;
- } else {
- $daemon->make_fault($SOAP::Constants::FAULT_CLIENT,
- 'Basic authentication failed');
- $c->send_response($daemon->response);
- return undef;
- }
- } elsif ($ticket) {
- ($user, $group) = PVE::Utils::verify_ticket ($daemon->{pve}->{secret}, $ticket);
- if (!($user && $group)) {
- $daemon->make_fault($SOAP::Constants::FAULT_CLIENT,
- "Ticket authentication failed - invalid ticket '$ticket'");
- $c->send_response($daemon->response);
- return undef;
- }
- if ($method eq 'update_ticket') {
- $ticket = PVE::Utils::create_auth_ticket ($daemon->{pve}->{secret}, $user, $group);
- }
- } else {
- $daemon->make_fault($SOAP::Constants::FAULT_CLIENT,
- 'Ticket authentication failed - no ticket');
- $c->send_response($daemon->response);
- return undef;
- }
-
- return ($user, $group, $ticket, $update);
-}
-
-sub handle_requests {
- my $self = shift;
-
- my $daemon = $self->{httpdaemon};
-
- my $rcount = 0;
-
- my $sel = IO::Select->new();
- $sel->add ($daemon->{_daemon});
-
- my $timeout = 5;
- my @ready;
- while (1) {
- if (scalar (@ready = $sel->can_read($timeout))) {
-
- if (!$daemon->{pve}->{secret} || $self->{reload_config}) {
- $self->{reload_config} = undef;
- syslog ("info", "reloading configuration")
- if $self->{reload_config};
- $daemon->{pve}->{secret} = PVE::Utils::load_auth_secret();
- }
-
- my $c;
- while (($c = $daemon->accept) || ($! == EINTR)) {
- next if !$c; # EINTR
-
- $c->timeout(5);
-
- $daemon->{pve}->{username} = undef;
- $daemon->{pve}->{groupname} = undef;
- $daemon->{pve}->{ticket} = undef;
-
- # handle requests
- while (my $r = $c->get_request) {
-
- my ($user, $group, $ticket, $update) = handle_login ($daemon, $c, $r);
- last if !$user;
-
- $daemon->{pve}->{username} = $user;
- $daemon->{pve}->{groupname} = $group;
- $daemon->{pve}->{ticket} = $ticket;
- $daemon->SOAP::Transport::HTTP::Server::handle;
-
- if ($update) {
- $daemon->response->header ("Set-Cookie" => "PVEAuthTicket=$ticket");
- }
-
- $c->send_response($daemon->response);
- }
- $rcount++;
-
- # we only handle one request per connection, because
- # we want to minimize the number of connections
-
- $c->shutdown(2);
- $c->close();
- last;
- }
-
- last if !$c || ($rcount >= $max_requests);
-
- } else {
- # timeout
- PVE::Config::poll(); # read inotify events
- }
- }
-}
-
-package PVE::ConfigClient;
-
-use SOAP::Lite;
-use HTTP::Cookies;
-use HTTP::Headers;
-use PVE::Config;
-
-my ($soaphost, $soapport) = PVE::Config::soap_host_port();
-
-sub __create_soaplite {
- my ($timeout, $port, $ticket, $username, $password) = @_;
-
- my $cookie_jar = HTTP::Cookies->new (ignore_discard => 1);
-
- if ($ticket) {
- $cookie_jar->set_cookie(0, 'PVEAuthTicket', $ticket, '/', $soaphost);
- }
-
- my $soap = SOAP::Lite
- -> serializer (PVE::SOAPSerializer->new)
- -> ns('http://proxmox.com/PVE/ConfigServer')
- -> on_fault (sub {
- my($soap, $res) = @_;
- die ref $res ? $res->faultstring : $soap->transport->status, "\n";
- })
- -> proxy("http://$soaphost:$port", timeout => $timeout,
- cookie_jar => $cookie_jar);
-
- if ($username && defined($password)) {
- $soap->proxy->credentials ("$soaphost:$port", 'PVE SOAP Server',
- $username, $password);
- }
-
- return $soap;
-}
-
-sub connect {
- my ($ticket, $cinfo, $cid) = @_;
-
- die "no ticket specified" if !$ticket;
-
- # set longet timeout for local connection
- my $timeout = $cid ? 10 : 120;
-
- my $port = $soapport;
-
- if ($cid) {
- die "invalid cluster ID '$cid'"
- if $cid !~ m/^\d+$/;
- my $ni;
- die "no config for cluster node '$cid'"
- if !($cinfo && ($ni = $cinfo->{"CID_$cid"}));
-
- $port = $ni->{configport};
- }
-
- return __create_soaplite ($timeout, $port, $ticket);
-}
-
-sub update_ticket {
- my ($ticket) = @_;
-
- die "no ticket specified" if !$ticket;
-
-
- if ($ticket !~ m/^((\S+)::\w+::\d+::[0-9a-f]{40})(::[0-9a-f]{40})?$/) {
- die "got invalid ticket '$ticket'\n";
- }
-
- $ticket = $1; # strip second checksum used by PVE::AuthCookieHandler
-
- my $username = $2;
-
- my $timeout = 120;
-
- my $soap = __create_soaplite ($timeout, $soapport, $ticket);
-
- my $nt = $soap->update_ticket()->result;
-
- if ($ticket !~ m/^${username}::\w+::\d+::[0-9a-f]{40}$/) {
- die "got invalid ticket '$ticket'\n";
- }
-
- return $nt;
-}
-
-sub request_ticket {
- my ($username, $password) = @_;
-
- die "no username specified\n" if !$username;
- die "no password specified for user '$username'\n" if !defined ($password);
-
- my $timeout = 120;
-
- my $soap = __create_soaplite ($timeout, $soapport, undef, $username, $password);
-
- my $ticket = $soap->update_ticket()->result;
-
- if ($ticket !~ m/^${username}::\w+::\d+::[0-9a-f]{40}$/) {
- die "got invalid ticket '$ticket'\n";
- }
-
- return $ticket
-}
-
-1;
+++ /dev/null
-package PVE::HTMLControls;
-
-use strict;
-use JSON;
-
-my $uidcount = 0;
-
-my %jsesc = ( "\n" => '\n',
- "\r" => '\r',
- "\t" => '\t',
- "\f" => '\f',
- "\b" => '\b',
- "\"" => '\"',
- "\\" => '\\\\',
- );
-
-sub string_to_js {
- my $str = shift;
- $str =~ s/([\\\"\n\r\t\f\b])/$jsesc{$1}/eg;
- $str =~ s/([\x00-\x07\x0b\x0e-\x1f])/'\\u00' . unpack('H2',$1)/eg;
- return '"' . $str . '"';
-}
-
-sub get_uid {
- my $prefix = shift || 'uid';
-
- $uidcount++;
-
- return $prefix . '_' . $$. '_' .$uidcount;
-}
-
-# Ajax controls
-
-sub create_log_viewer {
- my ($lvid, $service, $serviceid, $filterid, $statusid, $trackid) = @_;
-
- $service = '' if !$service;
-
- # trackid format: UID:$pid:/path/to/executable
-
- $trackid = '' if !$trackid;
-
- my $myupdater = get_uid ($lvid);
-
- my $out = "<script type='text/javascript'><!--\n";
- $out .= <<__EOJS;
-
- var $myupdater = new logViewer ('$lvid', '$service', '$serviceid', '$filterid', '$statusid', '$trackid');
-
- $myupdater.start();
-
-__EOJS
-
- $out .= "--></script>\n";
-
- return $out;
-}
-
-sub create_wsviewer {
- my ($lvid, $statusid, $url, $args, $period) = @_;
-
- my $myupdater = get_uid ($lvid);
-
- $period = 10 if !$period;
-
- $statusid = '' if !$statusid;
-
- my $jsargs = to_json ($args);
- my $out = "<script type='text/javascript'><!--\n";
- $out .= <<__EOJS;
-
- var $myupdater = new wsViewer ('$lvid', '$statusid', $period, '$url', $jsargs);
-
- $myupdater.start();
-
-__EOJS
-
- $out .= "--></script>\n";
-
- return $out;
-}
-
-sub create_periodic_updater {
- my ($lvid, $url, $args, $period) = @_;
-
- $period = 10 if !$period;
-
- my $jsargs = to_json ($args);
-
- $lvid = 'noautoupdate' if !$lvid;
-
- my $out = "<script type='text/javascript'><!--\n";
- $out .= <<__EOJS;
-
- new Ajax.PeriodicalUpdater ('$lvid', '$url', {
- frequency: $period,
- parameters: $jsargs
- });
-
-__EOJS
-
- $out .= "--></script>\n";
- return $out;
-}
-
-# vzlist viewer
-
-sub create_vzlist_viewer {
- my ($lvid, $statusid, $cid) = @_;
-
- my $myupdater = get_uid ($lvid);
-
- my $out = "<script type='text/javascript'><!--\n";
- $out .= <<__EOJS;
-
- var $myupdater = new vzlistViewer ('$lvid', '$statusid', '$cid');
-
- $myupdater.start();
-
-__EOJS
-
- $out .= "--></script>\n";
-
- return $out;
-}
-
-# server time viewer
-
-sub create_time_viewer {
- my ($uid) = @_;
-
- my $out = "\n<script type='text/javascript'><!--\n";
- $out .= <<__EOJS;
-
- new timeViewer ('$uid');
-
-__EOJS
- $out .= "--></script>\n";
-
- return $out;
-}
-
-sub create_command_viewer {
- my ($lvid, $statusid, $abortid, $upid) = @_;
-
- my $jsvar = get_uid($lvid);
-
- return '' if !defined ($upid);
- return '' if !defined ($abortid);
-
- my $out = "\n<script type='text/javascript'><!--\n";
- $out .= <<__EOJS;
-
- var $jsvar = new commandViewer ('$jsvar', '$lvid', '$upid', '$statusid', '$abortid');
-
- $jsvar.start ();
-
-__EOJS
-
- $out .= "--></script>\n";
-
- return $out;
-}
-
-1;
+++ /dev/null
-package PVE::HTMLDropDown;
-
-use strict;
-use vars qw(@ISA);
-
-my $umenuid = 0;
-
-sub new {
- my ($class) = @_;
-
- my $self = {};
- $self->{count}=0;
- $self->{links}=0;
- $self->{uid} = "pvemenu_" . ++$umenuid;
- bless($self);
- return $self;
-}
-
-sub add_item {
- my ($self,$name,$link,$text,$img) = @_;
- if (!(defined($self->{$name}->{count}))) { $self->{$name}->{count}=0; }
- $self->{$name}->{$self->{$name}->{count}}->{link} = $link;
- $self->{$name}->{$self->{$name}->{count}}->{text} = $text;
- $self->{$name}->{$self->{$name}->{count}}->{image} = $img;
- $self->{$name}->{count} = $self->{$name}->{count} + 1;
- $self->{$name}->{menuid} = $self->{uid} . "_" . $name;
-}
-
-sub out_dropdown_menu {
-
- my ($self,$name) = @_;
- my $i;
- my $br=0;
-
- my $image = "/images/iarrdown.png";
-
- my $menuid = $self->{$name}->{menuid};
-
- my $html = "";
- $html .= "<div id=\"$menuid\" onMouseOut =\"dropdown('$menuid',0);\" onMouseOver=\"dropdown('$menuid',1);\" style=\"position:absolute; top:0px; left:0px; visibility: hidden;\">";
-
- $html .= "<span style='width:15px; color:#FFFFFF;'><img alt='' src='$image' border=0></span><br>";
-
- $html .= "<div class='dropdown'>";
- for $i (0 .. ($self->{$name}->{count}-1)) {
-
-
- if ($self->{$name}->{$i}->{text} eq "-" ) {
- $html = $html . "<hr width='175'>";
- $br=0;
- } else {
- if ($br == 1) {$html = $html . "<br>"; }
- my $img = $self->{$name}->{$i}->{image};
- my $imgtxt .= $img ? "<img alt='' src='$img' style='border:0px; vertical-align:text-bottom;'> " : '';
- my $txt = $self->{$name}->{$i}->{text};
- $txt =~ s/ / /g;
- $html .= "<a style='white-space:nowrap;' class='dropdown' id='${menuid}_ddlnk_$i' href='$self->{$name}->{$i}->{link}'>$imgtxt$txt</a>";
- $br=1;
- }
- }
-
- $html .= "</div><br></div>";
-
- return $html;
-}
-
-sub out_symbol {
- my ($self,$name,$shape,$elink) = @_;
- my $html;
-
- my $image = "/images/tarrdown.png";
- if ($shape) {
- $image = "/images/$shape.png";
- }
-
- my $menuid = $self->{$name}->{menuid};
-
- my $lnk_name = $menuid . "_lnk_" . $self->{links};
- if (defined($elink)) { $elink = ",'$elink'"; }
- $html = "<img alt='' style='cursor:pointer;' name='$lnk_name' src='$image' border=0 " .
- "onMousedown=\"javascript:dropdown('$menuid',1,'$lnk_name'$elink);\">";
- $self->{links} = $self->{links} + 1;
- return $html;
-}
-
-1;
-
+++ /dev/null
-package PVE::HTMLForm;
-
-use strict;
-use HTML::Entities;
-use PVE::I18N;
-use PVE::HTMLTable;
-
-sub new {
- my ($type, $formdata, $name) = @_;
- my $self = {};
-
- $self->{formdata} = $formdata;
- $self->{elements} = 0;# internal element counter
- $self->{submit} = 0;
- $self->{name} = $name ? $name : "frm";
-
- bless($self, $type);
-
- $self->{action} = $self->{formdata}->{"form_$self->{name}_submit"};
-
- $self->postaction;
-
- return $self;
-}
-
-sub postaction {
- my ($self) = @_;
-
- my ($key, %d);
-
- # Rebuild Date for IP, Bool and Time fields
- foreach $key (sort keys (%{$self->{formdata}})) {
- if ($key =~ m/ip_[0-9]+_(.*)/) {
- if (!(exists ($d{$1}))) {
- $d{$1}=1;
- defined ($self->{formdata}->{"ip_0_$1"}) ||
- ($self->{formdata}->{"ip_0_$1"} = '0');
- defined ($self->{formdata}->{"ip_1_$1"}) ||
- ($self->{formdata}->{"ip_1_$1"} = '0');
- defined ($self->{formdata}->{"ip_2_$1"}) ||
- ($self->{formdata}->{"ip_2_$1"} = '0');
- defined ($self->{formdata}->{"ip_3_$1"}) ||
- ($self->{formdata}->{"ip_3_$1"} = '0');
- $self->{formdata}->{"$1"} =
- $self->{formdata}->{"ip_0_$1"} . "." .
- $self->{formdata}->{"ip_1_$1"} . "." .
- $self->{formdata}->{"ip_2_$1"} . "." .
- $self->{formdata}->{"ip_3_$1"};
- }
- }
- if ($key =~ m/time_[0-9]+_(.*)/) {
- if (!(exists ($d{$1}))) {
- $d{$1}=1;
- defined ($self->{formdata}->{"time_0_$1"}) ||
- ($self->{formdata}->{"time_0_$1"} = '00');
- defined ($self->{formdata}->{"time_1_$1"}) ||
- ($self->{formdata}->{"time_1_$1"} = '00');
- $self->{formdata}->{"$1"} =
- $self->{formdata}->{"time_0_$1"} . ":" .
- $self->{formdata}->{"time_1_$1"};
- }
- }
- if ($key =~ m/cb_n_(.*)/) {
- if (!(exists ($d{$1}))) {
- my $name = $1;
- $d{$name} = 1;
- my $val = "";
- my $tmp;
- foreach my $k (keys (%{$self->{formdata}})) {
- if ($k =~ m/cb__(\w+)_$name/) {
- $tmp->{$1} = 1;
- }
- }
- foreach my $k (keys (%$tmp)) {
- $val .= " " if $val;
- $val .= $k;
- }
- $self->{formdata}->{"$1"} = $val;
- }
- }
- if ($key =~ m/bool_n_(.*)/) {
- if (!(exists ($d{$1}))) {
- $d{$1}=1;
- my $val = "0";
- if ($self->{formdata}->{"bool_$1"}) {
- $val = "1";
- }
- $self->{formdata}->{"$1"} = $val;
- }
- }
- }
-}
-
-sub action {
- my ($self) = @_;
- return $self->{action};
-}
-
-sub create_element {
- my ($self, $name, $type, $value, $opt, $width) = @_;
-
- my $out = '';
-
- my $class = 'normal';
-
- my $encvalue = encode_entities ($value);
-
- $width = 200 if !$width;
-
- my $innerwidth = $width - 5; # width - margin - border - padding
-
- my $widthstr = "style='width:${innerwidth}px;'";
-
- # normal text
- if ($type eq "text") {
- $out .= "<input $widthstr class='$class' type='text' name=$name value='$encvalue'/>";
- }
- elsif ($type eq "textarea") {
- my $rows = $opt || 4;
- my $rh = int ($rows*int(1.2*12+1));
- $out .= "<textarea class='$class' name=$name style='width:${innerwidth}px;height:${rh}px;' ROWS=$rows>$value</textarea>";
- }
- elsif ($type eq "viewonly") {
- $out .= "<input $widthstr disabled class='$class' readonly type='text' value='$encvalue'></input>";
- }
- # read only text
- elsif ($type eq "rotext") {
- $out .= "<input readonly $widthstr class='$class rotext' type='text' " .
- "name=${name} title='$encvalue' value='$encvalue'/>";
- }
- # server time
- elsif ($type eq "rotime") {
- my $uid = PVE::HTMLControls::get_uid('mytimer');
- $out .= "<div $widthstr class='bool input' id='$uid'>$encvalue</div>";
- $out .= PVE::HTMLControls::create_time_viewer ($uid);
- }
- # time of day
- elsif ($type eq "time") {
- my @tmp = split(/:/, $value);
- for my $i (0..1) {
- $out .= "<input type=text name=time_${i}_$name class='$class time' value='$tmp[$i]' />";
- $out .= " : " if !$i;
- }
- }
- # password
- elsif ($type eq "password") {
- $out .= "<input $widthstr class='$class' type='password' name=$name value='$encvalue'/>";
- }
- # number
- elsif ($type eq "number") {
- $out .= "<input $widthstr class='$class' type='text' id='$name' name='$name' value='$encvalue'/>";
- }
- # float
- elsif ($type eq "float") {
- $out .= "<input $widthstr class='$class' type='text' id='$name' name='$name' value='$encvalue'/>";
- }
- # boolean value (0, 1)
- elsif ($type eq "bool" || $type eq "robool" || $type eq 'dynamicbool' || $type eq "nbool") {
- my $checked = $value ? 'checked' : '';
- my $id = "bool_$name";
-
- $out .= "<label><div class='$class bool' style='width:${innerwidth}px;text-align:center;vertical-align:bottom;'>";
- $out .= " ";
- if ($type eq 'dynamicbool') {
- $out .= "<input type='checkbox' name='$id' id='$id' $checked " .
- "onClick='javascript:pve_form_save(\"$self->{name}\", \"post\");'/>";
- } elsif ($type eq "robool") {
- $out .= "<input type='checkbox' disabled name='${id}_ro' $checked/>";
- } else {
- $out .= "<input type='checkbox' name='$id' id='$id' $checked/>";
- }
-
- $out .= " ";
- $out .= "</div></label>";
- if ($type eq "robool") {
- $out .= "<input type='hidden' name='$id' id='$id' $checked/>";
- }
- $out .= "<input type='hidden' name='bool_n_$name' id='bool_n_$name' value='1'/>";
- }
- # dropdown
- elsif ($type eq "dropdown" || $type eq "dynamicdropdown") {
-
- my $table = PVE::HTMLTable->new ([]);
-
- my $titles;
- my $values;
- my $defvalue;
- if (ref($opt) eq 'ARRAY') {
- $values = $opt;
- } else {
- $values = $opt->{values};
- $defvalue = $opt->{default};
- foreach my $head (@{$opt->{titles}}) {
- push @$titles, 1, undef, $head;
- }
- }
-
- $table->add_headline ($titles) if $titles;
-
- if (defined($value)) {
- my $found;
- my $first;
- foreach my $elem (@$values) {
- my ($ev, $et, @da);
- if (ref ($elem) eq 'ARRAY') {
- ($ev, $et, @da) = @$elem;
- } else {
- $ev = $et = $elem;
- }
- $first = $ev if !$first;
- $found = 1 if $ev eq $value;
- }
- if (!$found) {
- $value = defined ($defvalue) ? $defvalue : $first;
- }
- }
-
- foreach my $elem (@$values) {
- my ($ev, $et, @da);
- if (ref ($elem) eq 'ARRAY') {
- ($ev, $et, @da) = @$elem;
- } else {
- $ev = $et = $elem;
- }
-
- push @da, $et if !scalar (@da);
-
- if (!defined($value)) {
- $value = defined ($defvalue) ? $defvalue : $ev;
- }
-
- my $checked = ($ev eq $value) ? 'checked="checked"' : '';
-
- my $inp = "<input type='radio' short='$et' name='$name' value='$ev' $checked />";
- my @line;
- foreach my $dv (@da) {
- if ($inp) {
- push @line, "$inp$dv";
- $inp = undef;
- } else {
- push @line, $dv;
- }
- }
-
- $table->add_row ('', @line);
- }
-
- my $width1 = $width - 25;
- $out .= "<div class='selectblock' style='width:${width}px;position:relative;' id='selectblock_$name'>";
- $out .= "<div class='$class bool' style='white-space:nowrap;overflow:hidden;'><div style='display:block;float:right;'><img alt='' src='/images/tarrdown.png'></div><div style='width:${width1}px;overflow:hidden;'><span>$value</span></div></div>";
-
- $out .= "<div class='selectbox'>";
- $out .= $table->out_table();
- $out .= "</div>";
- $out .= "</div>";
-
- $out .= "<script language='javascript' type='text/javascript'>";
- if ($type eq "dynamicdropdown") {
- $out .= "new Selectbox('selectblock_$name','$self->{name}');";
- } else {
- $out .= "new Selectbox('selectblock_$name');";
- }
- $out .= "</script>";
- }
- # checkbox
- elsif ($type eq "checkbox") {
- my ($rows, $elref) = @$opt;
- my $sel;
- my @element = @$elref;
- map { $sel->{$_} = 1; } split ('\s', $value);
- $out .= "<table cellspacing=2 style='width:${width}px;' class='checkbox'>";
- for my $i (0 .. $#element/$rows) {
- $out .= "<tr>";
- for (my $j = 0; $j < $rows; $j++) {
- my $ind = $i*$rows + $j;
- last if $ind > $#element;
- my ($ev, $et) = ($element[$ind][0], $element[$ind][1]);
- my $val = $sel->{$ev} ? 'checked=true' : '';
- $out .= "<td><label>$et <input $val type=checkbox name='cb__${ev}_$name'></input></label></td>";
- }
- $out .= "</tr>";
- }
- $out .= "</table>";
- $out .= "<input type=hidden name='cb_n_$name' value='$#element'/>";
- }
- # ip address
- elsif ($type eq "ip") {
- my @tmp = split(/\./, $value);
-
- $out .= "<table border=0 cellspacing=0 cellpadding=0><tr>";
- for my $i (0..3) {
- my $id = "ip_${i}_$name";
- my $nextid = $i < 3 ? "ip_" . ($i+1) . "_$name" : '';
- my $float = "style='float:left;";
- $out .= <<__EOD;
-<td><input class='$class ip' type='text' id='$id' name='$id' value='$tmp[$i]'
- onKeyUp="pve_form_validate_natural('$id', 255);"
- onKeyDown="return pve_form_ip_keyfilter(event,'$id','$nextid');"
-/>
-__EOD
- if ($i != 3) {
- $out .= "<td align=center style='width:8px;font-family:ARIAL;" .
- "font-weight:bold; font-size:14px;'>.</td>";
- }
- }
- $out .= "</tr></table>";
-
- }
- # file upload
- elsif ($type eq "file") {
- # most wrowsers (firefox) ignore setting 'width', dont know how to fix
- $out .= "<input $widthstr class='$class' type='file' id='$name' name='$name'/>";
- }
- # hidden input
- elsif ($type eq "hidden") {
- if (defined ($value)) {
- $out .= "<input type='hidden' id='$name' name=$name value='$encvalue'/>";
- }
- }
- # Day of week
- elsif ($type eq "dow") {
- my $cl = { mon => '', tue => '', wed => '', thu => '',
- fri => '', sat => '', sun => '' };
- foreach my $day (split (/\s+/, $value)) {
- $cl->{$day} = 'checked';
- }
- my @dn = split (/\s+/, __("Mon Tue Wed Thu Fri Sat Sun"));
- my $w='15%';
- $out .= "<div $widthstr class='bool'><table border=0 cellspacing=2 cellpadding=0>";
- $out .= "<tr align=center><td width='$w'>$dn[0]<td width='$w'>$dn[1]<td width='$w'>$dn[2]";
- $out .= "<td width='$w'>$dn[3]<td width='$w'>$dn[4]<td width='$w'>$dn[5]<td width='$w'>$dn[6]</tr>";
- $out .= "<tr align=center>";
- $out .= "<td><input type=checkbox $cl->{mon} name='$name' value=mon>";
- $out .= "<td><input type=checkbox $cl->{tue} name='$name' value=tue>";
- $out .= "<td><input type=checkbox $cl->{wed} name='$name' value=wed>";
- $out .= "<td><input type=checkbox $cl->{thu} name='$name' value=thu>";
- $out .= "<td><input type=checkbox $cl->{fri} name='$name' value=fri>";
- $out .= "<td><input type=checkbox $cl->{sat} name='$name' value=sat>";
- $out .= "<td><input type=checkbox $cl->{sun} name='$name' value=sun>";
- $out .= "</tr></table></div>";
- }
- else {
- die "unknown elemet type '$type'";
- }
-
- $out .= "\n";
-
- return $out;
-}
-
-sub create_cmdbutton {
- my ($self, $type, $text) = @_;
-
- my $href = "javascript:pve_form_save(\"$self->{name}\", \"$type\");";
-
- my $out = "<img alt='' style='vertical-align:text-bottom;width:15px; height:15px;' src='/images/tarrright.png'> ";
-
- $text = $type if !$text;
-
- if ($type eq "save") {
- $text = __('save');
- } elsif ($type eq "search") {
- $text = __('search');
- } elsif ($type eq "create") {
- $text = __('create');
- } elsif ($type eq "upload") {
- $text = __('upload');
- }
-
- $out .= "<a href='$href' class='frmsubmit'>$text</a>";
-
- return $out;
-}
-
-sub create_header {
- my ($self, $action) = @_;
-
- $action = '' if !$action;
-
- return "<form style='margin:0px;' id='$self->{name}' action='$action' method='POST' ENCTYPE='multipart/form-data' accept-charset='UTF-8'>";
-}
-
-sub create_footer {
- my $self = shift;
-
- my $out = $self->create_element("form_$self->{name}_submit", 'hidden', 'post');
- $out .= "</form>";
-
- return $out;
-}
-
-1;
+++ /dev/null
-package PVE::HTMLGrid;
-
-use strict;
-
-# define some symbolic names for standard widths used
-my $col_widths = {
- fw => 735, # overall form width
-
- fw1 => 150, # col1
- fw2 => 205, # col2
- fw4 => 205, # col4
-};
-
-# compute width of col3
-$col_widths->{fw3} = $col_widths->{fw} -
- $col_widths->{fw1} - $col_widths->{fw2} - $col_widths->{fw4};
-
-$col_widths->{fw3to4} = $col_widths->{fw3} + $col_widths->{fw4};
-$col_widths->{fw2to4} = $col_widths->{fw2} +
- $col_widths->{fw3} + $col_widths->{fw4};
-
-sub get_width {
- my $name = shift;
-
- die "internal error" if !defined ($col_widths->{$name});
- return $col_widths->{$name};
-}
-
-sub new {
- my ($type, @wa) = @_;
-
- my $self = {};
-
- $self->{rowcount} = 0;
- $self->{colums} = scalar (@wa);
- $self->{data} = [];
-
- my @awidth;
- my @aalign;
- foreach my $wd (@wa) {
- my ($w, $align) = split (/:/, $wd);
-
- my $rw = $col_widths->{$w};
- $w = $rw if defined ($rw);
-
- push @awidth, $w;
- push @aalign, $align;
- }
-
- $self->{widths} = [ @awidth ];
- $self->{aligns} = [ @aalign ];
-
-
- bless($self);
-
- return $self;
-}
-
-sub add_row {
- my ($self, @cols) = @_;
-
- push @{$self->{data}}, [ @cols ];
-}
-
-sub html {
- my ($self) = @_;
-
- my $out = "<table class=grid border=0 cellspacing=0 cellpadding=2>";
- my $widths = $self->{widths};
- my $aligns = $self->{aligns};
- for (my $i = 0; $i < $self->{colums}; $i++) {
- $out .= "<COL width='@$widths[$i]'>";
- }
-
- foreach my $ca (@{$self->{data}}) {
- $out .= "<tr>";
-
- for (my $i = 0; $i < $self->{colums}; $i++) {
-
- my $align = @$aligns[$i] ? "align='@$aligns[$i]'" : '';
- $out .= "<td $align>@$ca[$i]</td>"
- }
-
- $out .= "</tr>";
- }
- $out .= "</table>";
-
- $self->{rowcount} = 0;
- $self->{data} = [];
-
- return $out;
-}
-
-1;
+++ /dev/null
-package PVE::HTMLServices;
-
-use strict;
-use CGI '3.12';
-use mod_perl2;
-use Apache2::Const qw(:common);
-use HTML::Entities;
-use JSON;
-use IO::File;
-use POSIX qw(tzset strftime);
-use Text::Wrap qw(wrap);
-use PVE::Config;
-use PVE::I18N;
-use PVE::ConfigServer;
-use PVE::HTMLUtils;
-use PVE::HTMLTable;
-use PVE::SafeSyslog;
-
-$PVE::HTMLServices::Obj = bless {
- helo => 'Helo',
-
- methods => {
- index => { proto => "index ()" },
- command => { proto => "command (upid, did)" },
- command_abort => { "command_abort (upid)" },
- status => { proto => "status (cid)" },
- status_update => { proto => "status_update (cid)" },
- vzlist => { proto => "vzlist (cid)" },
- vmops => { proto => "vmops (inactive)" },
- vmlogview => { proto => "vmlogview (cid, veid, service)" },
- viewlog => { proto => "viewlog (service, filter)" },
- vmstatus => { proto => "vmstatus (cid, veid, type)" },
- hello => { proto => "hello ()" },
- servertime => { proto => "servertime ()" },
- },
-
-};
-
-sub ws_json_hello {
- my($conn, $args) = @_;
-
- return {
- name => "A JSON Example",
- value => [ 'a', 'b'],
- };
-}
-
-sub ws_servertime {
-
- # trak TZ changes
-
- POSIX::tzset();
-
- my ($sec, $min, $hour) = localtime (time());
-
- return sprintf ("%02d:%02d:%02d", $hour, $min, $sec);
-}
-
-sub ws_json_vzlist {
- my($conn, $args) = @_;
-
- my $cid = $args->{"cid"};
-
- my $html;
- my $status;
-
- eval {
- my $cvzl = PVE::Cluster::vzlist_update ($cid, $conn->{ticket});
- die "no data" if !$cvzl;
- $html = PVE::HTMLUtils::create_vzlist_table ($cid, $cvzl->{"CID_$cid"});
-
- };
-
- my $err = $@;
-
- if ($err) {
- syslog ('err', $err);
- $html = "Unable to get data for Cluster Node $cid<br>";
- $status = "<blink><font color=red>Unable to load local cluster table</blink>";
- }
-
- return {
- html => $html,
- status => $status || "Online",
- };
-}
-
-sub ws_json_status {
- my($conn, $args) = @_;
-
- my $cid = $args->{"cid"};
- my $verbose = $args->{"verbose"};
-
- my $html;
-
- my $cinfo = PVE::Cluster::clusterinfo ();
-
- eval {
- my $rcon = PVE::ConfigClient::connect ($conn->{ticket}, $cinfo, $cid);
- my $status = $rcon->ping()->result;
- $html = PVE::HTMLUtils::create_host_status ($cinfo, $status, $verbose);
- };
-
- my $err = $@;
-
- if ($err) {
- syslog ('err', $err);
-
- return {
- html => encode_entities ("ERROR: $err"),
- status => "Unable to get data for Cluster Node $cid<br>",
- };
- }
-
- return {
- html => $html,
- status => "Online",
- };
-}
-
-sub ws_status_update {
- my($conn, $args) = @_;
-
- my $cid = $args->{"cid"};
-
- my $html;
-
- my $cinfo = PVE::Cluster::clusterinfo ();
-
- my $ni = $cinfo->{"CID_$cid"};
-
- my $role = '-';
- my $name = "Node $cid";
- my $nodeip = '-';
-
- eval {
-
- die "unknown CID '$cid'\n" if !$ni;
-
- $role = $ni->{role};
- $role = 'Master' if $role eq 'M';
- $role = 'Node' if $role eq 'N';
-
- $name = $ni->{name};
- $nodeip = $ni->{ip};
-
- my $rcon = PVE::ConfigClient::connect ($conn->{ticket}, $cinfo, $cid);
-
- my $status = $rcon->ping()->result;
-
- my $state = $status->{insync} ? 'active' : '<blink><font color=red>nosync</font></blink>';
-
- my $mem = int (0.5 + ($status->{meminfo}->{mbmemused}*100/$status->{meminfo}->{mbmemtotal}));
- my $disk = int (0.5 + ($status->{hdinfo}->{root}->{used}*100/$status->{hdinfo}->{root}->{avail}));
-
- my $cpu = int ($status->{cpu}*100);
- my $wait = int ($status->{wait}*100);
-
- $html = "<td>$name</td><td>$nodeip</td><td>$role</td><td>$state</td>" .
- "<td>$status->{uptime}->{uptimestrshort}</td>" .
- "<td>$status->{uptime}->{avg1}</td>" .
- "<td>$cpu%</td><td>$wait%</td><td>$mem%</td><td>$disk%</td>";
-
- };
-
- my $err = $@;
-
- if ($err) {
- syslog ('err', $err);
- my $state = "<blink><font color=red>ERROR: " . encode_entities ($err) . "</blink>";
- return "<td>$name</td><td>$nodeip</td><td>$role</td><td colspan=7>$state</td>";
- }
-
- return $html;
-}
-
-sub ws_json_vmstatus {
- my($conn, $args) = @_;
-
- my $cid = $args->{"cid"};
- my $veid = $args->{"veid"};
- my $type = $args->{"type"};
-
- my $html;
- my $status = '';
-
- my $cinfo = PVE::Cluster::clusterinfo ();
-
- eval {
- my $vzinfo = PVE::Cluster::load_vmconfig ($cinfo, $cid, $veid, $type, $conn->{ticket});
- $html = PVE::HTMLUtils::create_vmstatus ($cid, $veid, $type, $vzinfo);
- };
-
- my $err = $@;
-
- if ($err) {
- syslog ('err', $err);
- $html = "Unable to get data for VM $veid<br>";
- $status = "<blink><font color=red>Unable to load virtual machine config</blink>";
- }
-
- return {
- html => $html,
- status => $status,
- };
-}
-
-sub ws_json_vmlogview {
- my($conn, $args) = @_;
-
- my $cid = $args->{"cid"};
- my $veid = $args->{"veid"};
- my $service = $args->{"service"};
-
- my $html = '';
- my $status;
-
- my $cinfo = PVE::Cluster::clusterinfo ();
-
- eval {
- my $ni = $cinfo->{"CID_$cid"} || die "unknown CID '$cid'";
-
- my $rcon = PVE::ConfigClient::connect ($conn->{ticket}, $cinfo, $cid);
- my $lines = $rcon->vmlogview($cid, $veid, $service)->result;
-
- foreach my $line (@$lines) {
- my $el = encode_entities ($line) . "<br>\n";
- if ($service eq 'init') {
- $el =~ s/&\#27;\[0;31m(.*)&\#27;\[0;39m/<font color=red>$1<\/font>/g;
- $el =~ s/&\#27;\[31m(.*)&\#27;\[39;49m/<font color=red>$1<\/font>/g;
- $el =~ s/&\#27;\[33m(.*)&\#27;\[39;49m/<font color=yellow>$1<\/font>/g;
- $el =~ s/&\#27;\[0;32m(.*)&\#27;\[0;39m/<font color=green>$1<\/font>/g;
- $el =~ s/&\#27;\[\d+G//g;
- }
- $html .= $el;
- }
- };
-
- my $err = $@;
-
- if ($err) {
- syslog ('err', $err);
- $html = "Unable to get data for Cluster Node $cid<br>";
- $status = "<blink><font color=red>Unable to load local cluster table</blink>";
- }
-
- return {
- html => $html,
- status => $status || "Online",
- };
-}
-
-# parse syslog line
-sub syslog_parse_line {
- my ($line) = @_;
-
- my $rec;
-
- if ($line =~
- m/^(\S+\s+\S+\s+\S+)\s+(\S+)\s+([^\s\[:]+)(\[(\S+)\])?([^:]*):\s+(.*)$/) {
- $rec->{date} = $1;
- $rec->{host} = $2;
- $rec->{prog} = $3;
- $rec->{prog} .= " $6" if $6;
- $rec->{pid} = $5;
- $rec->{text} = $7;
- } else {
- if ($line =~
- m/^(\S+\s+\S+\s+\S+)\s+(\S+)\s+(last message repeated \d+ times)$/) {
- $rec->{date} = $1;
- $rec->{host} = $2;
- $rec->{prog} = 'syslog';
- $rec->{pid} = 0;
- $rec->{text} = $3;
- } else {
- # unknown log format
- $rec->{date} = "0";
- $rec->{host} = "unknown";
- $rec->{prog} = "unknown";
- $rec->{pid} = "0";
- $rec->{text} = $line;
- }
- }
-
- if (lc ($rec->{prog}) eq '/usr/sbin/cron') {
- $rec->{prog} = 'cron';
- }
-
- return $rec;
-}
-
-sub ws_json_viewlog {
- my($conn, $args) = @_;
-
- my $out = '';
-
- my $filter = $args->{"filter"};
- my $service = $args->{"service"} || '';
- my $trackid = $args->{"trackid"} || '';
-
- $filter =~ s|\\|\\\\|g;
- $filter =~ s/\?/\\\?/g;
- $filter =~ s/\(/\\\(/g;
- $filter =~ s/\)/\\\)/g;
- $filter =~ s/\{/\\\{/g;
- $filter =~ s/\}/\\\}/g;
- $filter =~ s/\[/\\\[/g;
- $filter =~ s/\]/\\\]/g;
- $filter =~ s/\./\\\./g;
- $filter =~ s/\*/\\\*/g;
- $filter =~ s/\+/\\\+/g;
-
- my $filename= "/var/log/syslog";
-
- my $limit = 100;
-
- if ($service eq 'apache') {
- $filename = "/var/log/apache2/access.log";
- }
-
- my $running = 0;
-
- if ($trackid) {
- my $rcon = PVE::ConfigClient::connect ($conn->{ticket});
- $running = $rcon->check_worker ($trackid)->result;
- }
-
- $out .= "<table border=0 cellspacing=3 cellpadding=0 style='font-family:monospace;'>";
-
- if ($filename eq '/var/log/syslog') {
- my $loga;
- my $needhost;
-
- open (TMP, "tail -$limit $filename|");
- while (my $line = <TMP>) {
- if (my $rec = syslog_parse_line ($line)) {
- next if $filter && $line !~ m/$filter/i;
- next if ($service && ($rec->{prog} !~ m"(^$service\/|\/$service$|^$service$)"));
-
- push @$loga, $rec;
- }
- }
- close (TMP);
-
-
- foreach my $rec (@$loga) {
- $out .= "<tr><td nowrap>" . encode_entities ($rec->{date}) . " </td>";
- if ($needhost) {
- $out .= "<td nowrap>" . encode_entities ($rec->{host}) . "</td>";
- }
-
- $rec->{prog} =~ s|^postfix/||;
-
- $out .= "<td nowrap>" . encode_entities ($rec->{prog}) . "</td>";
- $out .= "<td align=right nowrap>" . $rec->{pid} . " </td>";
- $out .= "<td nowrap>" . encode_entities ($rec->{text}) . "</td>";
- $out .= "</tr>";
- }
- } else {
- open (TMP, "tail -$limit $filename|");
- while (my $line = <TMP>) {
- chomp $line;
- next if $filter && $line !~ m/$filter/i;
- $line = encode_entities ($line);
- $out .= "<tr><td nowrap>" . $line . "</td></tr>";
- }
- close (TMP);
- }
- $out .= "</table>\n";
-
- if ($trackid) {
- return {
- html => $out,
- status => $running ? "Update in progress" : "Update finished",
- running => $running,
- };
- } else {
- return {
- html => $out,
- status => "Online",
- running => 1,
- };
- }
-}
-
-sub ws_json_vmops {
- my($conn, $args) = @_;
-
- my $inactive = $args->{"inactive"};
-
- my $vmops = PVE::Config::read_file ("vmops");
- my $out = PVE::HTMLUtils::create_vmops_table ($vmops, $inactive);
-
- return { html => $out, status => 'OK' };
-}
-
-sub ws_command_abort {
- my($conn, $args) = @_;
-
- my $upid = $args->{"upid"};
-
- my $rcon = PVE::ConfigClient::connect ($conn->{ticket});
- $rcon->check_worker ($upid, 1);
-}
-
-sub ws_json_command {
- my($conn, $args) = @_;
-
- my $out = '';
-
- my $upid = $args->{"upid"};
- my $jsvar = $args->{"jsvar"};
-
- my $upid_hash = PVE::Utils::upid_decode ($upid);
-
- my $cmdtype = $upid_hash->{type}; # 'vmops', 'apldownload'
-
- if (!$upid_hash || !$upid_hash->{filename}) {
- return {
- html => '',
- running => 0,
- status => "got strange parameters $upid"
- };
- }
-
- my $filename = $upid_hash->{filename};
-
- my $fh = new IO::File $filename, "r";
- if (!defined ($fh)) {
- return {
- html => '',
- running => 1,
- status => "unable to open output file '$filename'" };
- }
-
- my $savedid = <$fh>;
- chomp $savedid;
-
- if ($savedid ne $upid) {
- return { html => '', running => 0, status => "no data"};
- }
-
- my $out = '';
- my $line;
-
- while (defined ($line = <$fh>)) {
- chomp $line;
-
- # skip ssh warning
- next if $line =~ m/^tcgetattr: Inappropriate ioctl for device$/;
-
- my $stat = '';
- while (defined ($line) && $line =~ m/^rsync\s+status:/) {
- $stat = $line;
- if (defined ($line = <$fh>)) {
- chomp $line;
- }
- }
-
- $out .= encode_entities ($stat) . "<br>" if $stat;
-
- $out .= encode_entities ($line) . "<br>" if defined ($line);;
- }
-
- $fh->close;
-
- my $rcon = PVE::ConfigClient::connect ($conn->{ticket});
- my $running = $rcon->check_worker ($upid)->result;
-
- my $status;
-
- if ($cmdtype eq 'apldownload') {
- $status = $running ? "downloading '$upid_hash->{apl}'" : "download finished";
- } else {
- $status = $running ? "executing command" : "command finished";
- }
- return {
- html => $out,
- status => $status,
- running => $running,
- };
-}
-
-sub ws_index {
- my($conn, $args) = @_;
-
- my $obj = $conn->{server};
-
- my $out = "Proxmox Web Service Description<br><br>";
-
- foreach my $m (keys %{$obj->{methods}}) {
- my $proto = $obj->{methods}->{$m}->{proto};
- $out .= "METHOD: $proto<br>";
- }
-
- return $out;
-}
-
-sub handler ($$) {
- my($obj, $r) = @_;
-
- my $auth_type = $r->ap_auth_type;
- my $uri = $r->uri;
-
- my $cookie_name = $auth_type->cookie_name ($r);
- my $cookie = $auth_type->key ($r);
-
- my ($username, $group) = split /::/, $cookie;
-
- my $conn = {
- server => $obj,
- request => $r,
- uri => $uri,
- user => $username,
- group => $group,
- ticket => $cookie,
- };
-
- my $pvecfg = PVE::Config::read_file ('pvecfg');
- my $language = $pvecfg->{language} || 'C';
- PVE::I18N::set_lang ($language);
-
- my $path = $r->path_info;
- if ($path =~ m'^/?(\w+)(\.htm|\.pl)?$' && $obj->{methods}->{$1}) {
- my $name = $1;
-
- my $cgi = CGI->new ($r);
-
- my $arglist = $cgi->Vars();
-
- $r->no_cache (1);
-
- if (my $serv = $obj->can ("ws_script_$name")) {
- my $data = &$serv ($conn, $arglist);
- my $x = length ($data);
- $r->content_type ('application/javascript');
- $r->headers_out->set ("Content-length", "$x");
- $r->headers_out->set ("Pragma", "no-cache");
- $r->print ($data);
- return OK;
- } elsif (my $serv = $obj->can ("ws_json_$name")) {
- my $data = &$serv ($conn, $arglist);
- my $js = to_json($data, {utf8 => 1});
- my $x = length ($js);
- $r->content_type ('application/json');
- $r->headers_out->set ("Content-length", "$x");
- $r->headers_out->set ("Pragma", "no-cache");
- $r->print ($js);
- return OK;
- } elsif (my $serv = $obj->can ("ws_$name")) {
- my $data = &$serv ($conn, $arglist);
- my $x = length ($data);
- $r->content_type ('text/html');
- $r->headers_out->set ("Content-length", "$x");
- $r->headers_out->set ("Pragma", "no-cache");
- $r->print ($data);
- return OK;
- } else {
- return NOT_FOUND;
- }
- } else {
- return NOT_FOUND;
- }
-
- return OK;
-}
-
-1;
+++ /dev/null
-package PVE::HTMLTable;
-
-use strict;
-use vars qw(@ISA);
-
-sub new {
- my ($type, $width) = @_;
-
- my $self = {};
-
- $self->{rowcount} = 0;
- $self->{link_edit} = '';
- $self->{width} = $width;
- bless($self);
-
- return $self;
-}
-sub link_edit {
- my ($self, $v) = @_;
- if (defined($v)) {
- $self->{link_edit} = $v;
- }
- $self->{link_edit};
-}
-
-sub add_headline {
- my ($self,$headinfo) = @_;
- $self->{headline} = $headinfo;
-}
-
-sub set_param {
- my ($self, $v) = @_;
- if (defined($v)) {
- $self->{rowdata}->{$self->{rowcount}}->{param} = $self->{rowdata}->{$self->{rowcount}}->{param} . "&" . $v;
- }
- return "";
-}
-sub get_param {
- my ($self, $row) = @_;
- if (defined($row)) {
- return $self->{rowdata}->{$row}->{param};
- } else {
- return "";
- }
-}
-sub set_row_link {
- my ($self,$lnk,$row) = @_;
- my $i;
- if (!(defined($row))) { $row = $self->{rowcount}; }
- $self->{rowdata}->{$row}->{lnk} = $lnk;
- return $self;
-}
-
-sub set_col_span {
- my ($self,$span,$row) = @_;
- if (!(defined($row))) { $row = $self->{rowcount}; }
- $self->{rowdata}->{$row}->{span} = $span;
- return $self;
-}
-
-sub add_row {
- my ($self,$id,@row) = @_;
- my $i;
-
- $self->{rowdata}->{$self->{rowcount}}->{len} = $#row;
- $self->{rowdata}->{$self->{rowcount}}->{id} = $id;
-
- for $i (0 .. $#row) {
- $self->{rowdata}->{$self->{rowcount}}->{"$i"} = $row[$i];
- }
- $self->{rowcount} = $self->{rowcount} + 1;
- return $self;
-}
-
-sub out_header {
- my ($self, $width) = @_;
-
- # NOTE: width = 100% if not specified
- # but you can also pass 0 or '' to avoid that behaviour
-
- if (!defined ($width)) { $width='100%'; }
-
- my $htmlout = "<table class='normal' cellspacing=0 cellpadding=3";
-
- $htmlout .= " style='width:$width;'" if $width;
-
- $htmlout .= ">";
-
- return $htmlout;
-}
-
-sub out_headline {
- my ($self) = @_;
-
- return "" if !$self->{headline};
-
- my @headinfo = @{$self->{headline}};
-
- my $htmlout = "<thead><tr>";
- for my $i (0 .. ($#headinfo/3)) {
- my ($span, $width, $text) = ($headinfo[$i*3], $headinfo[($i*3)+1],$headinfo[($i*3)+2]);
- $htmlout .= "<th colspan=$span ";
- $htmlout .= " style='width:$width;'" if $width;
- $htmlout .= ">$text</th>";
- }
- $htmlout .= "</tr></thead>";
- return $htmlout;
-}
-
-
-sub out_footer {
- my ($self) = @_;
-
- return "</table>";
-}
-
-sub out_celldata {
- my ($self,$row,$col) = @_;
- my $data = $self->{rowdata}->{"$row"}->{"$col"};
- return $data;
-}
-
-sub out_table {
- my ($self, $width, $sel) = @_;
-
- my $htmlout = "";
- my $col1 = "#EDEDED";
- my $col2 = "#FFFFFF";
- my $col3 = "#FFF3BF";
- # Tableheader
- $htmlout .= $self->out_header($width);
-
- # Tableheadline
- $htmlout .= $self->out_headline ();
-
- $htmlout .= "<tbody>";
-
- #Tablecontent
- for my $i (0 .. ($self->{rowcount}-1)) {
- my $col = $i % 2 ? $col2 : $col1;
-
- $col = $col3 if defined ($sel) && $sel == $i;
-
- $htmlout .= "<tr style='background-color:$col;'";
-
- my $rid = $self->{rowdata}->{$i}->{id};
- $htmlout .= " id='$rid'" if $rid;
-
- if (defined($self->{rowdata}->{$i}->{lnk})) {
- $htmlout .= " class='link' onClick='goTo(\"$self->{rowdata}->{$i}->{lnk}\");'";
- }
-
- $htmlout .= ">";
-
- my @wa = @{$self->{width}};
- my $span = $self->{rowdata}->{$i}->{span};
- for my $c (0 .. $self->{rowdata}->{"$i"}->{len}) {
- my $sw = "";
- if (defined ($span) && (@$span[$c] > 1)) {
- $sw = "colspan=@$span[$c]";
- }
- my $wtxt = $wa[$c] ? "width:$wa[$c];" : '';
- $htmlout .= "<td $sw style='$wtxt'>".$self->out_celldata($i, $c)."</td>";
-
- $c += @$span[$c] - 1 if $sw;
- }
- $htmlout .= "</tr>\n";
- }
-
- $htmlout .= "</tbody>";
-
- # Tablefooter
- $htmlout .= $self->out_footer();
-
- return $htmlout;
-}
-
-1;
+++ /dev/null
-package PVE::HTMLUtils;
-
-use strict;
-require Exporter;
-use vars qw(@ISA @EXPORT);
-use Socket;
-use PVE::I18N;
-use HTML::Entities;
-use PVE::HTMLDropDown;
-use PVE::HTMLTable;
-use PVE::HTMLGrid;
-use PVE::HTMLControls;
-use PVE::APLInfo;
-use PVE::Storage;
-use Data::Dumper;
-
-@ISA = qw(Exporter);
-@EXPORT = qw(check_field check_range check_write_mode);
-
-
-# useful for debugging
-sub var_to_html {
- my $v = shift;
-
- return "<pre>" . Dumper ($v) . "</pre>";
-}
-
-sub format_size {
- my $size = shift;
-
- my $kb = $size / 1024;
-
- if ($kb < 1024) {
- return int ($kb) . "KB";
- }
-
- my $mb = $size / (1024*1024);
-
- if ($mb < 1024) {
- return int ($mb) . "MB";
- } else {
- my $gb = $mb / 1024;
- return sprintf ("%.2fGB", $gb);
- }
-}
-
-# HTML encode/decode text to store in config files (single line encoding)
-sub encode_description {
- my $desc = shift;
-
- $desc = encode_entities ($desc);
-
- $desc =~ s|\r?\n|<br>|gm;
-
- return $desc;
-}
-
-sub decode_description {
- my $desc = shift;
-
- $desc =~ s|<br>|\n|g;
-
- return decode_entities ($desc);
-}
-
-# html field checks
-
-sub check_range {
- my ($name, $value, $min, $max) = @_;
-
- if ($min && ($value < $min)) {
- die sprintf(__("Field '%s' is below minimum ($value < $min)") . "\n", $name);
- }
- if ($max && ($value > $max)) {
- die sprintf(__("Field '%s' is above maximum ($value > $max)") . "\n", $name);
- }
-}
-
-sub check_field {
- my ($name, $value, @checks) = @_;
-
- foreach my $c (@checks) {
- if ($c eq 'NOTEMPTY') {
- die sprintf(__("Field '%s' must not be empty") . "\n", $name) if !defined ($value) || ($value eq '');
- } elsif ($c eq 'NATURAL') {
- die sprintf(__("Field '%s' contains invalid characters") . "\n", $name) if $value !~ m/^\d+$/;
- } elsif ($c eq 'FLOAT') {
- die sprintf(__("Field '%s' contains invalid characters") . "\n", $name) if $value !~ m/^\d+(\.\d+)?$/;
- } elsif ($c eq 'NOWHITESPACES') {
- die sprintf(__("Field '%s' must not contain white spaces") . "\n", $name) if $value =~ m/\s/;
- } elsif ($c eq 'HTMLCOLOR') {
- die sprintf(__("Field '%s' is no valid html color (required format: #XXXXXX)") . "\n", $name) if $value !~ m/^\s*\#[a-f0-9A-F]{6}\s*$/;
- } elsif ($c eq 'EMAIL') {
- if ($value !~ m/^\S+\@\S+\.\S+$/) {
- die sprintf(__("Field '%s' does not look like a valid email address") . "\n", $name);
- }
- } elsif ($c eq 'IPADDRESS') {
- if ($value !~ m/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) {
- die sprintf (__("Field '%s' does not look like a valid IP address") . "\n", $name);
- }
- } elsif ($c eq 'MAC') {
- if ($value !~ m/^([a-f0-9A-F]{2}:){5}[a-f0-9A-F]{2}$/) {
- die sprintf(__("Field '%s' does not look like no valid MAC address (required format: XX:XX:XX:XX:XX:XX)") . "\n", $name);
- }
- } elsif ($c eq 'SERVER') { # resolves server name
- my $packed_ip = gethostbyname($value);
- if (!defined $packed_ip) {
- die sprintf(__("Field '%s' does not look like a valid server address") . "\n", $name);
- }
- $value = inet_ntoa($packed_ip);
- } elsif ($c eq 'PORTAL') { # resolves iscsi portal name
-
- if ($value =~ m/^([^:]+)(:(\d+))?$/) {
- my $server = $1;
- my $port = $3;
-
- my $packed_ip = gethostbyname($server);
- if (defined $packed_ip) {
- $server = inet_ntoa($packed_ip);
- $value = $port ? "$server:$port" : $server;
- next;
- }
- }
- die sprintf(__("Field '%s' does not look like a valid ISCSI portal") . "\n", $name);
- } elsif ($c =~ m/^CHAREXCL:(.*)$/) {
- die sprintf(__("Field '%s' must not contain special characters") . "\n", $name) if $value =~ m/$1/;
- } elsif ($c =~ m/^REGMATCH:(.*)$/) {
- die sprintf(__("Field '%s' must not contain special characters") . "\n", $name) if $value !~ m/$1/;
- } else {
- die "unimplemente check '$c' - internal error";
- }
- }
-
- return $value;
-}
-
-sub msg {
- my $id = shift;
-
- return __('You do not have write access.') if $id eq 'nowr';
-
- return __('This information is only available on the master node.') if $id eq 'infoatmaster';
-
- return __("Are you sure you want to remove VM %s? This will permanently erase all VM data.") if $id eq 'confirm_remove';
-
-}
-
-sub check_write_mode {
- my ($perm) = @_;
-
- if ($perm ne 'w') {
- die msg('nowr') . "\n";
- }
-}
-
-sub modify_url {
- my ($uri, %args, %mod) = @_;
-
- my $qstring = "";
-
- $args{action} = undef if !defined ($args{action});
- $args{aa} = undef if !defined ($args{aa});
-
- foreach my $p (keys (%args)) {
- next if defined ($mod{$p}) || !defined ($args{$p});
- $qstring .= $qstring ? "&" : "?";
- $qstring .= "$p=$args{$p}";
- }
- foreach my $p (keys (%mod)) {
- $qstring .= $qstring ? "&" : "?";
- $qstring .= "$p=$mod{$p}";
- }
-
- return $uri . $qstring;
-}
-
-sub parse_args {
- my ($string) = @_;
- return () unless defined $string and $string;
-
- return map {
- tr/+/ /;
- s/%([0-9a-fA-F]{2})/pack("C",hex($1))/ge;
- $_;
- } split /[=&;]/, $string, -1;
-}
-
-# |----------------------------|
-# |<b>$title</b>: $msg |
-# |----------------------------|
-sub create_noteframe {
- my ($title, $msg) = @_;
- my $html = "<div class='menubg lightcolbd' style='width:741px;border:1px solid;padding:2px;'>";
- $html .= "<b>$title:</b> $msg</div>";
- return $html;
-}
-
-# create a nice box
-#
-# |----------------------------|
-# |$left $right|
-# |----------------------------|
-# |$content |
-# |----------------------------|
-
-sub create_statusframe {
- my ($id, $left, $right, $content, $height) = @_;
-
- $left = ' ' if !$left;
- $right = ' ' if !$right;
-
- my $idtxt = $id ? "id='$id'" : '';
- my $idtxtleft = $id ? "id='${id}left'" : '';
- my $idtxtright = $id ? "id='${id}right'" : '';
-
- my $out .= "<table border=0 cellspacing=0 cellpadding=0 class='menubg lightcolbd' style='width:747px; border: 1px solid;border-bottom:0px;padding:2px;padding-left:5px;padding-right:5px;'>";
- $out .= "<tr><td $idtxtleft>$left</td>";
-
- $out .= "<td $idtxtright align=right>$right</td></tr></table>";
-
- my $hs = $height ? "height:${height}px;" : '';
-
- my $ovfl = $height ? 'auto' : 'visible';
- $out .= "<div $idtxt class=lightcolbd style='border: 1px solid; width:735px; $hs overflow:$ovfl; white-space: nowrap;padding:5px;'>$content</div>";
-
- return $out;
-}
-
-sub create_vmops_frame {
- my ($vmid, $upid) = @_;
-
-
- if (!$upid) {
- my $filename = "/tmp/vmops-$vmid.out";
- if (my $fh = IO::File->new ($filename, "r")) {
- $upid = <$fh>;
- close ($fh);
- chomp $upid;
- }
- }
-
- my $out = '';
-
- if ($upid) {
- my $href = "javascript:command_abort(\"$upid\");";
- my $abort = "<a class='frmsubmit' id='abortbutton' href='$href'></a>";
-
- $out .= create_statusframe ('logview', undef, $abort, undef, 450, 1);
- $out .= PVE::HTMLControls::create_command_viewer ('logview', 'logviewleft', 'abortbutton', $upid);
- }else {
- $out .= __("Nothing to view");
- }
-
- return $out;
-}
-
-sub create_apldownload_frame {
- my ($userid, $upid) = @_;
-
- if (!$upid) {
- my $filename = "/tmp/apldownload-$userid.out";
- if (my $fh = IO::File->new ($filename, "r")) {
- $upid = <$fh>;
- close ($fh);
- chomp $upid;
- }
- }
-
- my $out = '';
-
- if ($upid) {
- my $href = "javascript:command_abort(\"$upid\");";
- my $abort = "<a class='frmsubmit' id='abortbutton' href='$href'></a>";
-
- $out .= create_statusframe ('logview', undef, $abort, undef, 100);
- $out .= PVE::HTMLControls::create_command_viewer ('logview', 'logviewleft', 'abortbutton', $upid);
- }else {
- $out .= __("Nothing to view");
- }
-
- return $out;
-}
-
-sub create_cpubar {
- my ($width, $abs, $rel) = @_;
-
- my $dvrel = $rel > 100 ? 100 : $rel;
- my $dvabs = $abs > 100 ? 100 : $abs;
-
- my $hwidth1 = sprintf ("%dpx", $width);
- my $hwidth2 = sprintf ("%dpx", int (($width * $dvrel)/100));
- my $hwidth3 = sprintf ("%dpx", int (($width * $dvabs)/100));
-
- my $per = sprintf ("%0.2f%", $rel);
-
- return "<div style='padding:0px;background-color:#C0C0C0;border:1px solid #000000;width:$hwidth1;height:14px;position:relative;'><div style='position:absolute;top:0px;left:0px;background-color:#00C000;border:0px;width:$hwidth2;height:14px;'></div><div style='position:absolute;top:11px;left:0px;background-color:#00F000;border:0px;width:$hwidth3;height:3px;'></div><div align=center style='width:100%;position:absolute;top:1px;left:0px;font-size:10px;'>$per</div></div>";
-}
-
-sub create_bar {
- my ($width, $max, $value, $text) = @_;
-
- if (!$max || ($max <= 0)) {
- $max = 1;
- $value = 0;
- }
-
- my $dv = $value > $max ? $max : $value;
-
- my $hwidth1 = sprintf ("%dpx", $width);
-
- my $hwidth2 = sprintf ("%dpx", int (($width * $dv)/$max));
-
- my $per = $text ? $text : sprintf ("%0.2f%", ($value*100)/$max);
- return "<div style='padding:0px;background-color:#C0C0C0;border:1px solid #000000;width:$hwidth1;height:14px;position:relative;'><div style='position:absolute;top:0px;left:0px;background-color:#00C000;border:0px;width:$hwidth2;height:14px;'></div><div align=center style='width:100%;position:absolute;top:1px;left:0px;font-size:10px;'>$per</div></div>";
-}
-
-sub uptime_to_str {
- my ($ut, $long) = @_;
-
- if (!$ut) {
- return '-';
- }
-
- if ($long) {
- my $days = int ($ut / 86400);
- $ut -= $days*86400;
- my $hours = int ($ut / 3600);
- $ut -= $hours*3600;
- my $mins = int ($ut / 60);
- $ut -= $mins*60;
-
- if ($days) {
- my $ds = $days > 1 ? __('days') : __('day');
- return sprintf "%d $ds %02d:%02d:%02d", $days, $hours, $mins, $ut;
- } else {
- return sprintf "%02d:%02d:%02d", $hours, $mins, $ut;
- }
- }
-
- if ($ut < 60) {
- return "${ut}s";
- } elsif ($ut < 3600) {
- my $mins = int ($ut / 60);
- return "${mins}m";
- } elsif ($ut < 86400) {
- my $hours = int ($ut / 3600);
- return "${hours}h";
- } else {
- my $days = int ($ut / 86400);
- return "${days}d";
- }
-}
-
-sub create_vzlist_table {
- my ($cid, $vzlist) = @_;
-
- my $table = PVE::HTMLTable->new ([]);
-
- my $out = '';
-
- my @header = ('1', '20px', ' ',
- '1', '50px', __('VMID'),
- '1', '70px', __('Status'),
- '1', '235px', __('Name'),
- '1', '50px', __('Uptime'),
- '1', '100px', __('Disk'),
- '1', '100px', __('Memory'),
- '1', '100px', __('CPU'),
- );
-
- $table->add_headline (\@header);
-
- my $ddown = PVE::HTMLDropDown->new ();
- $ddown->add_item ("menu${cid}_0", "?action=start", __('Start'));
- $ddown->add_item ("menu${cid}_0", "?confirmdestroy=1", __('Remove'));
- $ddown->add_item ("menu${cid}_0", "/vmlist/migrate.htm?online=0", __('Migrate'));
-
- $ddown->add_item ("menu${cid}_1", "?action=restart", __('Restart'));
- $ddown->add_item ("menu${cid}_1", "?action=shutdown", __('Shutdown'));
- $ddown->add_item ("menu${cid}_1", "?action=stop", __('Stop'));
- $ddown->add_item ("menu${cid}_1", "javascript:pve_console()", __('Console'));
- $ddown->add_item ("menu${cid}_1", "/vmlist/migrate.htm?online=0", __('Migrate'));
-
- $ddown->add_item ("menu${cid}_2", "?action=start", __('Start'));
- $ddown->add_item ("menu${cid}_2", "?action=umount", __('Unmount'));
-
- my $found = 0;
-
- foreach my $vkey (sort keys %$vzlist) {
- next if $vkey !~ m/^VEID_(\d+)$/;
- my $veid = $1;
- my $d = $vzlist->{$vkey};
-
- $found = 1;
-
- my $type = $d->{type};
-
- if ($d->{status} eq 'running' || $d->{status} eq 'stopped' ||
- $d->{status} eq 'shutdown' || $d->{status} eq 'stop' ||
- $d->{status} eq 'start' || $d->{status} eq 'mounted') {
-
- my $mlabel = "menu${cid}_1";
-
- if ($d->{status} eq 'stopped') {
- $mlabel = "menu${cid}_0";
- } elsif ($d->{status} eq 'mounted') {
- $mlabel = "menu${cid}_2";
- }
-
- my $menu = $ddown->out_symbol ($mlabel, '', "&cid=$cid&veid=$veid&type=$type");
-
- $table->set_row_link ("/$type/$cid-$veid/index.htm");
-
- my $membar;
- my $diskbar;
-
- my $cpubar = create_cpubar (100, $d->{pctcpu}, $d->{relcpu});
- if ($d->{type} eq 'openvz') {
- $membar = create_bar (100, $d->{maxmem}, $d->{mem},
- format_size ($d->{mem}*1024*1024));
-
- if ($d->{status} ne 'stopped') {
- $diskbar = create_bar (100, $d->{maxdisk}, $d->{disk},
- format_size ($d->{disk}*1024*1024));
- } else {
- my $ds = format_size ($d->{maxdisk}*1024*1024);
- $diskbar = "<div width=100 align=right>$ds</div>";
- }
- } elsif ($d->{type} eq 'qemu') {
- $membar = create_bar (100, $d->{maxmem}, $d->{mem},
- format_size ($d->{mem}*1024*1024));
- my $ds = format_size ($d->{maxdisk}*1024*1024);
- $diskbar = "<div width=100 align=right>$ds</div>";
- }
-
- # add soft hyphenation (in case someone has a very long hostname)
- $d->{name} =~ s/\./\.­/g;
-
- if ($d->{status} eq 'stopped' || $d->{status} eq 'mounted') {
- $membar = '';
- $cpubar = '';
- }
- $table->add_row ('', $menu, $veid, $d->{status}, $d->{name},
- uptime_to_str ($d->{uptime}), $diskbar, $membar, $cpubar);
- } elsif ($d->{status} eq 'create') {
- $table->set_row_link ("/logs/index.htm?cid=$cid&veid=$veid");
- $table->add_row ('', '', $veid, $d->{status}, '', '', '', '', '');
- } else {
- $table->add_row ('', '', $veid, $d->{status}, '', '', '', '', '');
- }
- }
-
- return __("Node has no VMs") if !$found;
-
- $out .= $ddown->out_dropdown_menu("menu${cid}_0");
- $out .= $ddown->out_dropdown_menu("menu${cid}_1");
- $out .= $ddown->out_dropdown_menu("menu${cid}_2");
-
- $out .= $table->out_table ();
-
- return $out;
-}
-
-sub create_vmops_table {
- my ($vmops, $inactive) = @_;
-
- my $table = PVE::HTMLTable->new ([]);
-
- my $out = '';
-
- my @header;
-
- if ($inactive) {
- @header = ('1', '120px', __('Command'),
- '1', '200px', __('Start time'),
- '1', '100px', __('User'),
- '1', '100px', __('CID'),
- '1', '100px', __('VMID'),
- );
- } else {
- @header = ('1', '20px', ' ',
- '1', '100px', __('Command'),
- '1', '200px', __('Start time'),
- '1', '100px', __('User'),
- '1', '100px', __('CID'),
- '1', '100px', __('VMID'),
- );
- }
-
- $table->add_headline (\@header);
-
- my $ddown = PVE::HTMLDropDown->new ();
- $ddown->add_item ('menu0', "?action=stop", __('Stop'));
-
- my $tlist;
-
-
- PVE::Utils::foreach_vmrec ($vmops, sub {
- my ($cid, $vmid, $d) = @_;
-
- # command still running
- my $running = PVE::Utils::check_process ($d->{pid}, $d->{pstart});
-
- if (!$inactive && $running) {
- my $menu = $ddown->out_symbol ('menu0', '', "&cid=$cid&veid=$vmid");
- push @$tlist, {
- cid => $cid,
- veid => $vmid,
- starttime => $d->{starttime},
- menu => $menu,
- command => $d->{command},
- user => $d->{user},
- };
- } elsif ($inactive && !$running) {
- push @$tlist, {
- cid => $cid,
- veid => $vmid,
- starttime => $d->{starttime},
- command => $d->{command},
- user => $d->{user}
- };
- }
- });
-
- if (!$tlist) {
- return __('Nothing to view');
- } else {
- foreach my $ref (sort {$b->{starttime} <=> $a->{starttime}} @$tlist) {
- $table->set_row_link ("/logs/index.htm?cid=$ref->{cid}&veid=$ref->{veid}");
- my $ct = localtime ($ref->{starttime});
- if ($inactive) {
- $table->add_row ('', $ref->{command}, $ct, $ref->{user},
- $ref->{cid}, $ref->{veid});
- } else {
- $table->add_row ('', $ref->{menu}, $ref->{command}, $ct,
- $ref->{user}, $ref->{cid}, $ref->{veid});
- }
- }
- }
-
- $out .= $ddown->out_dropdown_menu("menu0");
- $out .= $table->out_table ();
-
- return $out;
-}
-
-sub html_table_ressource {
- my ($table, $barwidth, $name, $max, $cur, $text) = @_;
-
- my $rmax = defined ($max) ? $max : 1;
-
- my $bar = defined ($max) ? create_bar ($barwidth, $rmax, $cur, $text) : ' ';
-
- my $maxtext = defined ($max) ? $max : "-";
-
- $table->add_row ('', $name, $cur, $maxtext, $bar);
-}
-
-sub action_button {
- my ($text, $action, $disabled) = @_;
-
- my $dtext = $disabled ? 'disabled' : '';
- my $loc = "?action=$action";
- return "<button $dtext type=button onclick='location=\"$loc\"'>$text</button>";
-}
-
-sub href_button {
- my ($text, $href, $disabled) = @_;
-
- $href = '' if !defined ($href);
-
- my $dtext = $disabled ? 'disabled' : '';
- return "<button $dtext type=button onclick='location=\"$href\"'>$text</button>";
-}
-
-sub create_confirmframe {
- my ($msg, $action, $href1, $href2) = @_;
-
- my $html .= "<br><div align=center>$msg</div><br>";
-
- my $b1 = PVE::HTMLUtils::href_button($action, $href1);
- my $b2 = PVE::HTMLUtils::href_button(__("Cancel"), $href2 || '');
-
- $html .= "<div align=center>$b1$b2</div><br>";
-
- return create_statusframe (undef, __("Confirm"), undef, $html);
-}
-
-
-sub create_vmstatus {
- my ($cid, $veid, $type, $vzinfo) = @_;
-
- my $status = $vzinfo->{vzlist}->{"VEID_$veid"}->{status};
- my $ip = $vzinfo->{vzlist}->{"VEID_$veid"}->{ip};
- my $name = $vzinfo->{vzlist}->{"VEID_$veid"}->{name};
-
- my $uptime = uptime_to_str ($vzinfo->{vzlist}->{"VEID_$veid"}->{uptime}, 1);
-
- my $veconf = $vzinfo->{config};
- my $ni = $vzinfo->{ni};
- my $html = '';
-
- my $pkglist = PVE::APLInfo::load_data();
- my $tmpl = $veconf->{ostemplate}->{value};
- my $pkginfo = $pkglist->{'all'}->{"$tmpl\.tar\.gz"};
-
- my $manageurl;
- if ($ip && (my $url = $pkginfo->{manageurl})) {
- $manageurl = $url;
- $manageurl =~ s/__IPADDRESS__/$ip/i;
- }
-
- my $vmops = PVE::Config::read_file ("vmops");
-
- my $op;
- if (defined($vmops->{"CID_$cid"}) && defined ($vmops->{"CID_$cid"}->{"VEID_$veid"})) {
- my $d = $vmops->{"CID_$cid"}->{"VEID_$veid"};
- if (PVE::Utils::check_process ($d->{pid}, $d->{pstart})) { # still running
- $op = $d->{command};
- }
- }
-
- my $grid = PVE::HTMLGrid->new ('fw1', 'fw2', "fw3to4:right");
-
- my $cmds = "<div>";
-
- if ($status eq 'running') {
- $cmds .= action_button ($type eq 'openvz' ? __("Restart") : __("Reset"),
- 'restart', defined ($op));
- } else {
- $cmds .= action_button (__("Start"), 'start', defined ($op));
- }
- $cmds .= action_button (__("Shutdown"), 'shutdown', defined ($op) || ($status ne 'running'));
- if ($status eq 'mounted') {
- $cmds .= action_button (__("Unmount"), 'umount', defined ($op));
- } else {
- $cmds .= action_button (__("Stop"), 'stop', defined ($op) || ($status eq 'stopped'));
- }
- $cmds .= href_button (__("Remove"), '?confirmdestroy=1', defined ($op) || ($status ne 'stopped'));
- $cmds .= "</div>";
-
- $grid->add_row (__('Status') . ':',
- "<b>" . (defined ($op) ? "executing task '$op'" : $status),
- $cmds);
-
- if ($type eq 'openvz') {
- my $iptext;
-
- if ($ip && $ip ne '-') {
- if ($manageurl && ($status eq 'running')) {
- $iptext = "<a class=cmd target=top href='$manageurl'>$ip</a>";
- } else {
- $iptext = $ip;
- }
- } else {
- $iptext = __('unknown');
- }
-
-
- $grid->add_row (__('Hostname') . ':', $name,
- $uptime eq '-' ? '' : __('Uptime') . ": $uptime");
-
-
- my $clink;
- if ($status ne 'stopped') {
- my $href = "javascript:pve_openvz_console($cid, $veid)";
- $clink .= "<a class=cmd href='$href'>" . __("Open VNC console") . "</a>";
- }
-
- $grid->add_row (__('IP Address') . ':', $iptext, $clink);
- } else {
- if ($uptime ne '-') {
- $grid->add_row (undef, undef, __('Uptime') . ": $uptime");
- }
-
- if ($status ne 'stopped') {
- my $href = "javascript:pve_qemu_console($cid, $veid)";
- $grid->add_row (undef, undef, "<a class=cmd href='$href'>Open VNC console</a>");
- }
- }
-
- $html .= $grid->html();
-
- $html .= "<br><br>";
-
- my $table = PVE::HTMLTable->new ([]);
-
- my $barwidth = 300;
- my $fw2 = int ((PVE::HTMLGrid::get_width ('fw') - $barwidth -
- PVE::HTMLGrid::get_width ('fw1'))/2);
-
- my @header = ('1', PVE::HTMLGrid::get_width ('fw1') . 'px', __('Resource'),
- '1', "${fw2}px", __('Current'),
- '1', "${fw2}px", __('Maximum'),
- '1', "${barwidth}px", ' ',
- );
- $table->add_headline (\@header);
-
- my $relcpu = $vzinfo->{vzlist}->{"VEID_$veid"}->{relcpu};
- html_table_ressource ($table, $barwidth, __('CPU Utilization') . ':', 100, $relcpu);
-
- if ($type eq 'openvz') {
- my $curmem = int ($vzinfo->{vzlist}->{"VEID_$veid"}->{mem});
- my $maxmem = int ($vzinfo->{vzlist}->{"VEID_$veid"}->{maxmem});
-
- html_table_ressource ($table, $barwidth, __("Memory/Swap") . ' (MB):', $maxmem, $curmem,
- format_size ($curmem*1024*1024));
- my $curdisk = sprintf ("%0.2f", $vzinfo->{vzlist}->{"VEID_$veid"}->{disk} / 1024);
- my $maxdisk = sprintf ("%0.2f", $vzinfo->{vzlist}->{"VEID_$veid"}->{maxdisk} / 1024);
- html_table_ressource ($table, $barwidth, __("Disk space") . ' (GB):', $maxdisk, $curdisk);
- } else {
- my $curmem = int ($vzinfo->{vzlist}->{"VEID_$veid"}->{mem});
- my $maxmem = int ($vzinfo->{vzlist}->{"VEID_$veid"}->{maxmem});
-
- html_table_ressource ($table, $barwidth, __("Memory") . ' (MB):', $maxmem, $curmem,
- format_size ($curmem*1024*1024));
- }
-
-
- $html .= $table->out_table ();
-
- return $html;
-}
-
-sub create_host_status {
- my ($cinfo, $status, $verbose) = @_;
-
- my @cellwidth = ('290px', '450px');
-
- my $table = PVE::HTMLTable->new (\@cellwidth);
-
- $table->add_row ('', __("Uptime"), $status->{uptime}->{uptimestr});
-
- $table->add_row ('', "CPU(s)", "$status->{cpuinfo}->{cpus} x $status->{cpuinfo}->{model}");
-
- my $stat = create_bar (300, 1, $status->{cpu});
- $table->add_row ('', __('CPU Utilization'), $stat);
-
- my $iowait = create_bar (300, 1, $status->{wait});
- $table->add_row ('', __('IO Delays'), $iowait);
-
- my $f1 = format_size ($status->{meminfo}->{mbmemtotal}*1024*1024);
- my $f2 = format_size ($status->{meminfo}->{mbmemused}*1024*1024);
- my $txt = __("Physical Memory") . " ($f1/$f2)";
- $stat = create_bar (300, $status->{meminfo}->{mbmemtotal},
- $status->{meminfo}->{mbmemused},
- format_size ($status->{meminfo}->{mbmemused}*1024*1024));
- $table->add_row ('', $txt, $stat);
-
- if ($status->{meminfo}->{mbswaptotal}) {
-
- $f1 = format_size ($status->{meminfo}->{mbswaptotal}*1024*1024);
- $f2 = format_size ($status->{meminfo}->{mbswapused}*1024*1024);
- $txt = __("Swap Space") . " ($f1/$f2)";
- $stat = create_bar (300, $status->{meminfo}->{mbswaptotal},
- $status->{meminfo}->{mbswapused},
- format_size ($status->{meminfo}->{mbswapused}*1024*1024));
- $table->add_row ('', $txt, $stat);
- }
-
- $f1 = format_size ($status->{hdinfo}->{root}->{total}*1024*1024);
- $f2 = format_size ($status->{hdinfo}->{root}->{used}*1024*1024);
- $txt = __("HD Space root") . " ($f1/$f2)";
- $stat = create_bar (300, $status->{hdinfo}->{root}->{avail},
- $status->{hdinfo}->{root}->{used});
- $table->add_row ('', $txt, $stat);
-
- $table->add_row ('', __("Version") . " (package/version/build)", $status->{cpuinfo}->{proxversion});
-
- $table->add_row ('', __("Kernel Version"), $status->{cpuinfo}->{kversion});
-
- my $out = $table->out_table();
-
- return $out if !$verbose || (scalar (@{$cinfo->{nodes}}) <= 1);
-
- $out .= "<br>";
-
- $table = PVE::HTMLTable->new ([]);
-
- my @header_sync = ('1', '150px', __('Synchronized Nodes'),
- '1', '150px', __('IP Address'),
- '1', '100px', __('Sync Status'),
- '1', '200px', __('Last succesfull sync'),
- '1', '100px', __('Delay (minutes)'),
- );
- $table->add_headline (\@header_sync);
-
- foreach my $ni (@{$cinfo->{nodes}}) {
- my $lastsync = $status->{"lastsync_$ni->{cid}"};
-
- $table->set_row_link ("/cluster/index.htm?cid=$ni->{cid}");
-
- my $diff;
- if (defined ($lastsync)) {
- $diff = time() - $lastsync;
- $diff = 0 if $diff < 0;
- } else {
- $table->add_row ('', $ni->{name}, $ni->{ip}, '-', '-', '-');
- next;
- }
- my $sstatus = 'OK';
- my $dstatus = '-';
-
- if ($diff > (60*3)) {
- $sstatus = '<blink><font color=red>nosync</font></blink>';
- $dstatus = int (($diff + 59)/60);
- }
-
- my $synctime = localtime ($lastsync);
-
- $table->add_row ('', $ni->{name}, $ni->{ip}, $sstatus, $synctime, $dstatus);
- }
-
- $out .= $table->out_table();
-
- return $out;
-}
-
-sub create_cluster_status {
- my ($cinfo) = @_;
-
- my $out = '';
-
- my $table = PVE::HTMLTable->new ([]);
-
- my @header = ('1', '100px', __('Hostname'),
- '1', '100px', __('IP Address'),
- '1', '50px', __('Role'),
- '1', '50px', __('State'),
- '1', '100px', __('Uptime'),
- '1', '60px', 'Load',
- '1', '60px', 'CPU',
- '1', '60px', 'IODelay',
- '1', '60px', 'Memory',
- '1', '60px', 'Disk',
- );
-
- $table->add_headline (\@header);
-
- foreach my $ni (@{$cinfo->{nodes}}) {
- my $role = cluster_format_role ($ni->{role});
- $table->set_row_link ("/cluster/index.htm?cid=$ni->{cid}");
- $table->set_col_span ([1,1,1,7]);
- $table->add_row ("rowcid$ni->{cid}", $ni->{name}, $ni->{ip}, $role, '');
- }
- $out .= $table->out_table ();
-
- foreach my $ni (@{$cinfo->{nodes}}) {
- $out .= PVE::HTMLControls::create_periodic_updater ("rowcid$ni->{cid}",
- '/ws/status_update',
- { cid => $ni->{cid} }, 5);
- }
-
- return $out;
-}
-
-sub create_pkginfo_frame {
- my ($d, $download) = @_;
-
- my $html = '<table>';
-
- $html .= "<tr><td width=100>Description:</td><td width=645><b>$d->{headline}</td>";
- $html .= "<tr><td><td style='white-space:normal;'>$d->{description}</td>" if $d->{description};
- $html .= "<tr><td colspan=2><hr></tr>";
- $html .= "<tr><td>Information:</td><td><a target=top href='$d->{infopage}'>$d->{infopage}</a></td>";
-
- #$html .= "<tr><td>Appliance:</td><td>$d->{package}</td>";
- $html .= "<tr><td>Version:</td><td>$d->{version}</td>";
- $html .= "<tr><td>Section:</td><td>$d->{section}</td>";
- #$html .= "<tr><td>OS:</td><td>$d->{os}</td>"; # already displayed with filename
-
- if ($d->{maintainer} =~ m/^\s*(.*\S)\s*\<(\S+\@\S+)\>\s*$/) {
- $html .= "<tr><td>Maintainer:</td><td>$1 <a href='mailto:$2'><$2></a></td>";
- }
-
- $html .= "<tr><td>Filename:</td><td>$d->{template}</td>";
- $html .= "<tr><td>MD5SUM:</td><td>$d->{md5sum}</td>";
-
-
- $html .= "<tr><td colspan=2><tr><td colspan=2>";
-
- if ($download) {
- $html .= "<tr><td><td><a class=cmd href='?action=download&aa=$d->{template}'>start download</a>";
- }
-
- $html .= "</table>";
-
- return PVE::HTMLUtils::create_statusframe ('', "Template Information for appliance '$d->{package}'", $d->{type}, $html);
-}
-
-sub storage_format_volume_list {
- my ($cfg, $vdisks) = @_;
-
- my $res = [];
-
- return $res if !$vdisks;
-
- PVE::Storage::foreach_volid ($vdisks, sub {
- my ($volid, $sid, $volname, $info) = @_;
-
- my $scfg = PVE::Storage::storage_config ($cfg, $sid);
-
- # skip used volumes
- return if PVE::Storage::volume_is_used ($cfg, $volid);
-
- my $stype = $scfg->{type};
- if ($stype eq 'iscsi') {
- my $size = int ($info->{size} / (1024 *1024));
- push @$res, [ $volid, sprintf "CH %02d ID %d LUN %d ($size GB)",
- $info->{channel}, $info->{id}, $info->{lun} ];
- } else {
- push @$res, [ $volid, $volname];
- }
- });
-
- return $res;
-}
-
-sub storage_format_volume_list_iscsi {
- my ($cfg, $vdisks) = @_;
-
- my $res = {
- titles => [ 'CH', 'ID', 'LUN', 'Size (GB)', 'VolumeID' ],
- values => [],
- };
-
- return $res if !$vdisks;
-
- PVE::Storage::foreach_volid ($vdisks, sub {
- my ($volid, $sid, $volname, $info) = @_;
- my $scfg = PVE::Storage::storage_config ($cfg, $sid);
-
- # skip used volumes
- return if PVE::Storage::volume_is_used ($cfg, $volid);
-
- my $stype = $scfg->{type};
- if ($stype eq 'iscsi') {
- my $size = int ($info->{size} / (1024 *1024));
- my $short = sprintf "CH %02d ID %d LUN %d ($size GB)", $info->{channel},
- $info->{id}, $info->{lun}, $size;
- push @{$res->{values}}, [ $volid, $short,
- $info->{channel}, $info->{id}, $info->{lun},
- $size, $volid ];
- } else {
- die "wrong storage type";
- }
- });
-
- return $res;
-}
-
-sub storage_format_storage_list {
- my ($stinfo, $sel) = @_;
-
- my $res = {
- titles => [ 'Storage', 'Type', 'Used (GB)', 'Capacity (GB)', ' ' ],
- values => [],
- };
-
- return $res if !$stinfo;
-
- my $cfg = $stinfo->{cfg};
-
- $sel = 'images' if !$sel;
-
- foreach my $sid (sort keys %{$stinfo->{$sel}}) {
- my $scfg = PVE::Storage::storage_config ($cfg, $sid);
-
- my $used;
- my $avail;
- my $diskbar;
-
- if ($scfg->{type} eq 'iscsi') {
- $used = $avail = "n/a";
- $diskbar = '';
- } else {
- my $d = $stinfo->{info}->{$sid};
- $used = int ($d->{used} / (1024*1024));
- $avail = int ($d->{avail} / (1024*1024));
- $diskbar = create_bar (200, $d->{avail} , $d->{used});
- }
-
- push @{$res->{values}}, [ $sid, "$sid ($scfg->{type})", $sid, $scfg->{type}, $used, $avail, $diskbar ];
- }
-
- return $res;
-}
-
-sub storage_format_iso_list {
- my ($cfg, $tlist) = @_;
-
- my $res = [];
-
- return $res if !$tlist;
-
- PVE::Storage::foreach_volid ($tlist, sub {
- my ($volid, $sid, $volname, $info) = @_;
- my (undef, $name) = PVE::Storage::parse_volname_dir ($volname);
- push @$res, [$volid, $name];
- });
-
- return $res;
-}
-
-sub check_vztmpl_name {
- my ($name, $noerr) = @_;
-
- if ($name =~ m/^([^-]+-[^-]+)-([^_]+)_([^_]+)\_(i386|amd64)\.tar\.gz$/) {
- return [$1, $2, $3, $4];
- }
-
- return undef if $noerr;
-
- die sprintf __("name '%s' does not conform to template naming scheme") .
- " (<OS>-<OSVERSION>-<NAME>_<VERSION>_(i386|amd64).tar.gz)\n", $name;
-}
-
-sub storage_format_vztmpl_list {
- my ($cfg, $tlist) = @_;
-
- my $default;
-
- my $res = {
- titles => [__('OS'), __('Name'), __('Version'), __('Arch.')],
- values => [],
- };
-
- return $res if !$tlist;
-
- PVE::Storage::foreach_volid ($tlist, sub {
- my ($volid, $sid, $volname, $info) = @_;
- my (undef, $name) = PVE::Storage::parse_volname_dir ($volname);
-
- $default = $volid if !$default && $volid =~ m|^local:vztmpl/debian-5.0-standard|;
-
- if (my $td = check_vztmpl_name ($name, 1)) {
- push @{$res->{values}}, [$volid, $name, @$td];
- }
- });
-
- return wantarray ? ($res, $default) : $res;
-}
-
-sub storage_format_vgs_list {
- my ($cfg, $tlist) = @_;
-
- my $res = [];
-
- return $res if !$tlist;
-
- foreach my $vgname (sort keys %$tlist) {
-
- # skip used groups
- next if PVE::Storage::vgroup_is_used ($cfg, $vgname);
-
- my $size = int ($tlist->{$vgname}->{size}/(1024*1024));
- push @$res, [$vgname, "$vgname (${size} GB)"];
- }
-
- if (!scalar(@$res)) {
- push @$res, [ '', "Found no volume groups"];
- }
-
- return $res;
-}
-
-sub cluster_format_cid_list {
- my ($cinfo, $exclude) = @_;
-
- my $res = {
- titles => [__('Name'), __('IP Address'), __('Role'), 'CID'],
- values => [],
- };
-
- return $res if !$cinfo;
-
- foreach my $ni (@{$cinfo->{nodes}}) {
-
- next if defined ($exclude) && ($exclude eq $ni->{cid});
-
- my $role = cluster_format_role ($ni->{role});
- push @{$res->{values}}, [$ni->{cid}, "$ni->{name} ($ni->{ip})",
- $ni->{name}, $ni->{ip}, $role, $ni->{cid}];
- }
-
- return $res;
-}
-
-sub cluster_format_vmid_list {
- my ($vzl) = @_;
-
- my $res = {
- titles => ['VMID', __('Name'), __('Status') ],
- values => [],
- default => '-',
- };
-
- return $res if !$vzl;
-
- PVE::Utils::foreach_veid_sorted ($vzl, sub {
- my ($veid, $d) = @_;
- push @{$res->{values}}, [$veid, "VM $veid ($d->{name})", $veid,
- $d->{name}, $d->{status}];
- });
-
- return $res;
-}
-
-sub cluster_format_role {
- my $role = shift;
-
- $role = __('Master') if $role eq 'M';
- $role = __('Node') if $role eq 'N';
-
- return $role;
-}
-
-1;
-
+++ /dev/null
-package PVE::I18N;
-
-use strict;
-require Exporter;
-use vars qw(@ISA @EXPORT);
-use Encode;
-use HTML::Entities;
-use Locale::Messages qw (:libintl_h dgettext);
-
-@ISA = qw(Exporter);
-@EXPORT = qw( __ );
-
-my $nlsinited;
-my $language = 'C';
-my $lang_is_utf8 = 0;
-
-my %textdomains = ();
-
-
-sub import
-{
- my ($self, $textdomain) = @_;
-
- # like Locale/TextDomain.pm
- # usage: use PVE::I18N qw(<textdomain>)
-
- $textdomain = 'pve-manager' if !$textdomain;
-
- # Check our caller.
- my $package = caller;
- return if exists $textdomains{$package};
-
- # Remember the textdomain of that package.
- $textdomains{$package} = $textdomain;
-
- PVE::I18N->export_to_level (1, $package, @EXPORT);
-}
-
-sub get_lang {
-
- my $section = 'default';
- my $lang = 'C';
-
- open (SYSCFG, "</etc/pve/pve.cfg") || return $lang;
- while (my $line = <SYSCFG>) {
- chomp $line;
- if ($line =~ m/\s*language\s*:\s*(\S+)\s*$/) {
- $lang = $1;
- last;
- }
- }
- close (SYSCFG);
-
- return $lang;
-}
-
-sub set_lang {
- my $lang = shift;
-
- $language = $lang;
-
- $lang_is_utf8 = scalar (grep { $language eq $_ } qw (vi pl ja hu ro ru fr tr zh_CN sr cs sl))
-}
-
-if (!$nlsinited) {
-
- set_lang (get_lang);
-
- $nlsinited = 1;
-}
-
-sub __ {
- my $msgid = shift;
- my $oldlang = $ENV{LANGUAGE};
- my $oldlc_all = $ENV{LC_ALL};
- $ENV{LANGUAGE} = $language;
-
- my $package = caller;
- my $textdomain = $textdomains{$package};
-
- my $res = dgettext($textdomain, $msgid);
-
- if ($lang_is_utf8) {
- $res = decode('UTF-8', $res) ;
- } else {
- $res = decode('iso-8859-1', $res) ;
- }
-
- $ENV{LANGUAGE} = $oldlang || '';
- $ENV{LC_ALL} = $oldlc_all || '';
- return $res;
-}
-
-1;
+++ /dev/null
-package PVE::SourceFilter;
-
-use Filter::Util::Call;
-use Data::Dumper;
-
-$Data::Dumper::Indent = 0;
-
-sub import
-{
- my($type, @arguments) = @_;
-
- my $stat = {};
- filter_add ($stat) ;
-}
-
-sub filter
-{
- my($self) = @_ ;
- my($status) ;
-
- $status = filter_read();
- if ($status <= 0) {
- return $status;
- }
-
- if (m/^package\s+(\S+);/) {
- foreach my $k (keys %$self) {delete $self->{$k}; }
- $self->{packagename} = $1;
- }
-
- if (m/^\s*\#\#FILTER_DATA\#\#/) {
- my $dtxt = Data::Dumper->Dump ([{%$self}], [qw(stats)]);
- $_ = "sub filter_data { my $dtxt; die \"PVE::SourceFilter - internal error\" if \$stats->{packagename} ne __PACKAGE__; return \$stats; }\n";
- }
-
- if (m/^sub\s+(\w+)\s.*\#\#SOAP_EXPORT\#\#/) {
- $self->{soap_exports}->{$1} = 1;
- }
-
- $self->{lines}++;
-
- $status ;
-}
-
-1;
+++ /dev/null
-package PVE::URLRewrite;
-
-use strict;
-use Apache2::Const qw(DECLINED);
-use PVE::HTMLUtils;
-
-sub handler {
- my $r = shift;
-
- my $uri = $r->uri;
-
- if ($uri =~ m!^/(qemu|openvz)/(\d+)-(\d+)/(.*)$!) {
- my $vmtype = $1;
- my $newuri = "/$1/$4";
- my $cid = $2;
- my $veid = $3;
-
- $r->uri ("$newuri");
-
- $r->pnotes ("PVE_VMINFO", { cid => $cid, veid => $veid,
- vmtype => $vmtype, uri => $uri});
- }
-
- return DECLINED;
-}
-
-1;
+++ /dev/null
-package PVE::Utils;
-
-use strict;
-use POSIX qw (:sys_wait_h strftime);
-use PVE::pvecfg;
-use IPC::Open3;
-use IO::File;
-use IO::Select;
-use PVE::SafeSyslog;
-use Authen::PAM qw(:constants);
-use Time::HiRes qw (gettimeofday);
-use Digest::SHA1;
-use Encode;
-
-my $clock_ticks = POSIX::sysconf(&POSIX::_SC_CLK_TCK);
-
-# access control
-
-my $accmode = {
- root => [[ '/', 'w' ]],
- audit => [[ '/', 'r' ]],
-};
-
-my $accmode_cnode = {
- root => [[ '/server/' , 'w' ],
- [ '/logs/', 'w' ],
- [ '/system/options.htm', 'r' ],
- [ '/system/', 'w' ],
- [ '/', 'r' ],
- ],
- audit => [[ '/', 'r' ]],
-};
-
-sub get_access_mode {
- my ($username, $group, $uri, $role) = @_;
-
- my $alist;
- if ($role eq 'N') {
- $alist = $accmode_cnode->{$group};
- } else {
- $alist = $accmode->{$group};
- }
- return undef if !$alist;
-
- foreach my $am (@$alist) {
- my ($d, $m) = @$am;
- return $m if $uri =~ m/^$d/;
- }
-
- return undef;
-}
-
-# authentication tickets
-
-sub load_auth_secret {
- my $secret = (split (/\s/, `md5sum /etc/pve/pve-root-ca.key`))[0];
-
- die "unable to load authentication secret\n" if !$secret;
-
- return $secret;
-}
-
-sub create_auth_ticket {
- my ($secret, $username, $group) = @_;
-
- my $timestamp = time();
- my $ticket = $username . '::' . $group . '::' . $timestamp . '::' .
- Digest::SHA1::sha1_hex($username, $group, $timestamp, $secret);
-
- return $ticket;
-}
-
-sub verify_username {
- my $username = shift;
-
- # we only allow a limited set of characters (colon is not allowed,
- # because we store usernames in colon separated lists)!
- return $username if $username =~ m/^[A-Za-z0-9\.\-_]+(\@[A-Za-z0-9\.\-_]+)?$/;
-
- return undef;
-}
-
-sub verify_ticket {
- my ($secret, $ticket) = @_;
-
- my $cookie_timeout = 2400; # seconds
-
- my ($username, $group, $time, $mac) = split /::/, $ticket;
-
- return undef if !verify_username($username);
-
- my $age = time() - $time;
-
- if (($age > -300) && ($age < $cookie_timeout) &&
- (Digest::SHA1::sha1_hex($username, $group, $time, $secret) eq $mac)) {
- return wantarray ? ($username, $group, $age) : $username;
- }
-
- return undef;
-}
-
-sub verify_web_ticket {
- my ($secret, $ticket) = @_;
-
- my $cookie_timeout = 2400; # seconds
-
- my ($username, $group, $time, $mac, $webmac) = split /::/, $ticket;
-
- return undef if !verify_username($username);
-
- my $age = time() - $time;
-
- if (($age > -300) && ($age < $cookie_timeout) &&
- (Digest::SHA1::sha1_hex($username, $group, $time, $mac, $secret) eq $webmac)) {
- return wantarray ? ($username, $group, $age) : $username;
- }
-
- return undef;
-}
-
-# password should be utf8 encoded
-sub pam_is_valid_user {
- my ($username, $password) = @_;
-
- # user (www-data) need to be able to read /etc/passwd /etc/shadow
-
- my $pamh = new Authen::PAM ('common-auth', $username, sub {
- my @res;
- while(@_) {
- my $msg_type = shift;
- my $msg = shift;
- push @res, (0, $password);
- }
- push @res, 0;
- return @res;
- });
-
- if (!ref ($pamh)) {
- my $err = $pamh->pam_strerror($pamh);
- die "Error during PAM init: $err";
- }
-
- my $res;
-
- if (($res = $pamh->pam_authenticate(0)) != PAM_SUCCESS) {
- my $err = $pamh->pam_strerror($res);
- die "PAM auth failed: $err\n";
- }
-
- if (($res = $pamh->pam_acct_mgmt (0)) != PAM_SUCCESS) {
- my $err = $pamh->pam_strerror($res);
- die "PAM auth failed: $err\n";
- }
-
- $pamh = 0; # call destructor
-
- return 1;
-}
-
-sub is_valid_user {
- my ($username, $password) = @_;
-
- if (!verify_username ($username)) {
- syslog ('info', "auth failed: invalid characters in username '$username'");
- return undef;
- }
-
- my $valid = 0;
-
- eval {
- $valid = pam_is_valid_user ($username, $password);
- };
- my $err = $@;
-
- if ($err) {
- syslog ('info', $err);
- return undef;
- }
-
- return undef if !$valid;
-
- my ($name, $passwd, $uid, $gid) = getpwnam ($username);
- my $groupname = getgrgid($gid) || 'nogroup';
-
- # fixme: what groups are allowed?
- if ($groupname ne 'root') {
- syslog ('info', "auth failed: group '$groupname' is not in the list of allowed groups");
- return undef;
- }
-
- return $groupname;
-}
-
-# UPID helper
-# WARN: $res->{filename} must not depend on PID, because we
-# use it before we know the PID
-
-sub upid_decode {
- my $upid = shift;
-
- my $res;
-
- # "UPID:$pid:$start:$type:$data"
- if ($upid =~ m/^UPID:(\d+)(-(\d+))?:(\d+):([^:\s]+):(.*)$/) {
- $res->{pid} = $1;
- $res->{pstart} = $3 || 0;
- $res->{starttime} = $4;
- $res->{type} = $5;
- $res->{data} = $6;
-
- if ($res->{type} eq 'vmops') {
- if ($res->{data} =~ m/^([^:\s]+):(\d+):(\d+):(\S+)$/) {
- $res->{command} = $1;
- $res->{cid} = $2;
- $res->{veid} = $3;
- $res->{user} = $4;
-
- $res->{filename} = "/tmp/vmops-$res->{veid}.out";
- } else {
- return undef;
- }
- } elsif ($res->{type} eq 'apldownload') {
- if ($res->{data} =~ m/^([^:\s]+):(.+)$/) {
- $res->{user} = $1;
- $res->{apl} = $2;
- $res->{filename} = "/tmp/apldownload-$res->{user}.out";
- } else {
- return undef;
- }
- }
- }
-
- return $res;
-}
-
-sub upid_encode {
- my $uip_hash = shift;
-
- my $d = $uip_hash; # shortcut
-
- return "UPID:$d->{pid}-$d->{pstart}:$d->{starttime}:$d->{type}:$d->{data}";
-}
-
-
-# save $SIG{CHLD} handler implementation.
-# simply set $SIG{CHLD} = &PVE::Utils::worker_reaper;
-# and register forked processes with PVE::Utils::register_worker(pid)
-# Note: using $SIG{CHLD} = 'IGNORE' or $SIG{CHLD} = sub { wait (); } or ...
-# has serious side effects, because perls built in system() and open()
-# functions can't get the correct exit status of a child. So we cant use
-# that (also see perlipc)
-
-my $WORKER_PIDS;
-
-sub worker_reaper {
- local $!; local $?;
- foreach my $pid (keys %$WORKER_PIDS) {
- my $waitpid = waitpid ($pid, WNOHANG);
- if (defined($waitpid) && ($waitpid == $pid)) {
- delete ($WORKER_PIDS->{$pid});
- }
- }
-}
-
-sub register_worker {
- my $pid = shift;
-
- return if !$pid;
-
- # do not register if already finished
- my $waitpid = waitpid ($pid, WNOHANG);
- if (defined($waitpid) && ($waitpid == $pid)) {
- delete ($WORKER_PIDS->{$pid});
- return;
- }
-
- $WORKER_PIDS->{$pid} = 1;
-}
-
-sub trim {
- my $s = shift;
-
- return $s if !$s;
-
- $s =~ s/^\s*//;
- $s =~ s/\s*$//;
-
- return $s;
-}
-
-sub foreach_vmrec {
- my ($vmhash, $func) = @_;
-
- foreach my $ckey (keys %$vmhash) {
- next if $ckey !~ m/^CID_(\d+)$/;
- my $cid = $1;
- if (my $vmlist = $vmhash->{$ckey}) {
- foreach my $vmkey (sort keys %$vmlist) {
- next if $vmkey !~ m/^VEID_(\d+)$/;
- my $vmid = $1;
- my $d = $vmlist->{$vmkey};
- &$func ($cid, $vmid, $d, $ckey, $vmkey);
- }
- }
- }
-}
-
-sub foreach_cid {
- my ($vmhash, $func) = @_;
-
- foreach my $ckey (keys %$vmhash) {
- next if $ckey !~ m/^CID_(\d+)$/;
- my $cid = $1;
- if (my $vmlist = $vmhash->{$ckey}) {
- &$func ($cid, $vmlist, $ckey);
- }
- }
-}
-
-sub foreach_veid {
- my ($vmlist, $func) = @_;
-
- foreach my $vmkey (keys %$vmlist) {
- next if $vmkey !~ m/^VEID_(\d+)$/;
- my $veid = $1;
- if (my $d = $vmlist->{$vmkey}) {
- &$func ($veid, $d, $vmkey);
- }
- }
-}
-
-sub foreach_veid_sorted {
- my ($vmlist, $func) = @_;
-
- my @vma = ();
- foreach my $vmkey (keys %$vmlist) {
- next if $vmkey !~ m/^VEID_(\d+)$/;
- push @vma, $1;
- }
-
- foreach my $vmid (sort @vma) {
- my $vmkey = "VEID_$vmid";
- if (my $d = $vmlist->{$vmkey}) {
- &$func ($vmid, $d, $vmkey);
- }
- }
-}
-
-sub read_proc_uptime {
- my $ticks = shift;
-
- my $uptime;
- my $fh = IO::File->new ("/proc/uptime", "r");
- if (defined ($fh)) {
- my $line = <$fh>;
- $fh->close;
-
- if ($line =~ m|^(\d+\.\d+)\s+(\d+\.\d+)\s*$|) {
- if ($ticks) {
- return (int($1*100), int($2*100));
- } else {
- return (int($1), int($2));
- }
- }
- }
-
- return (0, 0);
-}
-
-sub read_proc_starttime {
- my $pid = shift;
-
- my $statstr;
- my $fh = IO::File->new ("/proc/$pid/stat", "r");
- if (defined ($fh)) {
- $statstr = <$fh>;
- $fh->close;
- }
-
- if ($statstr =~ m/^$pid \(.*\) \S (-?\d+) -?\d+ -?\d+ -?\d+ -?\d+ \d+ \d+ \d+ \d+ \d+ (\d+) (\d+) (-?\d+) (-?\d+) -?\d+ -?\d+ -?\d+ 0 (\d+) (\d+) (-?\d+) \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ \d+ -?\d+ -?\d+ \d+ \d+ \d+/) {
- my $ppid = $1;
- my $starttime = $6;
-
- return $starttime;
- }
-
- return 0;
-}
-
-sub check_process {
- my ($pid, $pstart) = @_;
-
- my $st = read_proc_starttime ($pid);
-
- return 0 if !$st;
-
- return $st == $pstart;
-}
-
-my $last_proc_stat;
-
-sub read_proc_stat {
- my $uptime;
-
- my $res = { user => 0, nice => 0, system => 0, idle => 0 , sum => 0};
-
- my $cpucount = 0;
-
- if (my $fh = IO::File->new ("/proc/stat", "r")) {
- while (defined (my $line = <$fh>)) {
- if ($line =~ m|^cpu\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s|) {
- $res->{user} = $1;
- $res->{nice} = $2;
- $res->{system} = $3;
- $res->{idle} = $4;
- $res->{used} = $1+$2+$3;
- $res->{iowait} = $5;
- } elsif ($line =~ m|^cpu\d+\s|) {
- $cpucount++;
- }
- }
- $fh->close;
- }
-
- $cpucount = 1 if !$cpucount;
-
- my $ctime = gettimeofday; # floating point time in seconds
-
- $res->{ctime} = $ctime;
- $res->{cpu} = 0;
- $res->{wait} = 0;
-
- $last_proc_stat = $res if !$last_proc_stat;
-
- my $diff = ($ctime - $last_proc_stat->{ctime}) * $clock_ticks * $cpucount;
-
- if ($diff > 1000) { # don't update too often
- my $useddiff = $res->{used} - $last_proc_stat->{used};
- $useddiff = $diff if $useddiff > $diff;
- $res->{cpu} = $useddiff/$diff;
- my $waitdiff = $res->{iowait} - $last_proc_stat->{iowait};
- $waitdiff = $diff if $waitdiff > $diff;
- $res->{wait} = $waitdiff/$diff;
- $last_proc_stat = $res;
- } else {
- $res->{cpu} = $last_proc_stat->{cpu};
- $res->{wait} = $last_proc_stat->{wait};
- }
-
- return $res;
-}
-
-sub get_uptime {
-
- my $res = { uptime => 0, idle => 0, avg1 => 0, avg5 => 0, avg15 => 0 };
-
- my $fh = IO::File->new ('/proc/loadavg', "r");
- my $line = <$fh>;
- $fh->close;
-
- if ($line =~ m|^(\d+\.\d+)\s+(\d+\.\d+)\s+(\d+\.\d+)\s+\d+/\d+\s+\d+\s*$|) {
- $res->{avg1} = $1;
- $res->{avg5} = $2;
- $res->{avg15} = $3;
- }
-
- ($res->{uptime}, $res->{idle}) = read_proc_uptime();
-
- my $ut = $res->{uptime};
- my $days = int ($ut / 86400);
- $ut -= $days*86400;
- my $hours = int ($ut / 3600);
- $ut -= $hours*3600;
- my $mins = $ut /60;
-
- my $utstr = strftime ("%H:%M:%S up ", localtime);
- if ($days) {
- my $ds = $days > 1 ? 'days' : 'day';
- $res->{uptimestrshort} = sprintf "%d $ds %02d:%02d", $days, $hours, $mins;
- } else {
- $res->{uptimestrshort} = sprintf "%02d:%02d", $hours, $mins;
- }
-
- $utstr .= "$res->{uptimestrshort}, ";
- $utstr .= "load average: $res->{avg1}, $res->{avg5}, $res->{avg15}";
- $res->{uptimestr} = $utstr;
-
- return $res;
-}
-
-
-# memory usage of current process
-sub get_mem_usage {
-
- my $res = { size => 0, resident => 0, shared => 0 };
-
- my $ps = 4096;
-
- open (MEMINFO, "</proc/$$/statm");
- my $line = <MEMINFO>;
- close (MEMINFO);
-
- if ($line =~ m/^(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+/) {
- $res->{size} = $1*$ps;
- $res->{resident} = $2*$ps;
- $res->{shared} = $3*$ps;
- }
-
- return $res;
-}
-
-sub get_memory_info {
-
- my $res = {
- memtotal => 0,
- memfree => 0,
- memused => 0,
- swaptotal => 0,
- swapfree => 0,
- swapused => 0,
- };
-
- open (MEMINFO, "/proc/meminfo");
-
- while (my $line = <MEMINFO>) {
- if ($line =~ m/^(\S+):\s+(\d+)\s*kB/i) {
- $res->{lc ($1)} = $2;
- }
- }
-
- close (MEMINFO);
-
- $res->{memused} = $res->{memtotal} - $res->{memfree};
- $res->{swapused} = $res->{swaptotal} - $res->{swapfree};
-
- $res->{mbmemtotal} = int ($res->{memtotal}/1024);
- $res->{mbmemfree} = int (($res->{memfree} + $res->{buffers} + $res->{cached})/1024);
- $res->{mbmemused} = $res->{mbmemtotal} - $res->{mbmemfree};
-
- $res->{mbswaptotal} = int ($res->{swaptotal}/1024);
- $res->{mbswapfree} = int ($res->{swapfree}/1024);
- $res->{mbswapused} = $res->{mbswaptotal} - $res->{mbswapfree};
-
- return $res;
-}
-
-sub get_hd_info {
- my ($dir) = @_;
-
- $dir = '/' if !$dir;
-
- my $hd = `df -P '$dir'`;
-
- # simfs ... openvz
- # vzfs ... virtuozzo
-
- my ($rootfs, $hdo_total, $hdo_used, $hdo_avail) = $hd =~
- m/^(simfs|vzfs|\/dev\/\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+\d+%\s.*$/mg;
-
- my $real_hd_used = int ($hdo_used/1024);
- my $real_hd_total = int ($hdo_total/1024);
-
- # available memory = total memory - reserved memory
- my $real_hd_avail = int (($hdo_used+$hdo_avail)/1024);
-
- return { total => $real_hd_total,
- avail => $real_hd_avail,
- used => $real_hd_used,
- free => $real_hd_avail - $real_hd_used
- };
-}
-
-my $cpuinfo;
-
-# cycles_per_jiffy = frequency_of_your_cpu/jiffies_per_second
-# jiffies_per_second = 1000
-
-# frequency_of_your_cpu can be read from /proc/cpuinfo, as:
-# cpu MHz : <frequency_of_your_cpu>
-
-sub get_cpu_info {
- my $fn = '/proc/cpuinfo';
-
- return $cpuinfo if $cpuinfo;
-
- open (CPUINFO, "<$fn");
-
- my $res;
-
- $res->{model} = 'unknown';
- $res->{mhz} = 0;
- $res->{cpus} = 0;
- $res->{cpu_cycles_per_jiffy} = 0; # just to be not 0
-
- #$cpu_total = 0;
-
- my $count = 0;
- while (my $line = <CPUINFO>) {
- if ($line =~ m/^processor\s*:\s*\d+\s*$/i) {
- $count++;
- } elsif ($line =~ m/^model\s+name\s*:\s*(.*)\s*$/i) {
- $res->{model} = $1 if $res->{model} eq 'unknown';
- } elsif ($line =~ m/^cpu\s+MHz\s*:\s*(\d+\.\d+)\s*$/i) {
- #$cpu_total += $1;
- $res->{mhz} = $1 if !$res->{mhz};
- $res->{cpu_cycles_per_jiffy} += $1 * 1000;
- } elsif ($line =~ m/^flags\s*:.*(vmx|svm)/) {
- $res->{hvm} = 1; # Hardware Virtual Machine (Intel VT / AMD-V)
- }
- }
-
- $res->{cpus} = $count;
-
- close (CPUINFO);
-
- $res->{kversion} = `uname -srv`;
-
- $res->{proxversion} = PVE::pvecfg::package() . "/" .
- PVE::pvecfg::version() . "/" .
- PVE::pvecfg::repoid();
-
- $cpuinfo = $res;
-
- return $res;
-}
-
-sub get_bridges {
-
- my $res = [];
-
- my $line;
- my $fd2;
-
- if ($fd2 = IO::File->new ("/proc/net/dev", "r")) {
- while (defined ($line = <$fd2>)) {
- chomp ($line);
- if ($line =~ m/^\s*(vmbr([0-9]{1,3})):.*/) {
- my ($name, $num) = ($1, $2);
- push @$res, $name if int($num) eq $num; # no leading zero
- }
- }
- close ($fd2);
- }
-
- return $res;
-}
-
-sub run_command {
- my ($cmd, $input, $timeout) = @_;
-
- my $reader = IO::File->new();
- my $writer = IO::File->new();
- my $error = IO::File->new();
-
- my $cmdstr = join (' ', @$cmd);
-
- my $orig_pid = $$;
-
- my $pid;
- eval {
- $pid = open3 ($writer, $reader, $error, @$cmd) || die $!;
- };
-
- my $err = $@;
-
- # catch exec errors
- if ($orig_pid != $$) {
- syslog ('err', "ERROR: $err");
- POSIX::_exit (1);
- kill ('KILL', $$);
- }
-
- die $err if $err;
-
- print $writer $input if defined $input;
- close $writer;
-
- my $select = new IO::Select;
- $select->add ($reader);
- $select->add ($error);
-
- my ($ostream, $estream) = ('', '');
-
- while ($select->count) {
- my @handles = $select->can_read ($timeout);
-
- if (defined ($timeout) && (scalar (@handles) == 0)) {
- kill (9, $pid);
- waitpid ($pid, 0);
- die "command '$cmdstr' failed: timeout";
- }
-
- foreach my $h (@handles) {
- my $buf = '';
- my $count = sysread ($h, $buf, 4096);
- if (!defined ($count)) {
- my $err = $!;
- kill (9, $pid);
- waitpid ($pid, 0);
- die "command '$cmdstr' failed: $err";
- }
- $select->remove ($h) if !$count;
- if ($h eq $reader) {
- $ostream .= $buf;
- } elsif ($h eq $error) {
- $ostream .= $buf;
- $estream .= $buf;
- }
- }
- }
-
- my $rv = waitpid ($pid, 0);
- my $ec = ($? >> 8);
-
- if ($ec) {
- if ($estream) {
- die "command '$cmdstr' failed with exit code $ec:\n$estream";
- }
- die "command '$cmdstr' failed with exit code $ec";
- }
-
- return $ostream;
-}
-
-sub _encrypt_pw {
- my ($pw) = @_;
-
- my $time = substr (Digest::SHA1::sha1_base64 (time), 0, 8);
- return crypt (encode("utf8", $pw), "\$1\$$time\$");
-}
-
-sub modify_user {
- my ($username, $group, $pw, $comment, $rawpw) = @_;
-
- my $cmd = ['/usr/sbin/usermod'];
-
- push @$cmd, '-c', $comment if defined ($comment);
-
- if ($pw) {
- my $epw = $rawpw ? $pw :_encrypt_pw ($pw);
- push @$cmd, '-p', $epw;
- }
-
- push @$cmd, '-g', $group if $group && $username ne 'root';
-
- return if scalar (@$cmd) == 1 ; # no flags given
-
- push @$cmd, $username;
-
- run_command ($cmd);
-}
-
-sub kvmkeymaps {
- return {
- 'dk' => ['Danish', 'da', 'qwerty/dk-latin1.kmap.gz', 'dk', 'nodeadkeys'],
- 'de' => ['German', 'de', 'qwertz/de-latin1-nodeadkeys.kmap.gz', 'de', 'nodeadkeys' ],
- 'de-ch' => ['Swiss-German', 'de-ch', 'qwertz/sg-latin1.kmap.gz', 'ch', 'de_nodeadkeys' ],
- 'en-gb' => ['United Kingdom', 'en-gb', 'qwerty/uk.kmap.gz' , 'gb', 'intl' ],
- 'en-us' => ['U.S. English', 'en-us', 'qwerty/us-latin1.kmap.gz', 'us', 'intl' ],
- 'es' => ['Spanish', 'es', 'qwerty/es.kmap.gz', 'es', 'nodeadkeys'],
- #'et' => [], # Ethopia or Estonia ??
- 'fi' => ['Finnish', 'fi', 'qwerty/fi-latin1.kmap.gz', 'fi', 'nodeadkeys'],
- #'fo' => ['Faroe Islands', 'fo', ???, 'fo', 'nodeadkeys'],
- 'fr' => ['French', 'fr', 'azerty/fr-latin1.kmap.gz', 'fr', 'nodeadkeys'],
- 'fr-be' => ['Belgium-French', 'fr-be', 'azerty/be2-latin1.kmap.gz', 'be', 'nodeadkeys'],
- 'fr-ca' => ['Canada-French', 'fr-ca', 'qwerty/cf.kmap.gz', 'ca', 'fr-legacy'],
- 'fr-ch' => ['Swiss-French', 'fr-ch', 'qwertz/fr_CH-latin1.kmap.gz', 'ch', 'fr_nodeadkeys'],
- #'hr' => ['Croatia', 'hr', 'qwertz/croat.kmap.gz', 'hr', ??], # latin2?
- 'hu' => ['Hungarian', 'hu', 'qwertz/hu.kmap.gz', 'hu', undef],
- 'is' => ['Icelandic', 'is', 'qwerty/is-latin1.kmap.gz', 'is', 'nodeadkeys'],
- 'it' => ['Italian', 'it', 'qwerty/it2.kmap.gz', 'it', 'nodeadkeys'],
- 'jp' => ['Japanese', 'ja', 'qwerty/jp106.kmap.gz', 'jp', undef],
- 'lt' => ['Lithuanian', 'lt', 'qwerty/lt.kmap.gz', 'lt', 'std'],
- #'lv' => ['Latvian', 'lv', 'qwerty/lv-latin4.kmap.gz', 'lv', ??], # latin4 or latin7?
- 'mk' => ['Macedonian', 'mk', 'qwerty/mk.kmap.gz', 'mk', 'nodeadkeys'],
- 'nl' => ['Dutch', 'nl', 'qwerty/nl.kmap.gz', 'nl', undef],
- #'nl-be' => ['Belgium-Dutch', 'nl-be', ?, ?, ?],
- 'no' => ['Norwegian', 'no', 'qwerty/no-latin1.kmap.gz', 'no', 'nodeadkeys'],
- 'pl' => ['Polish', 'pl', 'qwerty/pl.kmap.gz', 'pl', undef],
- 'pt' => ['Portuguese', 'pt', 'qwerty/pt-latin1.kmap.gz', 'pt', 'nodeadkeys'],
- 'pt-br' => ['Brazil-Portuguese', 'pt-br', 'qwerty/br-latin1.kmap.gz', 'br', 'nodeadkeys'],
- #'ru' => ['Russian', 'ru', 'qwerty/ru.kmap.gz', 'ru', undef], # dont know?
- 'si' => ['Slovenian', 'sl', 'qwertz/slovene.kmap.gz', 'si', undef],
- #'sv' => [], Swedish ?
- #'th' => [],
- #'tr' => [],
- };
-}
-
-sub debmirrors {
-
- return {
- 'at' => 'ftp.at.debian.org',
- 'au' => 'ftp.au.debian.org',
- 'be' => 'ftp.be.debian.org',
- 'bg' => 'ftp.bg.debian.org',
- 'br' => 'ftp.br.debian.org',
- 'ca' => 'ftp.ca.debian.org',
- 'ch' => 'ftp.ch.debian.org',
- 'cl' => 'ftp.cl.debian.org',
- 'cz' => 'ftp.cz.debian.org',
- 'de' => 'ftp.de.debian.org',
- 'dk' => 'ftp.dk.debian.org',
- 'ee' => 'ftp.ee.debian.org',
- 'es' => 'ftp.es.debian.org',
- 'fi' => 'ftp.fi.debian.org',
- 'fr' => 'ftp.fr.debian.org',
- 'gr' => 'ftp.gr.debian.org',
- 'hk' => 'ftp.hk.debian.org',
- 'hr' => 'ftp.hr.debian.org',
- 'hu' => 'ftp.hu.debian.org',
- 'ie' => 'ftp.ie.debian.org',
- 'is' => 'ftp.is.debian.org',
- 'it' => 'ftp.it.debian.org',
- 'jp' => 'ftp.jp.debian.org',
- 'kr' => 'ftp.kr.debian.org',
- 'mx' => 'ftp.mx.debian.org',
- 'nl' => 'ftp.nl.debian.org',
- 'no' => 'ftp.no.debian.org',
- 'nz' => 'ftp.nz.debian.org',
- 'pl' => 'ftp.pl.debian.org',
- 'pt' => 'ftp.pt.debian.org',
- 'ro' => 'ftp.ro.debian.org',
- 'ru' => 'ftp.ru.debian.org',
- 'se' => 'ftp.se.debian.org',
- 'si' => 'ftp.si.debian.org',
- 'sk' => 'ftp.sk.debian.org',
- 'tr' => 'ftp.tr.debian.org',
- 'tw' => 'ftp.tw.debian.org',
- 'gb' => 'ftp.uk.debian.org',
- 'us' => 'ftp.us.debian.org',
- };
-}
-
-sub shellquote {
- my $str = shift;
-
- return "''" if !defined ($str) || ($str eq '');
-
- die "unable to quote string containing null (\\000) bytes"
- if $str =~ m/\x00/;
-
- # from String::ShellQuote
- if ($str =~ m|[^\w!%+,\-./:@^]|) {
-
- # ' -> '\''
- $str =~ s/'/'\\''/g;
-
- $str = "'$str'";
- $str =~ s/^''//;
- $str =~ s/''$//;
- }
-
- return $str;
-}
-
-sub service_cmd {
- my ($service, $cmd) = @_;
-
- my $initd_cmd;
-
- ($cmd eq 'start' || $cmd eq 'stop' || $cmd eq 'restart'
- || $cmd eq 'reload' || $cmd eq 'awaken') ||
- die "unknown service command '$cmd': ERROR";
-
- if ($service eq 'postfix') {
- $initd_cmd = '/etc/init.d/postfix';
- } elsif ($service eq 'pvemirror') {
- $initd_cmd = '/etc/init.d/pvemirror';
- } elsif ($service eq 'pvetunnel') {
- $initd_cmd = '/etc/init.d/pvetunnel';
- } elsif ($service eq 'pvedaemon') {
- $initd_cmd = '/etc/init.d/pvedaemon';
- } elsif ($service eq 'apache') {
- if ($cmd eq 'restart') {
- $initd_cmd = '/usr/sbin/apache2ctl';
- $cmd = 'graceful';
- } else {
- die "invalid service cmd 'apache $cmd': ERROR";
- }
- } elsif ($service eq 'network') {
- if ($cmd eq 'restart') {
- return system ('(sleep 1; /etc/init.d/networking restart; /etc/init.d/postfix restart; /usr/sbin/apache2ctl graceful)&');
- }
- die "invalid service cmd 'network $cmd': ERROR";
- } elsif ($service eq 'ntpd') {
- # debian start/stop scripts does not work for us
- if ($cmd eq 'stop') {
- system ('/etc/init.d/ntp stop');
- #system ('/usr/bin/killall /usr/sbin/ntpd');
- } elsif ($cmd eq 'start') {
- system ('/etc/init.d/ntp start');
- system ('/sbin/hwclock --systohc');
- } elsif ($cmd eq 'restart') {
- system ('/etc/init.d/ntp restart');
- system ('/sbin/hwclock --systohc');
- # restart cron/syslog to get right schedules and log time/dates
- system ('/etc/init.d/sysklogd restart');
- system ('/etc/init.d/cron restart');
- }
- return 0;
- } elsif ($service eq 'syslog') {
- $initd_cmd = '/etc/init.d/sysklogd';
- } elsif ($service eq 'cron') {
- $initd_cmd = '/etc/init.d/cron';
- } elsif ($service eq 'sshd') {
- $initd_cmd = '/etc/init.d/ssh';
- } else {
- die "unknown service '$service': ERROR";
- }
-
- my $servicecmd = "$initd_cmd $cmd";
-
- my $res = run_command ([$initd_cmd, $cmd]);
-
- return $res;
-}
-
-sub service_state {
- my ($service) = @_;
-
- my $pid_file;
-
- if ($service eq 'postfix') {
- $pid_file = '/var/spool/postfix/pid/master.pid';
- } elsif ($service eq 'apache') {
- $pid_file = '/var/run/apache2.pid';
- } elsif ($service eq 'bind') {
- $pid_file = '/var/run/bind/run/named.pid';
- } elsif ($service eq 'pvemirror') {
- $pid_file = '/var/run/pvemirror.pid';
- } elsif ($service eq 'pvetunnel') {
- $pid_file = '/var/run/pvetunnel.pid';
- } elsif ($service eq 'pvedaemon') {
- $pid_file = '/var/run/pvedaemon.pid';
- } elsif ($service eq 'ntpd') {
- $pid_file = '/var/run/ntpd.pid';
- } elsif ($service eq 'sshd') {
- $pid_file = '/var/run/sshd.pid';
- } else {
- die "unknown service '$service': ERROR";
- }
-
- my $pid;
- if (my $fh = IO::File->new ($pid_file, "r")) {
- my $line = <$fh>;
- chomp $line;
-
- if ($line && ($line =~ m/^\s*(\d+)\s*$/)) {
- $pid = $1;
- }
- }
-
- return 'running' if ($pid && kill (0, $pid));
-
- return 'stopped';
-};
-
-sub service_wait_stopped {
- my ($timeout, @services) = @_;
-
- my $starttime = time();
-
- while (1) {
- my $wait = 0;
-
- foreach my $s (@services) {
- if (service_state ($s) eq 'running') {
-
- if ((time() - $starttime) > $timeout) {
- die "unable to stop services (got timeout)\n";
- }
-
- service_cmd ($s, 'stop');
- $wait = 1;
- }
- }
-
- if ($wait) {
- sleep (1);
- } else {
- last;
- }
- }
-}
-
-sub check_vm_settings {
- my ($settings) = @_;
-
- if (defined ($settings->{mem})) {
-
- my $max = 65536;
- my $min = 64;
-
- if ($settings->{mem} < $min) {
- die __("Memory needs to be at least $min MB") . "\n";
- }
- if ($settings->{mem} > $max) {
- die __("Memory needs to be less than $max MB") . "\n";
- }
- }
-
- if (defined ($settings->{swap})) {
-
- my $max = 65536;
-
- if ($settings->{swap} > $max) {
- die __("Swap needs to be less than $max MB") . "\n";
- }
- }
-
- if (defined ($settings->{cpuunits}) &&
- ($settings->{cpuunits} < 8 || $settings->{cpuunits} > 500000)) {
- die "parameter cpuunits out of range\n";
- }
-
- if (defined ($settings->{cpus}) &&
- ($settings->{cpus} < 1 || $settings->{cpus} > 16)) {
- die "parameter cpus out of range\n";
- }
-}
-
-1;
-
+++ /dev/null
-package PVE::API2;
-
-use strict;
-use warnings;
-
-use Apache2::Const qw(:http);
-use PVE::RESTHandler;
-
-use base qw(PVE::RESTHandler);
-
-# preload classes
-use PVE::API2::Cluster;
-use PVE::API2::Nodes;
-use PVE::API2::AccessControl;
-use PVE::API2::Storage::Config;
-
-__PACKAGE__->register_method ({
- subclass => "PVE::API2::Cluster",
- path => 'cluster',
-});
-
-__PACKAGE__->register_method ({
- subclass => "PVE::API2::Nodes",
- path => 'nodes',
-});
-
-__PACKAGE__->register_method ({
- subclass => "PVE::API2::Storage::Config",
- path => 'storage',
-});
-
-__PACKAGE__->register_method ({
- subclass => "PVE::API2::AccessControl",
- path => 'access',
-});
-
-__PACKAGE__->register_method ({
- name => 'index',
- path => '',
- method => 'GET',
- permissions => { user => 'all' },
- description => "Directory index.",
- parameters => {
- additionalProperties => 0,
- properties => {},
- },
- returns => {
- type => 'array',
- items => {
- type => "object",
- properties => {
- subdir => { type => 'string' },
- },
- },
- links => [ { rel => 'child', href => "{subdir}" } ],
- },
- code => sub {
- my ($resp, $param) = @_;
-
- my $res = [];
-
- my $ma = PVE::API2->method_attributes();
-
- foreach my $info (@$ma) {
- next if !$info->{subclass};
-
- my $subpath = $info->{match_re}->[0];
-
- push @$res, { subdir => $subpath };
- }
-
- return $res;
- }});
-
-1;
+++ /dev/null
-package PVE::API2::Cluster;
-
-use strict;
-use warnings;
-
-use PVE::SafeSyslog;
-use PVE::Tools qw(extract_param);
-use PVE::Cluster qw(cfs_lock_file cfs_read_file cfs_write_file);
-use PVE::Storage;
-use JSON;
-
-use Data::Dumper; # fixme: remove
-
-use Apache2::Const qw(:http);
-
-use PVE::RESTHandler;
-use PVE::RPCEnvironment;
-
-use base qw(PVE::RESTHandler);
-
-my $dc_schema = PVE::Cluster::get_datacenter_schema();
-my $dc_properties = {
- delete => {
- type => 'string', format => 'pve-configid-list',
- description => "A list of settings you want to delete.",
- optional => 1,
- }
-};
-foreach my $opt (keys %{$dc_schema->{properties}}) {
- $dc_properties->{$opt} = $dc_schema->{properties}->{$opt};
-}
-
-__PACKAGE__->register_method ({
- name => 'index',
- path => '',
- method => 'GET',
- description => "Cluster index.",
- permissions => { user => 'all' },
- parameters => {
- additionalProperties => 0,
- properties => {},
- },
- returns => {
- type => 'array',
- items => {
- type => "object",
- properties => {},
- },
- links => [ { rel => 'child', href => "{name}" } ],
- },
- code => sub {
- my ($param) = @_;
-
- my $result = [
- { name => 'log' },
- { name => 'options' },
- { name => 'resources' },
- { name => 'tasks' },
- ];
-
- return $result;
- }});
-
-__PACKAGE__->register_method({
- name => 'log',
- path => 'log',
- method => 'GET',
- description => "Read cluster log",
- permissions => { user => 'all' },
- parameters => {
- additionalProperties => 0,
- properties => {
- max => {
- type => 'integer',
- description => "Maximum number of entries.",
- optional => 1,
- minimum => 1,
- }
- },
- },
- returns => {
- type => 'array',
- items => {
- type => "object",
- properties => {},
- },
- },
- code => sub {
- my ($param) = @_;
-
- my $rpcenv = PVE::RPCEnvironment::get();
-
- my $max = $param->{max} || 0;
- my $user = $rpcenv->get_user();
-
- my $admin = $rpcenv->check($user, "/", [ 'Sys.Syslog' ]);
-
- my $loguser = $admin ? '' : $user;
-
- my $res = decode_json(PVE::Cluster::get_cluster_log($loguser, $max));
-
- return $res->{data};
- }});
-
-__PACKAGE__->register_method({
- name => 'resources',
- path => 'resources',
- method => 'GET',
- description => "Resources index (cluster wide).",
- permissions => { user => 'all' },
- parameters => {
- additionalProperties => 0,
- properties => {},
- },
- returns => {
- type => 'array',
- items => {
- type => "object",
- properties => {
- },
- },
- },
- code => sub {
- my ($param) = @_;
-
- my $rpcenv = PVE::RPCEnvironment::get();
- my $user = $rpcenv->get_user();
-
- my $res = [];
-
- my $nodes = PVE::Cluster::get_nodelist();
-
- my $rrd = PVE::Cluster::rrd_dump();
-
- my $vmlist = PVE::Cluster::get_vmlist() || {};
- my $idlist = $vmlist->{ids} || {};
-
-
- # we try to generate 'numbers' by using "$X + 0"
- foreach my $vmid (keys %$idlist) {
- my $data = $idlist->{$vmid};
-
- next if !$rpcenv->check($user, "/vms/$vmid", [ 'VM.Audit' ]);
-
- my $entry = {
- id => "$data->{type}/$vmid",
- vmid => $vmid + 0,
- node => $data->{node},
- type => $data->{type},
- };
-
- if (my $d = $rrd->{"pve2-vm/$vmid"}) {
-
- $entry->{uptime} = $d->[0] + 0;
- $entry->{name} = $d->[1];
-
- $entry->{maxcpu} = $d->[3] + 0;
- $entry->{cpu} = $d->[4] + 0;
- $entry->{maxmem} = $d->[5] + 0;
- $entry->{mem} = $d->[6] + 0;
- $entry->{maxdisk} = $d->[7] + 0;
- $entry->{disk} = $d->[8] + 0;
- }
-
- push @$res, $entry;
- }
-
- foreach my $node (@$nodes) {
- my $entry = {
- id => "node/$node",
- node => $node,
- type => "node",
- };
- if (my $d = $rrd->{"pve2-node/$node"}) {
-
- $entry->{uptime} = $d->[0] + 0;
- $entry->{maxcpu} = $d->[3] + 0;
- $entry->{cpu} = $d->[4] + 0;
- $entry->{maxmem} = $d->[6] + 0;
- $entry->{mem} = $d->[7] + 0;
- $entry->{maxdisk} = $d->[10] + 0;
- $entry->{disk} = $d->[11] + 0;
- }
-
- push @$res, $entry;
- }
-
- my $cfg = PVE::Storage::config();
- my @sids = PVE::Storage::storage_ids ($cfg);
-
- foreach my $storeid (@sids) {
- my $scfg = PVE::Storage::storage_config($cfg, $storeid);
- next if !$rpcenv->check($user, "/storage/$storeid", [ 'Datastore.Audit' ]);
- # we create a entry for each node
- foreach my $node (@$nodes) {
- next if !PVE::Storage::storage_check_enabled($cfg, $storeid, $node, 1);
- my $entry = {
- id => "storage/$node/$storeid",
- storage => $storeid,
- node => $node,
- type => 'storage',
- };
-
- if (my $d = $rrd->{"pve2-storage/$node/$storeid"}) {
- $entry->{maxdisk} = $d->[1] + 0;
- $entry->{disk} = $d->[2] + 0;
- }
-
- push @$res, $entry;
-
- }
- }
-
- return $res;
- }});
-
-__PACKAGE__->register_method({
- name => 'tasks',
- path => 'tasks',
- method => 'GET',
- description => "List recent tasks (cluster wide).",
- permissions => { user => 'all' },
- parameters => {
- additionalProperties => 0,
- properties => {},
- },
- returns => {
- type => 'array',
- items => {
- type => "object",
- properties => {
- upid => { type => 'string' },
- },
- },
- },
- code => sub {
- my ($param) = @_;
-
- my $rpcenv = PVE::RPCEnvironment::get();
- my $user = $rpcenv->get_user();
-
- my $tlist = PVE::Cluster::get_tasklist();
-
- my $res = [];
-
- return $res if !$tlist;
-
- my $all = $rpcenv->check($user, "/", [ 'Sys.Audit' ]);
-
- foreach my $task (@$tlist) {
- push @$res, $task if $all || ($task->{user} eq $user);
- }
-
- return $res;
- }});
-
-__PACKAGE__->register_method({
- name => 'get_options',
- path => 'options',
- method => 'GET',
- description => "Get datacenter options.",
- permissions => {
- path => '/',
- privs => [ 'Sys.Audit' ],
- },
- parameters => {
- additionalProperties => 0,
- properties => {},
- },
- returns => {
- type => "object",
- properties => {},
- },
- code => sub {
- my ($param) = @_;
- return PVE::Cluster::cfs_read_file('datacenter.cfg');
- }});
-
-__PACKAGE__->register_method({
- name => 'set_options',
- path => 'options',
- method => 'PUT',
- description => "Set datacenter options.",
- permissions => {
- path => '/',
- privs => [ 'Sys.Modify' ],
- },
- protected => 1,
- parameters => {
- additionalProperties => 0,
- properties => $dc_properties,
- },
- returns => { type => "null" },
- code => sub {
- my ($param) = @_;
-
- my $filename = 'datacenter.cfg';
-
- my $delete = extract_param($param, 'delete');
-
- my $code = sub {
-
- my $conf = cfs_read_file($filename);
-
- foreach my $opt (keys %$param) {
- $conf->{$opt} = $param->{$opt};
- }
-
- foreach my $opt (PVE::Tools::split_list($delete)) {
- delete $conf->{$opt};
- };
-
- cfs_write_file($filename, $conf);
- };
-
- cfs_lock_file($filename, undef, $code);
- die $@ if $@;
-
- return undef;
- }});
-
-1;
+++ /dev/null
-include $(top_builddir)/common.mk
-
-SUBDIRS=
-
-pvelib_DATA = \
- Cluster.pm \
- Nodes.pm \
- Tasks.pm \
- Network.pm \
- Services.pm
-
-CLEANFILES = *~
-
-pvelibdir = @PERL_LIBDIR@/PVE/API2
+++ /dev/null
-package PVE::API2::Network;
-
-use strict;
-use warnings;
-
-use PVE::Tools qw(extract_param);
-use PVE::SafeSyslog;
-use PVE::INotify;
-use PVE::Exception qw(raise_param_exc);
-use PVE::RESTHandler;
-use PVE::RPCEnvironment;
-use PVE::JSONSchema qw(get_standard_option);
-use PVE::AccessControl;
-use IO::File;
-
-use base qw(PVE::RESTHandler);
-
-my $iflockfn = "/etc/network/.pve-interfaces.lock";
-
-my $bond_mode_enum = [
- 'balance-rr',
- 'active-backup',
- 'balance-xor',
- 'broadcast',
- '802.3ad',
- 'balance-tlb',
- 'balance-alb'
- ];
-
-my $confdesc = {
- autostart => {
- description => "Automatically start interface on boot.",
- type => 'boolean',
- optional => 1,
- },
- bridge_ports => {
- description => "Specify the iterfaces you want to add to your bridge.",
- optional => 1,
- type => 'string', format => 'pve-iface-list',
- },
- slaves => {
- description => "Specify the interfaces used by the bonding device.",
- optional => 1,
- type => 'string', format => 'pve-iface-list',
- },
- bond_mode => {
- description => "Bonding mode.",
- optional => 1,
- type => 'string', enum => $bond_mode_enum,
- },
- gateway => {
- description => 'Default gateway address.',
- type => 'string', format => 'ipv4',
- optional => 1,
- },
- netmask => {
- description => 'Network mask.',
- type => 'string', format => 'ipv4mask',
- optional => 1,
- },
- address => {
- description => 'IP address.',
- type => 'string', format => 'ipv4',
- optional => 1,
- requires => 'netmask',
- }
-};
-
-sub json_config_properties {
- my $prop = shift;
-
- foreach my $opt (keys %$confdesc) {
- $prop->{$opt} = $confdesc->{$opt};
- }
-
- return $prop;
-}
-
-__PACKAGE__->register_method({
- name => 'index',
- path => '',
- method => 'GET',
- permissions => { user => 'all' },
- description => "List available networks",
- proxyto => 'node',
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- type => {
- description => "Only list specific interface types.",
- type => 'string',
- enum => ['bond', 'bridge', 'alias', 'eth'],
- optional => 1,
- },
- },
- },
- returns => {
- type => "array",
- items => {
- type => "object",
- properties => {},
- },
- links => [ { rel => 'child', href => "{iface}" } ],
- },
- code => sub {
- my ($param) = @_;
-
- my $config = PVE::INotify::read_file('interfaces');
-
- delete $config->{lo}; # do not list the loopback device
-
- if ($param->{type}) {
- foreach my $k (keys %$config) {
- delete $config->{$k} if $param->{type} ne $config->{$k}->{type};
- }
- }
-
- return PVE::RESTHandler::hash_to_array($config, 'iface');
- }});
-
-
-my $check_duplicate_gateway = sub {
- my ($config, $newiface) = @_;
-
- foreach my $iface (keys %$config) {
- raise_param_exc({ gateway => "Default gateway already exists on interface '$iface'." })
- if ($newiface ne $iface) && $config->{$iface}->{gateway};
- }
-};
-
-
-__PACKAGE__->register_method({
- name => 'create_network',
- path => '',
- method => 'POST',
- permissions => {
- path => '/nodes/{node}',
- privs => [ 'Sys.Modify' ],
- },
- description => "Create network device configuration",
- protected => 1,
- proxyto => 'node',
- parameters => {
- additionalProperties => 0,
- properties => json_config_properties({
- node => get_standard_option('pve-node'),
- iface => get_standard_option('pve-iface')}),
- },
- returns => { type => 'null' },
- code => sub {
- my ($param) = @_;
-
- my $node = extract_param($param, 'node');
- my $iface = extract_param($param, 'iface');
-
- my $code = sub {
- my $config = PVE::INotify::read_file('interfaces');
-
- raise_param_exc({ iface => "interface already exists" })
- if $config->{$iface};
-
- &$check_duplicate_gateway($config, $iface)
- if $param->{gateway};
-
- $param->{method} = $param->{address} ? 'static' : 'manual';
-
- $config->{$iface} = $param;
-
- PVE::INotify::write_file('interfaces', $config);
- };
-
- PVE::Tools::lock_file($iflockfn, 10, $code);
- die $@ if $@;
-
- return undef;
- }});
-
-__PACKAGE__->register_method({
- name => 'update_network',
- path => '{iface}',
- method => 'PUT',
- permissions => {
- path => '/nodes/{node}',
- privs => [ 'Sys.Modify' ],
- },
- description => "Update network device configuration",
- protected => 1,
- proxyto => 'node',
- parameters => {
- additionalProperties => 0,
- properties => json_config_properties({
- node => get_standard_option('pve-node'),
- iface => get_standard_option('pve-iface'),
- delete => {
- type => 'string', format => 'pve-configid-list',
- description => "A list of settings you want to delete.",
- optional => 1,
- }}),
- },
- returns => { type => 'null' },
- code => sub {
- my ($param) = @_;
-
- my $node = extract_param($param, 'node');
- my $iface = extract_param($param, 'iface');
- my $delete = extract_param($param, 'delete');
-
- my $code = sub {
- my $config = PVE::INotify::read_file('interfaces');
-
- raise_param_exc({ iface => "interface does not exist" })
- if !$config->{$iface};
-
- foreach my $k (PVE::Tools::split_list($delete)) {
- delete $config->{$iface}->{$k};
- }
-
- &$check_duplicate_gateway($config, $iface)
- if $param->{gateway};
-
- $param->{method} = $param->{address} ? 'static' : 'manual';
-
- foreach my $k (keys %$param) {
- $config->{$iface}->{$k} = $param->{$k};
- }
-
- PVE::INotify::write_file('interfaces', $config);
- };
-
- PVE::Tools::lock_file($iflockfn, 10, $code);
- die $@ if $@;
-
- return undef;
- }});
-
-__PACKAGE__->register_method({
- name => 'network_config',
- path => '{iface}',
- method => 'GET',
- permissions => {
- path => '/nodes/{node}',
- privs => [ 'Sys.Audit' ],
- },
- description => "Read network device configuration",
- proxyto => 'node',
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- iface => get_standard_option('pve-iface'),
- },
- },
- returns => {
- type => "object",
- properties => {
- type => {
- type => 'string',
- },
- method => {
- type => 'string',
- },
- },
- },
- code => sub {
- my ($param) = @_;
-
- my $config = PVE::INotify::read_file('interfaces');
-
- raise_param_exc({ iface => "interface does not exist" })
- if !$config->{$param->{iface}};
-
- return $config->{$param->{iface}};
- }});
-
-__PACKAGE__->register_method({
- name => 'delete_network',
- path => '{iface}',
- method => 'DELETE',
- permissions => {
- path => '/nodes/{node}',
- privs => [ 'Sys.Modify' ],
- },
- description => "Delete network device configuration",
- protected => 1,
- proxyto => 'node',
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- iface => get_standard_option('pve-iface'),
- },
- },
- returns => { type => 'null' },
- code => sub {
- my ($param) = @_;
-
- my $code = sub {
- my $config = PVE::INotify::read_file('interfaces');
-
- raise_param_exc({ iface => "interface does not exist" })
- if !$config->{$param->{iface}};
-
- delete $config->{$param->{iface}};
-
- PVE::INotify::write_file('interfaces', $config);
- };
-
- PVE::Tools::lock_file($iflockfn, 10, $code);
- die $@ if $@;
-
- return undef;
- }});
-
-
-
+++ /dev/null
-package PVE::API2::Nodes::Nodeinfo;
-
-use strict;
-use warnings;
-use POSIX;
-use Filesys::Df;
-use Time::Local qw(timegm_nocheck);
-use PVE::pvecfg;
-use PVE::Tools;
-use PVE::ProcFSTools;
-use PVE::SafeSyslog;
-use PVE::Cluster;
-use PVE::INotify;
-use PVE::RESTHandler;
-use PVE::RPCEnvironment;
-use PVE::JSONSchema qw(get_standard_option);
-use PVE::AccessControl;
-use PVE::API2::Services;
-use PVE::API2::Network;
-use PVE::API2::Tasks;
-use PVE::API2::Storage::Scan;
-use PVE::API2::Storage::Status;
-use PVE::API2::Qemu;
-use JSON;
-
-use base qw(PVE::RESTHandler);
-
-__PACKAGE__->register_method ({
- subclass => "PVE::API2::Qemu",
- path => 'qemu',
-});
-
-__PACKAGE__->register_method ({
- subclass => "PVE::API2::Services",
- path => 'services',
-});
-
-__PACKAGE__->register_method ({
- subclass => "PVE::API2::Network",
- path => 'network',
-});
-
-__PACKAGE__->register_method ({
- subclass => "PVE::API2::Tasks",
- path => 'tasks',
-});
-
-__PACKAGE__->register_method ({
- subclass => "PVE::API2::Storage::Scan",
- path => 'scan',
-});
-
-__PACKAGE__->register_method ({
- subclass => "PVE::API2::Storage::Status",
- path => 'storage',
-});
-
-__PACKAGE__->register_method ({
- name => 'index',
- path => '',
- method => 'GET',
- permissions => { user => 'all' },
- description => "Node index.",
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- },
- },
- returns => {
- type => 'array',
- items => {
- type => "object",
- properties => {},
- },
- links => [ { rel => 'child', href => "{name}" } ],
- },
- code => sub {
- my ($param) = @_;
-
- my $result = [
- { name => 'syslog' },
- { name => 'status' },
- { name => 'tasks' },
- { name => 'rrd' }, # fixme: remove?
- { name => 'rrddata' },# fixme: remove?
- { name => 'vncshell' },
- { name => 'time' },
- { name => 'dns' },
- { name => 'services' },
- { name => 'scan' },
- { name => 'storage' },
- { name => 'upload' },
- { name => 'qemu' },
- { name => 'network' },
- { name => 'network_changes' },
- ];
-
- return $result;
- }});
-
-__PACKAGE__->register_method({
- name => 'network_changes',
- path => 'network_changes',
- method => 'GET',
- permissions => {
- path => '/nodes/{node}',
- privs => [ 'Sys.Audit' ],
- },
- description => "Get network configuration changes (diff) since last boot.",
- proxyto => 'node',
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- },
- },
- returns => { type => "string" },
- code => sub {
- my ($param) = @_;
-
- my $res = PVE::INotify::read_file('interfaces', 1);
-
- return $res->{changes} || '';
- }});
-
-__PACKAGE__->register_method({
- name => 'revert_network_changes',
- path => 'network_changes',
- method => 'DELETE',
- permissions => {
- path => '/nodes/{node}',
- privs => [ 'Sys.Modify' ],
- },
- protected => 1,
- description => "Revert network configuration changes.",
- proxyto => 'node',
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- },
- },
- returns => { type => "null" },
- code => sub {
- my ($param) = @_;
-
- unlink "/etc/network/interfaces.new";
-
- return undef;
- }});
-
-__PACKAGE__->register_method({
- name => 'status',
- path => 'status',
- method => 'GET',
- permissions => {
- path => '/nodes/{node}',
- privs => [ 'Sys.Audit' ],
- },
- description => "Read node status",
- proxyto => 'node',
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- },
- },
- returns => {
- type => "object",
- properties => {
-
- },
- },
- code => sub {
- my ($param) = @_;
-
- my $res = {
- uptime => 0,
- idle => 0,
- };
-
- my ($uptime, $idle) = PVE::ProcFSTools::read_proc_uptime();
- $res->{uptime} = $uptime;
-
- my ($avg1, $avg5, $avg15) = PVE::ProcFSTools::read_loadavg();
- $res->{loadavg} = [ $avg1, $avg5, $avg15];
-
- my ($sysname, $nodename, $release, $version, $machine) = POSIX::uname();
-
- $res->{kversion} = "$sysname $release $version";
-
- $res->{cpuinfo} = PVE::ProcFSTools::read_cpuinfo();
-
- my $stat = PVE::ProcFSTools::read_proc_stat();
- $res->{cpu} = $stat->{cpu};
- $res->{wait} = $stat->{wait};
-
- my $meminfo = PVE::ProcFSTools::read_meminfo();
- $res->{memory} = {
- free => $meminfo->{memfree},
- total => $meminfo->{memtotal},
- used => $meminfo->{memused},
- };
- $res->{swap} = {
- free => $meminfo->{swapfree},
- total => $meminfo->{swaptotal},
- used => $meminfo->{swapused},
- };
-
- $res->{pveversion} = PVE::pvecfg::package() . "/" .
- PVE::pvecfg::version() . "/" .
- PVE::pvecfg::repoid();
-
- my $dinfo = df('/', 1); # output is bytes
-
- $res->{rootfs} = {
- total => $dinfo->{blocks},
- avail => $dinfo->{bavail},
- used => $dinfo->{used},
- free => $dinfo->{bavail} - $dinfo->{used},
- };
-
- return $res;
- }});
-
-__PACKAGE__->register_method({
- name => 'node_cmd',
- path => 'status',
- method => 'POST',
- permissions => {
- path => '/nodes/{node}',
- privs => [ 'Sys.PowerMgmt' ],
- },
- protected => 1,
- description => "Reboot or shutdown a node.",
- proxyto => 'node',
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- command => {
- description => "Specify the command.",
- type => 'string',
- enum => [qw(reboot shutdown)],
- },
- },
- },
- returns => { type => "null" },
- code => sub {
- my ($param) = @_;
-
- if ($param->{command} eq 'reboot') {
- system ("(sleep 2;/sbin/reboot)&");
- } elsif ($param->{command} eq 'shutdown') {
- system ("(sleep 2;/sbin/poweroff)&");
- }
-
- return undef;
- }});
-
-
-__PACKAGE__->register_method({
- name => 'rrd',
- path => 'rrd',
- method => 'GET',
- protected => 1, # fixme: can we avoid that?
- permissions => {
- path => '/nodes/{node}',
- privs => [ 'Sys.Audit' ],
- },
- description => "Read node RRD statistics (returns PNG)",
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- timeframe => {
- description => "Specify the time frame you are interested in.",
- type => 'string',
- enum => [ 'hour', 'day', 'week', 'month', 'year' ],
- },
- ds => {
- description => "The list of datasources you want to display.",
- type => 'string', format => 'pve-configid-list',
- },
- cf => {
- description => "The RRD consolidation function",
- type => 'string',
- enum => [ 'AVERAGE', 'MAX' ],
- optional => 1,
- },
- },
- },
- returns => {
- type => "object",
- properties => {
- filename => { type => 'string' },
- },
- },
- code => sub {
- my ($param) = @_;
-
- return PVE::Cluster::create_rrd_graph(
- "pve2-node/$param->{node}", $param->{timeframe},
- $param->{ds}, $param->{cf});
-
- }});
-
-__PACKAGE__->register_method({
- name => 'rrddata',
- path => 'rrddata',
- method => 'GET',
- protected => 1, # fixme: can we avoid that?
- permissions => {
- path => '/nodes/{node}',
- privs => [ 'Sys.Audit' ],
- },
- description => "Read node RRD statistics",
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- timeframe => {
- description => "Specify the time frame you are interested in.",
- type => 'string',
- enum => [ 'hour', 'day', 'week', 'month', 'year' ],
- },
- cf => {
- description => "The RRD consolidation function",
- type => 'string',
- enum => [ 'AVERAGE', 'MAX' ],
- optional => 1,
- },
- },
- },
- returns => {
- type => "array",
- items => {
- type => "object",
- properties => {},
- },
- },
- code => sub {
- my ($param) = @_;
-
- return PVE::Cluster::create_rrd_data(
- "pve2-node/$param->{node}", $param->{timeframe}, $param->{cf});
- }});
-
-__PACKAGE__->register_method({
- name => 'syslog',
- path => 'syslog',
- method => 'GET',
- description => "Read system log",
- proxyto => 'node',
- permissions => {
- path => '/nodes/{node}',
- privs => [ 'Sys.Syslog' ],
- },
- protected => 1,
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- start => {
- type => 'integer',
- minimum => 0,
- optional => 1,
- },
- limit => {
- type => 'integer',
- minimum => 0,
- optional => 1,
- },
- },
- },
- returns => {
- type => 'array',
- items => {
- type => "object",
- properties => {
- n => {
- description=> "Line number",
- type=> 'integer',
- },
- t => {
- description=> "Line text",
- type => 'string',
- }
- }
- }
- },
- code => sub {
- my ($param) = @_;
-
- my $lines = [];
-
- my $rpcenv = PVE::RPCEnvironment::get();
- my $user = $rpcenv->get_user();
- my $node = $param->{node};
-
- my $fh = IO::File->new("/var/log/syslog", "r");
- die "unable to open file - $!" if !$fh;
-
- my $start = $param->{start} || 0;
- my $limit = $param->{limit} || 50;
- my $count = 0;
- my $line;
- while (defined ($line = <$fh>)) {
- next if $count++ < $start;
- next if $limit <= 0;
- chomp $line;
- push @$lines, { n => $count, t => $line};
- $limit--;
- }
-
- close($fh);
-
- # HACK: ExtJS store.guaranteeRange() does not like empty array
- # so we add a line
- if (!$count) {
- $count++;
- push @$lines, { n => $count, t => "no content"};
- }
-
- $rpcenv->set_result_count($count);
-
- return $lines;
- }});
-
-my $sslcert;
-
-__PACKAGE__->register_method ({
- name => 'vncshell',
- path => 'vncshell',
- method => 'POST',
- protected => 1,
- permissions => {
- path => '/nodes/{node}',
- privs => [ 'Sys.Console' ],
- },
- description => "Creates a VNC Shell proxy.",
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- },
- },
- returns => {
- additionalProperties => 0,
- properties => {
- user => { type => 'string' },
- ticket => { type => 'string' },
- cert => { type => 'string' },
- port => { type => 'integer' },
- upid => { type => 'string' },
- },
- },
- code => sub {
- my ($param) = @_;
-
- my $rpcenv = PVE::RPCEnvironment::get();
-
- my $user = $rpcenv->get_user();
-
- my $ticket = PVE::AccessControl::assemble_ticket($user);
-
- my $node = $param->{node};
-
- $sslcert = PVE::Tools::file_get_contents("/etc/pve/pve-root-ca.pem", 8192)
- if !$sslcert;
-
- my $port = PVE::Tools::next_vnc_port();
-
- my $remip;
-
- if ($node ne PVE::INotify::nodename()) {
- $remip = PVE::Cluster::remote_node_ip($node);
- }
-
- # NOTE: vncterm VNC traffic is already TLS encrypted,
- # so we select the fastest chipher here (or 'none'?)
- my $remcmd = $remip ?
- ['/usr/bin/ssh', '-c', 'blowfish-cbc', '-t', $remip] : [];
-
- my $shcmd = $user eq 'root@pam' ? [ "/bin/bash", "-l" ] : [ "/bin/login" ];
-
- my $timeout = 10;
-
- # fixme: do we want to require special auth permissions?
- # example "-perm Shell"
- my @cmd = ('/usr/bin/vncterm', '-rfbport', $port,
- '-timeout', $timeout, '-authpath', "/nodes/$node",
- '-perm', 'Sys.Console', '-c', @$remcmd, @$shcmd);
-
- my $realcmd = sub {
- my $upid = shift;
-
- syslog ('info', "starting vnc proxy $upid\n");
-
- my $cmdstr = join (' ', @cmd);
- syslog ('info', "launch command: $cmdstr");
-
- if (system(@cmd) != 0) {
- my $msg = "vncterm failed - $?";
- syslog ('err', $msg);
- return;
- }
-
- return;
- };
-
- my $upid = $rpcenv->fork_worker('vncshell', "", $user, $realcmd);
-
- return {
- user => $user,
- ticket => $ticket,
- port => $port,
- upid => $upid,
- cert => $sslcert,
- };
- }});
-
-__PACKAGE__->register_method({
- name => 'dns',
- path => 'dns',
- method => 'GET',
- permissions => {
- path => '/nodes/{node}',
- privs => [ 'Sys.Audit' ],
- },
- description => "Read DNS settings.",
- proxyto => 'node',
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- },
- },
- returns => {
- type => "object",
- additionalProperties => 0,
- properties => {
- search => {
- description => "Search domain for host-name lookup.",
- type => 'string',
- optional => 1,
- },
- dns1 => {
- description => 'First name server IP address.',
- type => 'string',
- optional => 1,
- },
- dns2 => {
- description => 'Second name server IP address.',
- type => 'string',
- optional => 1,
- },
- dns3 => {
- description => 'Third name server IP address.',
- type => 'string',
- optional => 1,
- },
- },
- },
- code => sub {
- my ($param) = @_;
-
- my $res = PVE::INotify::read_file('resolvconf');
-
- return $res;
- }});
-
-__PACKAGE__->register_method({
- name => 'update_dns',
- path => 'dns',
- method => 'PUT',
- description => "Write DNS settings.",
- proxyto => 'node',
- protected => 1,
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- search => {
- description => "Search domain for host-name lookup.",
- type => 'string',
- },
- dns1 => {
- description => 'First name server IP address.',
- type => 'string', format => 'ipv4',
- optional => 1,
- },
- dns2 => {
- description => 'Second name server IP address.',
- type => 'string', format => 'ipv4',
- optional => 1,
- },
- dns3 => {
- description => 'Third name server IP address.',
- type => 'string', format => 'ipv4',
- optional => 1,
- },
- },
- },
- returns => { type => "null" },
- code => sub {
- my ($param) = @_;
-
- PVE::INotify::update_file('resolvconf', $param);
-
- return undef;
- }});
-
-__PACKAGE__->register_method({
- name => 'time',
- path => 'time',
- method => 'GET',
- permissions => {
- path => '/nodes/{node}',
- privs => [ 'Sys.Audit' ],
- },
- description => "Read server time and time zone settings.",
- proxyto => 'node',
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- },
- },
- returns => {
- type => "object",
- additionalProperties => 0,
- properties => {
- timezone => {
- description => "Time zone",
- type => 'string',
- },
- time => {
- description => "Seconds since 1970-01-01 00:00:00 UTC.",
- type => 'integer',
- minimum => 1297163644,
- },
- localtime => {
- description => "Seconds since 1970-01-01 00:00:00 (local time)",
- type => 'integer',
- minimum => 1297163644,
- },
- },
- },
- code => sub {
- my ($param) = @_;
-
- my $ctime = time();
- my $ltime = timegm_nocheck(localtime($ctime));
- my $res = {
- timezone => PVE::INotify::read_file('timezone'),
- time => time(),
- localtime => $ltime,
- };
-
- return $res;
- }});
-
-__PACKAGE__->register_method({
- name => 'set_timezone',
- path => 'time',
- method => 'PUT',
- description => "Set time zone.",
- proxyto => 'node',
- protected => 1,
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- timezone => {
- description => "Time zone. The file '/usr/share/zoneinfo/zone.tab' contains the list of valid names.",
- type => 'string',
- },
- },
- },
- returns => { type => "null" },
- code => sub {
- my ($param) = @_;
-
- PVE::INotify::write_file('timezone', $param->{timezone});
-
- return undef;
- }});
-
-__PACKAGE__->register_method ({
- name => 'upload',
- path => 'upload',
- method => 'POST',
- permissions => {
- path => '/storage/{storage}',
- privs => [ 'Datastore.AllocateSpace' ],
- },
- description => "Upload content.",
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- storage => get_standard_option('pve-storage-id'),
- filename => {
- description => "The name of the file to create/upload.",
- type => 'string',
- },
- vmid => get_standard_option
- ('pve-vmid', {
- description => "Specify owner VM",
- optional => 1,
- }),
- },
- },
- returns => {
- description => "Volume identifier",
- type => 'string',
- },
- code => sub {
- my ($param) = @_;
-
- # todo: can we proxy file uploads to remote nodes?
- if ($param->{node} ne PVE::INotify::nodename()) {
- raise_param_exc({ node => "can't upload content to remote node" });
- }
-
- my $node = $param->{node};
- my $storeid = $param->{storage};
- my $name = $param->{filename};
-
- my $fh = CGI::upload('filename') || die "unable to get file handle\n";
-
- syslog ('info', "UPLOAD $name to $node $storeid");
-
- # fixme:
- die "upload not implemented\n";
-
- my $buffer = "";
- my $tmpname = "/tmp/proxmox_upload-$$.bin";
-
- eval {
- open FILE, ">$tmpname" || die "can't open temporary file '$tmpname' - $!\n";
- while (read($fh, $buffer, 32768)) {
- die "write failed - $!" unless print FILE $buffer;
- }
- close FILE || die " can't close temporary file '$tmpname' - $!\n";
- };
- my $err = $@;
-
- if ($err) {
- unlink $tmpname;
- die $err;
- }
-
- unlink $tmpname; # fixme: proxy to local host import
-
- # fixme: return volid
-
- return undef;
-
- }});
-
-package PVE::API2::Nodes;
-
-use strict;
-use warnings;
-
-use PVE::SafeSyslog;
-use PVE::Cluster;
-use PVE::RESTHandler;
-use PVE::RPCEnvironment;
-
-use base qw(PVE::RESTHandler);
-
-__PACKAGE__->register_method ({
- subclass => "PVE::API2::Nodes::Nodeinfo",
- path => '{node}',
-});
-
-__PACKAGE__->register_method ({
- name => 'index',
- path => '',
- method => 'GET',
- permissions => { user => 'all' },
- description => "Cluster node index.",
- parameters => {
- additionalProperties => 0,
- properties => {},
- },
- returns => {
- type => 'array',
- items => {
- type => "object",
- properties => {},
- },
- links => [ { rel => 'child', href => "{name}" } ],
- },
- code => sub {
- my ($param) = @_;
-
- my $clinfo = PVE::Cluster::get_clinfo();
- my $res = [];
-
- my $nodename = PVE::INotify::nodename();
- my $nodelist = $clinfo->{nodelist};
-
- my $rrd = PVE::Cluster::rrd_dump();
-
- my @nodes = $nodelist ? (keys %$nodelist) : $nodename;
-
- foreach my $node (@nodes) {
- my $entry = { name => $node };
- if (my $d = $rrd->{"pve2-node/$node"}) {
-
- $entry->{uptime} = $d->[0];
- $entry->{maxcpu} = $d->[3];
- $entry->{cpu} = $d->[4];
- $entry->{maxmem} = $d->[6];
- $entry->{mem} = $d->[7];
- $entry->{maxdisk} = $d->[10];
- $entry->{disk} = $d->[11];
- }
-
- push @$res, $entry;
- }
-
- return $res;
- }});
-
-1;
+++ /dev/null
-package PVE::API2::Services;
-
-use strict;
-use warnings;
-
-use PVE::Tools;
-use PVE::SafeSyslog;
-use PVE::Cluster;
-use PVE::INotify;
-use PVE::Exception qw(raise_param_exc);
-use PVE::RESTHandler;
-use PVE::RPCEnvironment;
-use PVE::JSONSchema qw(get_standard_option);
-use PVE::AccessControl;
-use IO::File;
-
-use base qw(PVE::RESTHandler);
-
-my $service_list = {
- apache => { name => 'WWW', desc => 'Web/API server' },
- postfix => { name => 'SMTP', desc => 'Simple Mail Tranfer Protocol' },
- ntpd => { name => 'NTP', desc => 'Network time protocol' },
- sshd => { name => 'SSH', desc => 'Secure shell daemon' },
- syslog => { name => 'Syslog', desc => 'Syslog daemon' },
- cron => { name => 'CRON', desc => 'Daemon to execute scheduled commands' },
- pvedaemon => { name => 'NodeManager', desc => 'PVE node manager daemon' },
- corosync => { name => 'Corosync', desc => 'Corosync cluster daemon' },
- pvecluster => { name => 'PVECluster', desc => 'Proxmox VE cluster file system' },
-};
-
-my $service_cmd = sub {
- my ($service, $cmd) = @_;
-
- my $initd_cmd;
-
- die "unknown service command '$cmd'\n"
- if $cmd !~ m/^(start|stop|restart|reload)$/;
-
- $cmd = $1; # untaint
-
- if ($service eq 'postfix') {
- $initd_cmd = '/etc/init.d/postfix';
- } elsif ($service eq 'pvecluster') {
- if ($cmd eq 'restart') {
- $initd_cmd = '/etc/init.d/pve-cluster';
- } else {
- die "invalid service cmd 'pve-cluster $cmd': ERROR";
- }
- } elsif ($service eq 'pvedaemon') {
- if ($cmd eq 'restart') {
- $initd_cmd = '/etc/init.d/pvedaemon';
- } else {
- die "invalid service cmd '$service $cmd': ERROR";
- }
- } elsif ($service eq 'apache') {
- if ($cmd eq 'restart') {
- $initd_cmd = '/usr/sbin/apache2ctl';
- $cmd = 'graceful';
- } else {
- die "invalid service cmd '$service $cmd': ERROR";
- }
- } elsif ($service eq 'ntpd') {
- # debian start/stop scripts does not work for us
- if ($cmd eq 'stop') {
- system ('/etc/init.d/ntp stop');
- #system ('/usr/bin/killall /usr/sbin/ntpd');
- } elsif ($cmd eq 'start') {
- system ('/etc/init.d/ntp start');
- system ('/sbin/hwclock --systohc');
- } elsif ($cmd eq 'restart') {
- system ('/etc/init.d/ntp restart');
- system ('/sbin/hwclock --systohc');
- # restart cron/syslog to get right schedules and log time/dates
- system ('/etc/init.d/rsyslog restart');
- system ('/etc/init.d/cron restart');
- }
- return 0;
- } elsif ($service eq 'syslog') {
- $initd_cmd = '/etc/init.d/rsyslog';
- } elsif ($service eq 'cron') {
- $initd_cmd = '/etc/init.d/cron';
- } elsif ($service eq 'corosync') {
- $initd_cmd = '/etc/init.d/cman';
- } elsif ($service eq 'sshd') {
- $initd_cmd = '/etc/init.d/ssh';
- } else {
- die "unknown service '$service': ERROR";
- }
-
- PVE::Tools::run_command ([$initd_cmd, $cmd]);
-};
-
-my $service_state = sub {
- my ($service) = @_;
-
- my $pid_file;
-
- if ($service eq 'postfix') {
- $pid_file = '/var/spool/postfix/pid/master.pid';
- } elsif ($service eq 'apache') {
- $pid_file = '/var/run/apache2.pid';
- } elsif ($service eq 'pvedaemon') {
- $pid_file = '/var/run/pvedaemon.pid';
- } elsif ($service eq 'pvecluster') {
- $pid_file = '/var/run/pve-cluster.pid';
- } elsif ($service eq 'ntpd') {
- $pid_file = '/var/run/ntpd.pid';
- } elsif ($service eq 'sshd') {
- $pid_file = '/var/run/sshd.pid';
- } elsif ($service eq 'cron') {
- $pid_file = '/var/run/crond.pid';
- } elsif ($service eq 'corosync') {
- $pid_file = '/var/run/corosync.pid';
- } elsif ($service eq 'syslog') {
- $pid_file = '/var/run/rsyslogd.pid';
- } else {
- die "unknown service '$service': ERROR";
- }
-
- my $pid;
- if (my $fh = IO::File->new ($pid_file, "r")) {
- my $line = <$fh>;
- chomp $line;
-
- if ($line && ($line =~ m/^\s*(\d+)\s*$/)) {
- $pid = $1;
- }
- }
-
- return 'running' if ($pid && kill (0, $pid));
-
- return 'stopped';
-};
-
-__PACKAGE__->register_method ({
- name => 'index',
- path => '',
- method => 'GET',
- permissions => {
- path => '/nodes/{node}',
- privs => [ 'Sys.Audit' ],
- },
- description => "Service list.",
- proxyto => 'node',
- protected => 1,
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- },
- },
- returns => {
- type => 'array',
- items => {
- type => "object",
- properties => {},
- },
- links => [ { rel => 'child', href => "{service}" } ],
- },
- code => sub {
- my ($param) = @_;
-
- my $res = [];
-
- foreach my $id (keys %{$service_list}) {
- push @$res, {
- service => $id,
- name => $service_list->{$id}->{name},
- desc => $service_list->{$id}->{desc},
- state => &$service_state($id),
- };
- }
-
- return $res;
- }});
-
-__PACKAGE__->register_method ({
- name => 'state',
- path => '{service}',
- method => 'GET',
- permissions => {
- path => '/nodes/{node}',
- privs => [ 'Sys.Audit' ],
- },
- description => "Read service properties",
- proxyto => 'node',
- protected => 1,
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- service => {
- description => "Service ID",
- type => 'string',
- enum => [ keys %{$service_list} ],
- },
- },
- },
- returns => {
- type => "object",
- properties => {},
- },
- code => sub {
- my ($param) = @_;
-
- my $si = $service_list->{$param->{service}};
- return {
- service => $param->{service},
- name => $si->{name},
- desc => $si->{desc},
- state => &$service_state($param->{service}),
- };
- }});
-
-__PACKAGE__->register_method ({
- name => 'cmd',
- path => '{service}',
- method => 'PUT',
- description => "Execute service commands.",
- proxyto => 'node',
- protected => 1,
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- service => {
- description => "Service ID",
- type => 'string',
- enum => [ keys %{$service_list} ],
- },
- command => {
- description => "The command to execute. The only valid command for service 'apache' and 'pvedaemon' is 'restart', because both services are required by this API.",
- type => 'string',
- enum => [qw(start stop restart reload)],
- },
- },
- },
- returns => { type => 'null'},
- code => sub {
- my ($param) = @_;
-
- my $si = $service_list->{$param->{service}};
- &$service_cmd($param->{service}, $param->{command});
-
- return undef;
- }});
+++ /dev/null
-package PVE::API2::Tasks;
-
-use strict;
-use warnings;
-use POSIX;
-use IO::File;
-use File::ReadBackwards;
-use PVE::Tools;
-use PVE::SafeSyslog;
-use PVE::RESTHandler;
-use PVE::ProcFSTools;
-use PVE::RPCEnvironment;
-use PVE::JSONSchema qw(get_standard_option);
-use PVE::AccessControl;
-
-use base qw(PVE::RESTHandler);
-
-__PACKAGE__->register_method({
- name => 'node_tasks',
- path => '',
- method => 'GET',
- permissions => { user => 'all' },
- description => "Read task list for one node (finished tasks).",
- proxyto => 'node',
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- start => {
- type => 'integer',
- minimum => 0,
- optional => 1,
- },
- limit => {
- type => 'integer',
- minimum => 0,
- optional => 1,
- },
- userfilter => {
- type => 'string',
- optional => 1,
- },
- errors => {
- type => 'boolean',
- optional => 1,
- },
- },
- },
- returns => {
- type => 'array',
- items => {
- type => "object",
- properties => {
- upid => { type => 'string' },
- },
- },
- links => [ { rel => 'child', href => "{upid}" } ],
- },
- code => sub {
- my ($param) = @_;
-
- my $rpcenv = PVE::RPCEnvironment::get();
- my $user = $rpcenv->get_user();
-
- my $res = [];
-
- my $filename = "/var/log/pve/tasks/index";
-
- my $node = $param->{node};
- my $start = $param->{start} || 0;
- my $limit = $param->{limit} || 50;
- my $userfilter = $param->{userfilter};
- my $errors = $param->{errors};
-
- my $count = 0;
- my $line;
-
- my $auditor = $rpcenv->check($user, "/nodes/$node", [ 'Sys.Audit' ]);
-
- my $parse_line = sub {
- if ($line =~ m/^(\S+)(\s([0-9A-Za-z]{8})(\s(\S.*))?)?$/) {
- my $upid = $1;
- my $endtime = $3;
- my $status = $5;
- if ((my $task = PVE::Tools::upid_decode($upid, 1))) {
- return if $userfilter && $task->{user} !~ m/\Q$userfilter\E/i;
- next if !($auditor || $user eq $task->{user});
-
- return if $errors && $status && $status eq 'OK';
-
- return if $count++ < $start;
- return if $limit <= 0;
-
- $task->{upid} = $upid;
- $task->{endtime} = hex($endtime) if $endtime;
- $task->{status} = $status if $status;
- push @$res, $task;
- $limit--;
- }
- }
- };
-
- if (my $bw = File::ReadBackwards->new($filename)) {
- while (defined ($line = $bw->readline)) {
- &$parse_line();
- }
- $bw->close();
- }
- if (my $bw = File::ReadBackwards->new("$filename.1")) {
- while (defined ($line = $bw->readline)) {
- &$parse_line();
- }
- $bw->close();
- }
-
- $rpcenv->set_result_count($count);
-
- return $res;
- }});
-
-__PACKAGE__->register_method({
- name => 'upid_index',
- path => '{upid}',
- method => 'GET',
- description => '', # index helper
- permissions => { user => 'all' },
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- upid => { type => 'string' },
- }
- },
- returns => {
- type => 'array',
- items => {
- type => "object",
- properties => {},
- },
- links => [ { rel => 'child', href => "{name}" } ],
- },
- code => sub {
- my ($param) = @_;
-
- return [
- { name => 'log' },
- { name => 'status' }
- ];
- }});
-
-__PACKAGE__->register_method({
- name => 'stop_task',
- path => '{upid}',
- method => 'DELETE',
- description => 'Stop a task.',
- permissions => { user => 'all' },
- protected => 1,
- proxyto => 'node',
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- upid => { type => 'string' },
- }
- },
- returns => { type => 'null' },
- code => sub {
- my ($param) = @_;
-
- my ($task, $filename) = PVE::Tools::upid_decode($param->{upid}, 1);
- raise_param_exc({ upid => "unable to parse worker upid" }) if !$task;
- raise_param_exc({ upid => "no such task" }) if ! -f $filename;
-
- my $rpcenv = PVE::RPCEnvironment::get();
- my $user = $rpcenv->get_user();
- my $node = $param->{node};
-
- my $sysadmin = $rpcenv->check($user, "/nodes/$node", [ 'Sys.Console' ]);
- die "Permission check failed\n"
- if !($sysadmin || $user eq $task->{user});
-
- my $pstart = PVE::ProcFSTools::read_proc_starttime($task->{pid});
- $task->{status} = ($pstart && ($pstart == $task->{pstart})) ?
- 'running' : 'stopped';
-
- die "not implemented - fixme";
-
- return undef;
- }});
-
-__PACKAGE__->register_method({
- name => 'read_task_log',
- path => '{upid}/log',
- method => 'GET',
- permissions => { user => 'all' },
- protected => 1,
- description => "Read task log.",
- proxyto => 'node',
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- upid => { type => 'string' },
- start => {
- type => 'integer',
- minimum => 0,
- optional => 1,
- },
- limit => {
- type => 'integer',
- minimum => 0,
- optional => 1,
- },
- },
- },
- returns => {
- type => 'array',
- items => {
- type => "object",
- properties => {
- n => {
- description=> "Line number",
- type=> 'integer',
- },
- t => {
- description=> "Line text",
- type => 'string',
- }
- }
- }
- },
- code => sub {
- my ($param) = @_;
-
- my ($task, $filename) = PVE::Tools::upid_decode($param->{upid}, 1);
- raise_param_exc({ upid => "unable to parse worker upid" }) if !$task;
-
- my $lines = [];
-
- my $rpcenv = PVE::RPCEnvironment::get();
- my $user = $rpcenv->get_user();
- my $node = $param->{node};
-
- my $auditor = $rpcenv->check($user, "/nodes/$node", [ 'Sys.Audit' ]);
- die "Permission check failed\n"
- if !($auditor || $user eq $task->{user});
-
- my $fh = IO::File->new($filename, "r");
- raise_param_exc({ upid => "no such task - unable to open file - $!" }) if !$fh;
-
- my $start = $param->{start} || 0;
- my $limit = $param->{limit} || 50;
- my $count = 0;
- my $line;
- while (defined ($line = <$fh>)) {
- next if $count++ < $start;
- next if $limit <= 0;
- chomp $line;
- push @$lines, { n => $count, t => $line};
- $limit--;
- }
-
- close($fh);
-
- # HACK: ExtJS store.guaranteeRange() does not like empty array
- # so we add a line
- if (!$count) {
- $count++;
- push @$lines, { n => $count, t => "no content"};
- }
-
- $rpcenv->set_result_count($count);
-
- return $lines;
- }});
-
-__PACKAGE__->register_method({
- name => 'read_task_status',
- path => '{upid}/status',
- method => 'GET',
- permissions => { user => 'all' },
- protected => 1,
- description => "Read task status.",
- proxyto => 'node',
- parameters => {
- additionalProperties => 0,
- properties => {
- node => get_standard_option('pve-node'),
- upid => { type => 'string' },
- },
- },
- returns => {
- type => "object",
- properties => {
- pid => {
- type => 'integer'
- },
- status => {
- type => 'string', enum => ['running', 'stopped'],
- },
- },
- },
- code => sub {
- my ($param) = @_;
-
- my ($task, $filename) = PVE::Tools::upid_decode($param->{upid}, 1);
- raise_param_exc({ upid => "unable to parse worker upid" }) if !$task;
- raise_param_exc({ upid => "no such task" }) if ! -f $filename;
-
- my $lines = [];
-
- my $rpcenv = PVE::RPCEnvironment::get();
- my $user = $rpcenv->get_user();
- my $node = $param->{node};
-
- my $auditor = $rpcenv->check($user, "/nodes/$node", [ 'Sys.Audit' ]);
- die "Permission check failed\n"
- if !($auditor || $user eq $task->{user});
-
- my $pstart = PVE::ProcFSTools::read_proc_starttime($task->{pid});
- $task->{status} = ($pstart && ($pstart == $task->{pstart})) ?
- 'running' : 'stopped';
-
- $task->{upid} = $param->{upid}; # include upid
-
- return $task;
- }});
+++ /dev/null
-package PVE::API2Client;
-
-use strict;
-use warnings;
-use URI;
-use HTTP::Cookies;
-use LWP::UserAgent;
-use JSON;
-use PVE::API2;
-use Data::Dumper; # fixme: remove
-use HTTP::Request::Common;
-
-sub get {
- my ($self, $path, $param) = @_;
-
- return $self->call('GET', $path, $param);
-}
-
-sub post {
- my ($self, $path, $param) = @_;
-
- return $self->call('POST', $path, $param);
-}
-
-sub put {
- my ($self, $path, $param) = @_;
-
- return $self->call('PUT', $path, $param);
-}
-
-sub delete {
- my ($self, $path, $param) = @_;
-
- return $self->call('DELETE', $path, $param);
-}
-
-sub call {
- my ($self, $method, $path, $param) = @_;
-
- #print "wrapper called\n";
-
- my $ticket;
-
- my $ua = $self->{useragent};
- my $cj = $self->{cookie_jar};
-
- $cj->scan(sub {
- my ($version, $key, $val) = @_;
- $ticket = $val if $key eq 'PVEAuthCookie';
- });
-
- if (!$ticket && $self->{username} && $self->{password}) {
- my $uri = URI->new();
- $uri->scheme($self->{protocol});
- $uri->host($self->{host});
- $uri->port($self->{port});
- $uri->path('/api2/json/ticket');
-
- my $response = $ua->post($uri, {
- username => $self->{username},
- password => $self->{password}});
-
- if (!$response->is_success) {
- die $response->status_line . "\n";
- }
- # the auth cookie should be set now
- }
-
- my $uri = URI->new();
- $uri->scheme($self->{protocol});
- $uri->host($self->{host});
- $uri->port($self->{port});
- $uri->path($path);
-
- # print $ua->{cookie_jar}->as_string;
-
- #print "CALL $method : " . $uri->as_string() . "\n";
-
- my $response;
- if ($method eq 'GET') {
- $uri->query_form($param);
- $response = $ua->request(HTTP::Request::Common::GET($uri));
- } elsif ($method eq 'POST') {
- $response = $ua->request(HTTP::Request::Common::POST($uri, Content => $param));
- } elsif ($method eq 'PUT') {
- $response = $ua->request(HTTP::Request::Common::PUT($uri, Content => $param));
- } elsif ($method eq 'DELETE') {
- $response = $ua->request(HTTP::Request::Common::DELETE($uri));
- } else {
- die "method $method not implemented\n";
- }
-
- #print "RESP: " . Dumper($response) . "\n";
-
- if ($response->is_success) {
- my $ct = $response->header('Content-Type');
-
- die "got unexpected content type" if $ct ne 'application/json';
-
- return from_json($response->decoded_content, {utf8 => 1, allow_nonref => 1});
-
- } else {
-
- die $response->status_line . "\n";
-
- }
-}
-
-sub new {
- my ($class, %param) = @_;
-
- my $self = {
- ticket => $param{ticket},
- username => $param{username},
- password => $param{password},
- host => $param{host} || 'localhost',
- port => $param{port},
- timeout => $param{timeout} || 60,
- };
- bless $self;
-
- if (!$self->{port}) {
- $self->{port} = $self->{host} eq 'localhost' ? 85 : 8006;
- }
- if (!$self->{protocol}) {
- $self->{protocol} = $self->{host} eq 'localhost' ? 'http' : 'https';
- }
-
- $self->{cookie_jar} = HTTP::Cookies->new (ignore_discard => 1);
-
- if ($self->{ticket}) {
- my $domain = "$self->{host}.local" unless $self->{host} =~ /\./;
- $self->{cookie_jar}->set_cookie(0, 'PVEAuthCookie', $self->{ticket},
- '/', $domain);
- }
-
- $self->{useragent} = LWP::UserAgent->new(
- cookie_jar => $self->{cookie_jar},
- protocols_allowed => [ 'http', 'https'],
- timeout => $self->{timeout},
- );
-
- $self->{useragent}->default_header('Accept-Encoding' => 'gzip'); # allow gzip
-
- return $self;
-}
-
-1;
+++ /dev/null
-package PVE::APIDaemon;
-
-use strict;
-use warnings;
-use vars qw(@ISA);
-use PVE::SafeSyslog;
-use PVE::INotify;
-use PVE::RPCEnvironment;
-
-use POSIX qw(EINTR);
-use POSIX ":sys_wait_h";
-use IO::Handle;
-use IO::Select;
-use HTTP::Daemon;
-use HTTP::Status qw(:constants);
-use CGI;
-use Data::Dumper; # fixme: remove
-use PVE::REST;
-use JSON;
-
-# This is a quite simple pre-fork server - only listens to local port
-
-@ISA = qw(HTTP::Daemon);
-
-my $documentroot = "/usr/share/pve-api/root";
-
-my $workers = {};
-
-my $max_workers = 3; # pre-forked worker processes
-my $max_requests = 500; # max requests per worker
-
-
-# some global vars
-my $child_terminate = 0;
-my $child_reload_config = 0;
-
-sub worker_finished {
- my $cpid = shift;
-
- syslog ('info', "worker $cpid finished");
-}
-
-sub finish_workers {
- local $!; local $?;
- foreach my $cpid (keys %$workers) {
- my $waitpid = waitpid ($cpid, WNOHANG);
- if (defined($waitpid) && ($waitpid == $cpid)) {
- delete ($workers->{$cpid});
- worker_finished ($cpid);
- }
- }
-}
-
-sub test_workers {
- foreach my $cpid (keys %$workers) {
- if (!kill(0, $cpid)) {
- waitpid($cpid, POSIX::WNOHANG());
- delete $workers->{$cpid};
- worker_finished ($cpid);
- }
- }
-}
-
-sub start_workers {
- my ($self, $rpcenv) = @_;
-
- my $count = 0;
- foreach my $cpid (keys %$workers) {
- $count++;
- }
-
- my $need = $max_workers - $count;
-
- return if $need <= 0;
-
- syslog ('info', "starting $need worker(s)");
-
- while ($need > 0) {
- my $pid = fork;
-
- if (!defined ($pid)) {
- syslog ('err', "can't fork worker");
- sleep (1);
- } elsif ($pid) { #parent
- $workers->{$pid} = 1;
- $0 = 'pvedaemon worker';
- syslog ('info', "worker $pid started");
- $need--;
- } else {
- $SIG{TERM} = $SIG{QUIT} = sub {
- $child_terminate = 1;
- };
-
- $SIG{USR1} = sub {
- $child_reload_config = 1;
- };
-
- eval {
- # try to init inotify
- PVE::INotify::inotify_init();
-
- $self->handle_requests($rpcenv);
- };
- syslog ('err', $@) if $@;
-
- exit (0);
- }
- }
-}
-
-sub terminate_server {
-
- syslog('info', "received terminate request");
-
- foreach my $cpid (keys %$workers) {
- kill (15, $cpid); # TERM childs
- }
-
- # nicely shutdown childs (give them max 10 seconds to shut down)
- my $previous_alarm = alarm (10);
- eval {
- local $SIG{ALRM} = sub { die "Timed Out!\n" };
-
- while ((my $pid = waitpid (-1, 0)) > 0) {
- if (defined($workers->{$pid})) {
- delete ($workers->{$pid});
- worker_finished ($pid);
- }
- }
-
- };
- alarm ($previous_alarm);
-
- foreach my $cpid (keys %$workers) {
- # KILL childs still alive!
- if (kill (0, $cpid)) {
- delete ($workers->{$cpid});
- syslog("err", "kill worker $cpid");
- kill (9, $cpid);
- }
- }
-
-}
-
-sub new {
- my $class = shift;
-
- my $self = $class->SUPER::new(@_) ||
- die "unable to create socket - $@\n";
-
- return $self;
-}
-
-sub start_server {
- my $self = shift;
-
- my $atfork = sub { close($self); };
- my $rpcenv = PVE::RPCEnvironment->init('priv', atfork => $atfork);
-
- eval {
- my $old_sig_chld = $SIG{CHLD};
- local $SIG{CHLD} = sub {
- finish_workers ();
- &$old_sig_chld(@_) if $old_sig_chld;
- };
-
- my $old_sig_term = $SIG{TERM};
- local $SIG{TERM} = sub {
- terminate_server ();
- &$old_sig_term(@_) if $old_sig_term;
- };
- local $SIG{QUIT} = sub {
- terminate_server();
- &$old_sig_term(@_) if $old_sig_term;
- };
-
- local $SIG{USR1} = 'IGNORE';
-
- local $SIG{HUP} = sub {
- syslog ("info", "received reload request");
- foreach my $cpid (keys %$workers) {
- kill (10, $cpid); # SIGUSR1 childs
- }
- };
-
- for (;;) { # forever
- $self->start_workers ($rpcenv);
- sleep (5);
- $self->test_workers ();
- }
- };
- my $err = $@;
-
- if ($err) {
- syslog ('err', "ERROR: $err");
- }
-}
-
-sub send_error {
- my ($c, $code, $msg) = @_;
-
- $c->send_response(HTTP::Response->new($code, $msg));
-}
-
-my $known_methods = {
- GET => 1,
- POST => 1,
- PUT => 1,
- DELETE => 1,
-};
-
-my $extract_params = sub {
- my ($r, $method) = @_;
-
- # NOTE: HTTP::Request::Params return undef instead of ''
- #my $parser = HTTP::Request::Params->new({req => $r});
- #my $params = $parser->params;
-
- my $post_params = {};
-
- if ($method eq 'PUT' || $method eq 'POST') {
- $post_params = CGI->new($r->content())->Vars;
- }
-
- my $query_params = CGI->new($r->url->query)->Vars;
-
- my $params = $post_params || {};
-
- foreach my $k (keys %{$query_params}) {
- $params->{$k} = $query_params->{$k};
- }
-
- return $params;
-};
-
-sub handle_requests {
- my ($self, $rpcenv) = @_;
-
- my $rcount = 0;
-
- my $sel = IO::Select->new();
- $sel->add ($self);
-
- my $timeout = 5;
- my @ready;
- while (1) {
- if (scalar (@ready = $sel->can_read($timeout))) {
-
- my $c;
- while (($c = $self->accept) || ($! == EINTR && !$child_terminate)) {
- next if !$c; # EINTR
-
- if ($child_reload_config) {
- $child_reload_config = 0;
- syslog('info', "child reload config");
- # fixme: anything to do here?
- }
-
- $c->timeout(5);
-
- # fixme: limit max request length somehow
-
- # handle requests
- while (my $r = $c->get_request) {
-
- my $method = $r->method();
-
- syslog('info', "perl method $method");
-
- if (!$known_methods->{$method}) {
- $c->send_error(HTTP_NOT_IMPLEMENTED);
- last;
- }
-
- my $uri = $r->uri->path();
- syslog('info', "start $method $uri");
-
- my ($rel_uri, $format) = PVE::REST::split_abs_uri($uri);
- if (!$format) {
-
- $c->send_error(HTTP_NOT_IMPLEMENTED);
-
- } else {
-
- my $headers = $r->headers;
-
- my $cookie = $headers->header('Cookie');
-
- my $ticket = PVE::REST::extract_auth_cookie($cookie);
-
- my $params = &$extract_params($r, $method);
-
- my $clientip = $headers->header('PVEClientIP');
-
- my $res = PVE::REST::rest_handler($clientip, $method, $uri, $rel_uri,
- $ticket, undef, $params);
-
- if ($res->{proxy}) {
-
- $res->{status} = 500;
- $c->send_error($res->{status}, "proxy not allowed");
-
- } else {
-
- PVE::REST::prepare_response_data($format, $res);
- my ($raw, $ct) = PVE::REST::format_response_data($format, $res, $uri);
-
- my $response = HTTP::Response->new($res->{status}, $res->{message});
- $response->header("Content-Type" => $ct);
- $response->header("Pragma", "no-cache");
-
- if ($res->{ticket}) {
- my $cookie = PVE::REST::create_auth_cookie($res->{ticket});
- $response->header("Set-Cookie" => $cookie);
- }
- $response->content($raw);
-
- $c->send_response($response);
- }
-
- syslog('info', "end $method $uri ($res->{status})");
- }
- }
- $rcount++;
-
- # we only handle one request per connection, because
- # we want to minimize the number of connections
-
- $c->shutdown(2);
- $c->close();
- last;
- }
-
- last if $child_terminate || !$c || ($rcount >= $max_requests);
-
- } else {
- last if $child_terminate;
-
- # timeout
- PVE::INotify::poll(); # read inotify events
- }
- }
-}
-
-1;
+++ /dev/null
-package PVE::APLInfo;
-
-use strict;
-use IO::File;
-use PVE::SafeSyslog;
-use PVE::I18N;
-use LWP::UserAgent;
-use PVE::Config;
-use POSIX qw(strftime);
-
-my $logfile = "/var/log/pveam.log";
-
-# Default list of GPG keys allowed to sign aplinfo
-#
-#pub 1024D/5CAC72FE 2004-06-24
-# Key fingerprint = 9ABD 7E02 AD24 3AD3 C2FB BCCC B0C1 CC22 5CAC 72FE
-#uid Proxmox Support Team <support@proxmox.com>
-
-my $valid_keys = {
- '9ABD7E02AD243AD3C2FBBCCCB0C1CC225CAC72FE' => 1, # fingerprint support@proxmox.com
- '25CAC72FE' => 1, # keyid support@proxmox.com
-};
-
-sub import_gpg_keys {
-
- my $keyfile = '/usr/share/doc/pve-manager/support@proxmox.com.pubkey';
-
- return system ("/usr/bin/gpg --batch --no-tty --status-fd=1 -q " .
- "--logger-fd=1 --import $keyfile >>$logfile");
-}
-
-sub logmsg {
- my ($logfd, $msg) = @_;
-
- chomp $msg;
-
- my $tstr = strftime ("%b %d %H:%M:%S", localtime);
-
- foreach my $line (split (/\n/, $msg)) {
- print $logfd "$tstr $line\n";
- }
-}
-
-sub url_get {
- my ($ua, $url, $file, $logfh) = @_;
-
- my $req = HTTP::Request->new(GET => $url);
-
- logmsg ($logfh, "start download $url");
- my $res = $ua->request($req, $file);
-
- if ($res->is_success) {
- logmsg ($logfh, "download finished: " . $res->status_line);
- return 0;
- }
-
- logmsg ($logfh, "download failed: " . $res->status_line);
-
- return 1;
-}
-
-sub update {
- my ($proxy) = @_;
-
- my $aplurl = "http://download.proxmox.com/appliances";
- my $aplsrcurl = "$aplurl/aplinfo.dat.gz";
- my $aplsigurl = "$aplurl/aplinfo.dat.asc";
-
- my $size;
- if (($size = (-s $logfile) || 0) > (1024*50)) {
- system ("mv $logfile $logfile.0");
- }
- my $logfd = IO::File->new (">>$logfile");
- logmsg ($logfd, "starting update");
-
- import_gpg_keys();
-
- my $tmp = "/tmp/pveam.tmp.$$";
- my $tmpgz = "$tmp.gz";
- my $sigfn = "$tmp.asc";
-
- # this code works for ftp and http
- # always use passive ftp
- local $ENV{FTP_PASSIVE} = 1;
- my $ua = LWP::UserAgent->new;
- $ua->agent("PVE/1.0");
-
- if ($proxy) {
- $ua->proxy(['http'], $proxy);
- } else {
- $ua->env_proxy;
- }
-
- eval {
- if (url_get ($ua, $aplsigurl, $sigfn, $logfd) != 0) {
- die "update failed - no signature\n";
- }
-
- if (url_get ($ua, $aplsrcurl, $tmpgz, $logfd) != 0) {
- die "update failed - no data\n";
- }
-
- if (system ("zcat -f $tmpgz >$tmp 2>/dev/null") != 0) {
- die "update failed: unable to unpack '$tmpgz'\n";
- }
-
- # verify signature
-
- my $cmd = "/usr/bin/gpg --verify --batch --no-tty --status-fd=1 -q " .
- "--logger-fd=1 $sigfn $tmp";
-
- open (CMD, "$cmd|") ||
- die "unable to execute '$cmd': $!\n";
-
- my $line;
- my $signer = '';
- while (defined ($line = <CMD>)) {
- chomp $line;
- logmsg ($logfd, $line);
-
- # code borrowed from SA
- next if $line !~ /^\Q[GNUPG:]\E (?:VALID|GOOD)SIG (\S{8,40})/;
- my $key = $1;
-
- # we want either a keyid (8) or a fingerprint (40)
- if (length $key > 8 && length $key < 40) {
- substr($key, 8) = '';
- }
- # use the longest match we can find
- $signer = $key if (length $key > length $signer) && $valid_keys->{$key};
- }
-
- close (CMD);
-
- die "unable to verify signature\n" if !$signer;
-
- logmsg ($logfd, "signature valid: $signer");
-
- # test syntax
- eval {
- my $fh = IO::File->new ("<$tmp") ||
- die "unable to open file '$tmp' - $!\n";
- PVE::Config::read_aplinfo ($tmp, $fh, 1);
- close ($fh);
- };
- die "update failed: $@" if $@;
-
- if (system ("mv $tmp /var/lib/pve-manager/apl-available 2>/dev/null") != 0) {
- die "update failed: unable to store data\n";
- }
-
- logmsg ($logfd, "update sucessful");
- };
-
- my $err = $@;
-
- unlink $tmp;
- unlink $tmpgz;
- unlink $sigfn;
-
- if ($err) {
- logmsg ($logfd, $err);
- close ($logfd);
-
- return 0;
- }
-
- close ($logfd);
-
- return 1;
-}
-
-sub load_data {
-
- my $filename = "/var/lib/pve-manager/apl-available";
-
- if (! -f $filename) {
- system ("cp /usr/share/doc/pve-manager/aplinfo.dat /var/lib/pve-manager/apl-available");
- }
-
- return PVE::Config::read_file ('aplinfo');
-}
-
-sub display_name {
- my ($template) = @_;
-
- my $templates = load_data ();
-
- return $template if !$templates;
-
- my $d = $templates->{'all'}->{$template};
-
- $template =~ s/\.tar\.gz$//;
- $template =~ s/_i386$//;
-
- return $template if !$d;
-
- return "$d->{package}_$d->{version}";
-}
-
-sub pkginfo {
- my ($template) = @_;
-
- my $templates = load_data ();
-
- return undef if !$templates;
-
- my $d = $templates->{'all'}->{$template};
-
- return $d;
-}
-
-sub webnews {
- my ($lang) = @_;
-
- my $templates = load_data ();
-
- my $html = '';
-
- $html .= __("<b>Welcome</b> to the Proxmox Virtual Environment!");
- $html .= "<br><br>";
- $html .= __("For more information please visit our homepage at");
- $html .= " <a href='http://www.proxmox.com' target='_blank'>www.proxmox.com</a>.";
-
- return $html if !$templates;
-
- # my $d = $templates->{'all'}->{"pve-web-news-$lang"} ||
- my $d = $templates->{all}->{'pve-web-news'};
-
- return $html if !$d;
-
- return $d->{description};
-}
-
-1;
-
+++ /dev/null
-include $(top_builddir)/common.mk
-
-SUBDIRS= API2
-
-PERLSOURCE = \
- API2.pm \
- API2Client.pm \
- APIDaemon.pm \
- REST.pm \
- APLInfo.pm
-
-BUILDDATA = pvecfg.pm
-
-pvelib_DATA = $(BUILDDATA) $(PERLSOURCE)
-
-CLEANFILES = $(BUILDDATA) *~
-
-pvelibdir = @PERL_LIBDIR@/PVE
+++ /dev/null
-package PVE::OpenVZ;
-
-use strict;
-use IO::Dir;
-use IO::File;
-use PVE::Config;
-
-my $confdir = "/etc/vz/conf";
-
-my $last_proc_vestat = {};
-
-$ENV{'PATH'} = '/sbin:/bin:/usr/sbin:/usr/bin';
-
-my $kernel_version = `uname -r`;
-
-sub vmlist {
-
- my $res = {};
-
- my $fd = IO::Dir->new ($confdir) ||
- die "unable to open dir '$confdir' - $!";
-
- while (defined(my $de = $fd->read)) {
- if ($de =~ m/^(\d+)\.conf$/) {
- my $veid = $1;
- next if !$veid; # skip VE0
- my $d = {
- status => 'stopped',
- type => 'openvz',
- };
-
- if (my $conf = PVE::Config::read_file ("$confdir/$de")) {
- $d->{name} = $conf->{hostname}->{value} || "VM$veid";
- $d->{name} =~ s/[\s]//g;
-
- $d->{cpus} = $conf->{cpus}->{value} || 1;
-
- $d->{disk} = 0;
- $d->{maxdisk} = int ($conf->{diskspace}->{bar} / 1024);
-
- $d->{mem} = 0;
- $d->{maxmem} = int (($conf->{vmguarpages}->{bar} * 4) / 1024);
- $d->{nproc} = 0;
-
- $d->{uptime} = 0;
- $d->{pctcpu} = 0;
- $d->{relcpu} = 0;
-
- if (my $ip = $conf->{ip_address}->{value}) {
- $ip =~ s/,;/ /g;
- $d->{ip} = (split(/\s+/, $ip))[0];
- } else {
- $d->{ip} = '-';
- }
- $res->{"VEID_$veid"} = $d;
- }
- }
- }
-
- my $fh;
-
- if ($fh = IO::File->new ("/proc/mounts", "r")) {
- while (defined (my $line = <$fh>)) {
- if ($line =~ m|^/var/lib/vz/private/(\d+)\s+/var/lib/vz/root/|) {
- $res->{"VEID_$1"}->{status} = 'mounted';
- }
- }
- }
-
- if ($fh = IO::File->new ("/proc/user_beancounters", "r")) {
- my $veid;
- while (defined (my $line = <$fh>)) {
- if ($line =~ m|\s*((\d+):\s*)?([a-z]+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)$|) {
- $veid = $2 if defined($2);
- next if !$veid;
- my ($name, $held, $maxheld, $bar, $lim, $failcnt) = ($3, $4, $5, $6, $7, $8);
- if (my $d = $res->{"VEID_$veid"}) {
- if ($name eq 'privvmpages') {
- $d->{mem} = int (($held *4) / 1024);
- $d->{maxmem} = int (($bar *4) / 1024);
- } elsif ($name eq 'numproc') {
- $d->{nproc} = $held;
- }
- }
- }
- }
- }
-
- if ($fh = IO::File->new ("/proc/vz/vzquota", "r")) {
- while (defined (my $line = <$fh>)) {
- if ($line =~ m|^(\d+):\s+/var/lib/vz/private/\d+$|) {
- if (my $d = $res->{"VEID_$1"}) {
- $line = <$fh>;
- if ($line =~ m|^\s*1k-blocks\s+(\d+)\s+(\d+)\s|) {
- $d->{disk} = int ($1/1024);
- $d->{maxdisk} = int ($2/1024);
- }
- }
- }
- }
- }
-
- my $cpuinfo = PVE::Utils::get_cpu_info();
- my $cpus = $cpuinfo->{cpus} || 1;
-
- # see http://wiki.openvz.org/Vestat
- if ($fh = new IO::File ("/proc/vz/vestat", "r")) {
- while (defined (my $line = <$fh>)) {
- if ($line =~ m/^\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+/) {
- my $veid = $1;
- my $user = $2;
- my $nice = $3;
- my $system = $4;
- my $ut = $5;
- my $sum = $8*$cpus; # uptime in jiffies * cpus = available jiffies
- my $used = $9; # used time in jiffies
-
- # HZ is 250 in our kernel 2.6.24 kernel
- # but HZ is 1000 in our kernel 2.6.18 kernel
- my $hz = 250;
- $hz = 1000 if $kernel_version && $kernel_version =~ m/^2.6.18/;
- my $uptime = int ($ut / $hz); # HZ is 250 in our kernel
-
- my $d = $res->{"VEID_$veid"};
- next if !$d;
-
- $d->{status} = 'running';
- $d->{uptime} = $uptime;
-
- if (!defined ($last_proc_vestat->{$veid}) ||
- ($last_proc_vestat->{$veid}->{sum} > $sum)) {
- $last_proc_vestat->{$veid} = { used => 0, sum => 0, pctcpu => 0, relcpu => 0};
- }
-
- my $diff = $sum - $last_proc_vestat->{$veid}->{sum};
-
- if ($diff > 1000) { # don't update too often
- my $useddiff = $used - $last_proc_vestat->{$veid}->{used};
- my $pctcpu = int ($useddiff*100/$diff);
- $last_proc_vestat->{$veid}->{sum} = $sum;
- $last_proc_vestat->{$veid}->{used} = $used;
- $last_proc_vestat->{$veid}->{pctcpu} = $d->{pctcpu} = $pctcpu;
-
- # fixme: openvz --cpus does not work currently
- my $relcpu = $pctcpu;
- $last_proc_vestat->{$veid}->{relcpu} = $d->{relcpu} = $relcpu;
-
- } else {
- $d->{pctcpu} = $last_proc_vestat->{$veid}->{pctcpu};
- $d->{relcpu} = $last_proc_vestat->{$veid}->{relcpu};
- }
- }
- }
- }
-
- return $res;
-
-}
+++ /dev/null
-package PVE::REST;
-
-use warnings;
-use strict;
-use Digest::SHA1 qw(sha1_base64);
-use PVE::Cluster;
-use PVE::SafeSyslog;
-use PVE::Tools;
-use PVE::API2;
-use Apache2::Const;
-use CGI;
-use mod_perl2;
-use JSON;
-use Digest::SHA;
-use LWP::UserAgent;
-use HTTP::Request::Common;
-use HTTP::Status qw(:constants :is status_message);
-use HTML::Entities;
-use PVE::JSONSchema;
-use PVE::AccessControl;
-use PVE::RPCEnvironment;
-
-use Data::Dumper; # fixme: remove
-
-my $cookie_name = 'PVEAuthCookie';
-
-my $baseuri = "/api2";
-
-# http://perl.apache.org/docs/2.0/api/Apache2/SubProcess.html
-
-sub extract_auth_cookie {
- my ($cookie) = @_;
-
- return undef if !$cookie;
-
- return ($cookie =~ /(?:^|\s)$cookie_name=([^;]*)/)[0];
-}
-
-sub create_auth_cookie {
- my ($ticket) = @_;
-
- return "${cookie_name}=$ticket; path=/; secure;";
-}
-
-sub format_response_data {
- my($format, $res, $uri) = @_;
-
- my $data = $res->{data};
- my $info = $res->{info};
-
- my ($ct, $raw);
-
- if ($format eq 'json') {
- $ct = 'application/json';
- $raw = to_json($data, {utf8 => 1, allow_nonref => 1});
- } elsif ($format eq 'html') {
- $ct = 'text/html';
- $raw = "<html><body>";
- if (!is_success($res->{status})) {
- my $msg = $res->{message} || '';
- $raw .= "<h1>ERROR $res->{status} $msg</h1>";
- }
- my $lnk = PVE::JSONSchema::method_get_child_link($info);
- if ($lnk && $data && $data->{data} && is_success($res->{status})) {
-
- my $href = $lnk->{href};
- if ($href =~ m/^\{(\S+)\}$/) {
- my $prop = $1;
- $uri =~ s/\/+$//; # remove trailing slash
- foreach my $elem (sort {$a->{$prop} cmp $b->{$prop}} @{$data->{data}}) {
- next if !ref($elem);
-
- if (defined(my $value = $elem->{$prop})) {
- if ($value ne '') {
- if (scalar(keys %$elem) > 1) {
- my $tv = to_json($elem, {allow_nonref => 1, canonical => 1});
- $raw .= "<a href='$uri/$value'>$value</a> <pre>$tv</pre><br>";
- } else {
- $raw .= "<a href='$uri/$value'>$value</a><br>";
- }
- }
- }
- }
- }
- } else {
- $raw .= "<pre>";
- $raw .= encode_entities(to_json($data, {utf8 => 1, allow_nonref => 1, pretty => 1}));
- $raw .= "</pre>";
- }
- $raw .= "</body></html>";
-
- } elsif ($format eq 'png') {
- $ct = 'image/png';
-
- # fixme: better to revove that whole png thing ?
-
- my $filename;
- $raw = '';
-
- if ($data && ref($data) && ref($data->{data}) &&
- $data->{data}->{filename}) {
- $filename = $data->{data}->{filename};
- $raw = PVE::Tools::file_get_contents($filename);
- }
-
- } elsif ($format eq 'extjs') {
- $ct = 'application/json';
- $raw = to_json($data, {utf8 => 1, allow_nonref => 1});
- } elsif ($format eq 'htmljs') {
- # we use this for extjs file upload forms
- $ct = 'text/html';
- $raw = encode_entities(to_json($data, {utf8 => 1, allow_nonref => 1}));
- } else {
- $ct = 'text/plain';
- $raw = to_json($data, {utf8 => 1, allow_nonref => 1, pretty => 1});
- }
-
- return wantarray ? ($raw, $ct) : $raw;
-}
-
-sub prepare_response_data {
- my ($format, $res) = @_;
-
- my $success = 1;
- my $new = {
- data => $res->{data},
- };
- if (scalar(keys %{$res->{errors}})) {
- $success = 0;
- $new->{errors} = $res->{errors};
- }
-
- if ($format eq 'extjs' || $format eq 'htmljs') {
- # HACK: extjs wants 'success' property instead of useful HTTP status codes
- if (is_error($res->{status})) {
- $success = 0;
- $new->{message} = $res->{message} || status_message($res->{status});
- $new->{status} = $res->{status} || HTTP_OK;
- $res->{message} = undef;
- $res->{status} = HTTP_OK;
- }
- $new->{success} = $success;
- }
-
- if ($success && $res->{total}) {
- $new->{total} = $res->{total};
- }
-
- $res->{data} = $new;
-}
-
-sub create_http_request {
- my ($uri, $method, $params) = @_;
-
- # NOTE: HTTP::Request::Common::PUT is crap - so we use our own code
- # borrowed from HTTP::Request::Common::POST
-
- if ($method eq 'POST' || $method eq 'PUT') {
-
- my $req = HTTP::Request->new($method => $uri);
- $req->header('Content-Type' => 'application/x-www-form-urlencoded');
-
- # We use a temporary URI object to format
- # the application/x-www-form-urlencoded content.
- my $url = URI->new('http:');
- $url->query_form(%$params);
- my $content = $url->query;
- if (defined($content)) {
- $req->header('Content-Length' => length($content));
- $req->content($content);
- } else {
- $req->header('Content-Length' => 0);
- }
-
- return $req;
- }
-
- die "unknown method '$method'";
-}
-
-sub proxy_handler {
- my($r, $clientip, $host, $method, $abs_uri, $ticket, $token, $params) = @_;
-
- syslog('info', "proxy start $method $host:$abs_uri");
-
- my $ua = LWP::UserAgent->new(
- protocols_allowed => [ 'http', 'https' ],
- timeout => 30,
- );
-
- $ua->default_header('cookie' => "${cookie_name}=$ticket") if $ticket;
- $ua->default_header('CSRFPreventionToken' => $token) if $token;
- $ua->default_header('PVEDisableProxy' => 'true');
- $ua->default_header('PVEClientIP' => $clientip);
-
- my $uri = URI->new();
-
- if ($host eq 'localhost') {
- $uri->scheme('http');
- $uri->host('localhost');
- $uri->port(85);
- } else {
- $uri->scheme('https');
- $uri->host($host);
- $uri->port(8006);
- }
-
- $uri->path($abs_uri);
-
- my $response;
- if ($method eq 'GET') {
- $uri->query_form($params);
- $response = $ua->request(HTTP::Request::Common::GET($uri));
- } elsif ($method eq 'POST' || $method eq 'PUT') {
- $response = $ua->request(create_http_request($uri, $method, $params));
- } elsif ($method eq 'DELETE') {
- $response = $ua->request(HTTP::Request::Common::DELETE($uri));
- } else {
- my $code = HTTP_NOT_IMPLEMENTED;
- $r->status_line("$code proxy method '$method' not implemented");
- return $code;
- }
-
-
- if (my $cookie = $response->header("Set-Cookie")) {
- $r->err_headers_out()->add("Set-Cookie" => $cookie);
- }
-
- my $ct = $response->header('Content-Type');
-
- my $code = $response->code;
- $r->status($code);
-
- if (my $message = $response->message) {
- $r->status_line("$code $message");
- }
-
- $r->content_type($ct) if $ct;
- my $raw = $response->decoded_content;
-
- # note: do not use err_headers_out(), because mod_deflate has a bug,
- # resulting in dup length (for exampe 'content-length: 89, 75')
- $r->headers_out()->add('Content-Length' , length($raw));
- $r->print($raw);
-
- syslog('info', "proxy end $method $host:$abs_uri ($code)");
-
- return OK;
-}
-
-my $check_permissions = sub {
- my ($rpcenv, $perm, $username, $param) = @_;
-
- return 1 if !$username && $perm->{user} eq 'world';
-
- return 1 if $username eq 'root@pam';
-
- die "permission check failed (user != root)\n" if !$perm;
-
- return 1 if $perm->{user} && $perm->{user} eq 'all';
-
- return 1 if $perm->{user} && $perm->{user} eq 'arg' &&
- $username eq $param->{username};
-
- if ($perm->{path} && $perm->{privs}) {
- my $path = PVE::Tools::template_replace($perm->{path}, $param);
- if (!$rpcenv->check($username, $path, $perm->{privs})) {
- my $privstr = join(',', @{$perm->{privs}});
- die "Permission check failed ($path, $privstr)\n";
- }
- return 1;
- }
-
- die "Permission check failed\n";
-};
-
-sub rest_handler {
- my ($clientip, $method, $abs_uri, $rel_uri, $ticket, $token, $params) = @_;
-
- my $rpcenv = PVE::RPCEnvironment::get();
-
- eval { $rpcenv->init_request(); };
- if (my $err = $@) {
- syslog('err', $err);
- return { status => HTTP_INTERNAL_SERVER_ERROR, message => $err };
- }
-
- my $euid = $>;
-
- my $require_auth = 1;
-
- # explicitly allow some calls without auth
- if (($rel_uri eq '/access/domains' && $method eq 'GET') ||
- ($rel_uri eq '/access/ticket' && $method eq 'POST')) {
- $require_auth = 0;
- }
-
- my ($username, $age);
-
- if ($require_auth) {
-
- eval {
- die "No ticket\n" if !$ticket;
-
- ($username, $age) = PVE::AccessControl::verify_ticket($ticket);
-
- PVE::AccessControl::verify_csrf_prevention_token($username, $token)
- if ($euid != 0) && ($method ne 'GET');
- };
- if (my $err = $@) {
- return {
- status => HTTP_UNAUTHORIZED,
- message => $err,
- };
- }
- }
-
- my $uri_param = {};
- my ($handler, $info) = PVE::API2->find_handler($method, $rel_uri, $uri_param);
- if (!$handler || !$info) {
- return {
- status => HTTP_NOT_IMPLEMENTED,
- message => "Method '$method $abs_uri' not implemented",
- };
- }
-
- delete $params->{_dc}; # remove disable cache parameter
-
- foreach my $p (keys %{$params}) {
- if (defined($uri_param->{$p})) {
- return {
- status => HTTP_BAD_REQUEST,
- message => "Parameter verification failed - duplicate parameter '$p'",
- };
- }
- $uri_param->{$p} = $params->{$p};
- }
-
- # check access permissions
- eval { &$check_permissions($rpcenv, $info->{permissions}, $username, $uri_param); };
- if (my $err = $@) {
- return {
- status => HTTP_FORBIDDEN,
- message => $err,
- };
- }
-
- if ($info->{proxyto}) {
- my $remip;
- eval {
- my $pn = $info->{proxyto};
- my $node = $uri_param->{$pn};
- die "proxy parameter '$pn' does not exists" if !$node;
-
- if ($node ne 'localhost' &&
- $node ne PVE::INotify::nodename()) {
- $remip = PVE::Cluster::remote_node_ip($node);
- }
- };
- if (my $err = $@) {
- return {
- status => HTTP_INTERNAL_SERVER_ERROR,
- message => $err,
- };
- }
- if ($remip) {
- return { proxy => $remip };
- }
- }
-
- # fixme: not sure if we should do that here, because we can't proxy those
- # methods to other hosts?
- return { proxy => 'localhost' } if $info->{protected} && ($euid != 0);
-
- # set environment variables
- $rpcenv->set_language('C'); # fixme:
- $rpcenv->set_user($username);
- $rpcenv->set_client_ip($clientip);
- $rpcenv->set_result_count(undef);
-
- my $resp = {
- info => $info, # useful to format output
- status => HTTP_OK,
- };
-
- eval {
- $resp->{data} = $handler->handle($info, $uri_param);
-
- if (my $count = $rpcenv->get_result_count()) {
- $resp->{total} = $count;
- }
- };
- my $err = $@;
- if ($err) {
- if (ref($err) eq "PVE::Exception") {
- $resp->{status} = $err->{code} || HTTP_INTERNAL_SERVER_ERROR;
- $resp->{message} = $err->{msg} || $@;
- $resp->{errors} = $err->{errors} if $err->{errors};
- } else {
- $resp->{status} = HTTP_INTERNAL_SERVER_ERROR;
- $resp->{message} = $@;
- }
- }
-
- $rpcenv->set_user(undef);
-
- if ($rel_uri eq '/access/ticket') {
- $resp->{ticket} = $resp->{data}->{ticket};
- }
-
- # fixme: update ticket if too old
- # $resp->{ticket} = update_ticket($ticket);
-
- return $resp;
-}
-
-sub split_abs_uri {
- my ($abs_uri) = @_;
-
- my ($format, $rel_uri) = $abs_uri =~ m/^\Q$baseuri\E\/+(html|json|extjs|png|htmljs)(\/.*)?$/;
- $rel_uri = '/' if !$rel_uri;
-
- return wantarray ? ($rel_uri, $format) : $rel_uri;
-}
-
-my $known_methods = {
- GET => 1,
- POST => 1,
- PUT => 1,
- DELETE => 1,
-};
-
-sub handler {
- my($r) = @_;
-
- #syslog('info', "perl handler called");
-
- my $method = $r->method;
- my $clientip = $r->connection->remote_ip();
-
- return HTTP_NOT_IMPLEMENTED
- if !$known_methods->{$method};
-
- my $cgi = CGI->new ($r);
-
- my $params = $cgi->Vars();
-
- my $cookie = $r->headers_in->{Cookie};
- my $token = $r->headers_in->{CSRFPreventionToken};
-
- my $ticket = extract_auth_cookie($cookie);
-
- $r->no_cache (1);
-
- my $abs_uri = $r->uri;
- my ($rel_uri, $format) = split_abs_uri($abs_uri);
- return HTTP_NOT_IMPLEMENTED if !$format;
-
- my $res = rest_handler($clientip, $method, $abs_uri, $rel_uri,
- $ticket, $token, $params);
-
- if ($res->{proxy}) {
- if (($res->{proxy} ne 'localhost') && $r->headers_in->{'PVEDisableProxy'}) {
- my $code = FORBIDDEN;
- $r->status($code);
- $r->status_line("$code proxy loop detected - aborted ");
- return $res->{status};
- }
- return proxy_handler($r, $clientip, $res->{proxy}, $method,
- $abs_uri, $ticket, $token, $params);
- }
-
- prepare_response_data($format, $res);
-
- if ($res->{ticket}) {
- my $cookie = create_auth_cookie($res->{ticket});
- $r->err_headers_out()->add("Set-Cookie" => $cookie);
- }
-
- $r->status($res->{status} || HTTP_OK);
-
- if ($res->{message}) {
- my ($firstline) = $res->{message} =~ m/\A(.*)$/m;
- $r->status_line("$res->{status} $firstline");
- }
-
- my ($raw, $ct) = format_response_data($format, $res, $abs_uri);
- $r->content_type ($ct);
-
- # note: do not use err_headers_out(), because mod_deflate has a bug,
- # resulting in dup length (for exampe 'content-length: 89, 75')
- $r->headers_out()->add('Content-Length', length($raw));
- $r->print($raw);
-
- #syslog('info', "perl handler end $res->{status}");
-
- return OK;
-}
-
-1;
+++ /dev/null
-package PVE::pvecfg;
-
-use strict;
-use vars qw(@ISA);
-use Carp;
-
-sub package {
- return '@PACKAGE@';
-}
-
-sub version {
- return '@VERSION@';
-}
-
-sub repoid {
- return '@REPOID@';
-}
-
-1;
\ No newline at end of file
+++ /dev/null
-#! /bin/sh
-# Common stub for a few missing GNU programs while installing.
-
-scriptversion=2005-06-08.21
-
-# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005
-# Free Software Foundation, Inc.
-# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.
-
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2, or (at your option)
-# any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301, USA.
-
-# As a special exception to the GNU General Public License, if you
-# distribute this file as part of a program that contains a
-# configuration script generated by Autoconf, you may include it under
-# the same distribution terms that you use for the rest of that program.
-
-if test $# -eq 0; then
- echo 1>&2 "Try \`$0 --help' for more information"
- exit 1
-fi
-
-run=:
-
-# In the cases where this matters, `missing' is being run in the
-# srcdir already.
-if test -f configure.ac; then
- configure_ac=configure.ac
-else
- configure_ac=configure.in
-fi
-
-msg="missing on your system"
-
-case "$1" in
---run)
- # Try to run requested program, and just exit if it succeeds.
- run=
- shift
- "$@" && exit 0
- # Exit code 63 means version mismatch. This often happens
- # when the user try to use an ancient version of a tool on
- # a file that requires a minimum version. In this case we
- # we should proceed has if the program had been absent, or
- # if --run hadn't been passed.
- if test $? = 63; then
- run=:
- msg="probably too old"
- fi
- ;;
-
- -h|--h|--he|--hel|--help)
- echo "\
-$0 [OPTION]... PROGRAM [ARGUMENT]...
-
-Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
-error status if there is no known handling for PROGRAM.
-
-Options:
- -h, --help display this help and exit
- -v, --version output version information and exit
- --run try to run the given command, and emulate it if it fails
-
-Supported PROGRAM values:
- aclocal touch file \`aclocal.m4'
- autoconf touch file \`configure'
- autoheader touch file \`config.h.in'
- automake touch all \`Makefile.in' files
- bison create \`y.tab.[ch]', if possible, from existing .[ch]
- flex create \`lex.yy.c', if possible, from existing .c
- help2man touch the output file
- lex create \`lex.yy.c', if possible, from existing .c
- makeinfo touch the output file
- tar try tar, gnutar, gtar, then tar without non-portable flags
- yacc create \`y.tab.[ch]', if possible, from existing .[ch]
-
-Send bug reports to <bug-automake@gnu.org>."
- exit $?
- ;;
-
- -v|--v|--ve|--ver|--vers|--versi|--versio|--version)
- echo "missing $scriptversion (GNU Automake)"
- exit $?
- ;;
-
- -*)
- echo 1>&2 "$0: Unknown \`$1' option"
- echo 1>&2 "Try \`$0 --help' for more information"
- exit 1
- ;;
-
-esac
-
-# Now exit if we have it, but it failed. Also exit now if we
-# don't have it and --version was passed (most likely to detect
-# the program).
-case "$1" in
- lex|yacc)
- # Not GNU programs, they don't have --version.
- ;;
-
- tar)
- if test -n "$run"; then
- echo 1>&2 "ERROR: \`tar' requires --run"
- exit 1
- elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
- exit 1
- fi
- ;;
-
- *)
- if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
- # We have it, but it failed.
- exit 1
- elif test "x$2" = "x--version" || test "x$2" = "x--help"; then
- # Could not run --version or --help. This is probably someone
- # running `$TOOL --version' or `$TOOL --help' to check whether
- # $TOOL exists and not knowing $TOOL uses missing.
- exit 1
- fi
- ;;
-esac
-
-# If it does not exist, or fails to run (possibly an outdated version),
-# try to emulate it.
-case "$1" in
- aclocal*)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`acinclude.m4' or \`${configure_ac}'. You might want
- to install the \`Automake' and \`Perl' packages. Grab them from
- any GNU archive site."
- touch aclocal.m4
- ;;
-
- autoconf)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`${configure_ac}'. You might want to install the
- \`Autoconf' and \`GNU m4' packages. Grab them from any GNU
- archive site."
- touch configure
- ;;
-
- autoheader)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`acconfig.h' or \`${configure_ac}'. You might want
- to install the \`Autoconf' and \`GNU m4' packages. Grab them
- from any GNU archive site."
- files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
- test -z "$files" && files="config.h"
- touch_files=
- for f in $files; do
- case "$f" in
- *:*) touch_files="$touch_files "`echo "$f" |
- sed -e 's/^[^:]*://' -e 's/:.*//'`;;
- *) touch_files="$touch_files $f.in";;
- esac
- done
- touch $touch_files
- ;;
-
- automake*)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
- You might want to install the \`Automake' and \`Perl' packages.
- Grab them from any GNU archive site."
- find . -type f -name Makefile.am -print |
- sed 's/\.am$/.in/' |
- while read f; do touch "$f"; done
- ;;
-
- autom4te)
- echo 1>&2 "\
-WARNING: \`$1' is needed, but is $msg.
- You might have modified some files without having the
- proper tools for further handling them.
- You can get \`$1' as part of \`Autoconf' from any GNU
- archive site."
-
- file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
- test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
- if test -f "$file"; then
- touch $file
- else
- test -z "$file" || exec >$file
- echo "#! /bin/sh"
- echo "# Created by GNU Automake missing as a replacement of"
- echo "# $ $@"
- echo "exit 0"
- chmod +x $file
- exit 1
- fi
- ;;
-
- bison|yacc)
- echo 1>&2 "\
-WARNING: \`$1' $msg. You should only need it if
- you modified a \`.y' file. You may need the \`Bison' package
- in order for those modifications to take effect. You can get
- \`Bison' from any GNU archive site."
- rm -f y.tab.c y.tab.h
- if [ $# -ne 1 ]; then
- eval LASTARG="\${$#}"
- case "$LASTARG" in
- *.y)
- SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
- if [ -f "$SRCFILE" ]; then
- cp "$SRCFILE" y.tab.c
- fi
- SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
- if [ -f "$SRCFILE" ]; then
- cp "$SRCFILE" y.tab.h
- fi
- ;;
- esac
- fi
- if [ ! -f y.tab.h ]; then
- echo >y.tab.h
- fi
- if [ ! -f y.tab.c ]; then
- echo 'main() { return 0; }' >y.tab.c
- fi
- ;;
-
- lex|flex)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a \`.l' file. You may need the \`Flex' package
- in order for those modifications to take effect. You can get
- \`Flex' from any GNU archive site."
- rm -f lex.yy.c
- if [ $# -ne 1 ]; then
- eval LASTARG="\${$#}"
- case "$LASTARG" in
- *.l)
- SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
- if [ -f "$SRCFILE" ]; then
- cp "$SRCFILE" lex.yy.c
- fi
- ;;
- esac
- fi
- if [ ! -f lex.yy.c ]; then
- echo 'main() { return 0; }' >lex.yy.c
- fi
- ;;
-
- help2man)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a dependency of a manual page. You may need the
- \`Help2man' package in order for those modifications to take
- effect. You can get \`Help2man' from any GNU archive site."
-
- file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
- if test -z "$file"; then
- file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
- fi
- if [ -f "$file" ]; then
- touch $file
- else
- test -z "$file" || exec >$file
- echo ".ab help2man is required to generate this page"
- exit 1
- fi
- ;;
-
- makeinfo)
- echo 1>&2 "\
-WARNING: \`$1' is $msg. You should only need it if
- you modified a \`.texi' or \`.texinfo' file, or any other file
- indirectly affecting the aspect of the manual. The spurious
- call might also be the consequence of using a buggy \`make' (AIX,
- DU, IRIX). You might want to install the \`Texinfo' package or
- the \`GNU make' package. Grab either from any GNU archive site."
- # The file to touch is that specified with -o ...
- file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
- if test -z "$file"; then
- # ... or it is the one specified with @setfilename ...
- infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
- file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $infile`
- # ... or it is derived from the source name (dir/f.texi becomes f.info)
- test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info
- fi
- # If the file does not exist, the user really needs makeinfo;
- # let's fail without touching anything.
- test -f $file || exit 1
- touch $file
- ;;
-
- tar)
- shift
-
- # We have already tried tar in the generic part.
- # Look for gnutar/gtar before invocation to avoid ugly error
- # messages.
- if (gnutar --version > /dev/null 2>&1); then
- gnutar "$@" && exit 0
- fi
- if (gtar --version > /dev/null 2>&1); then
- gtar "$@" && exit 0
- fi
- firstarg="$1"
- if shift; then
- case "$firstarg" in
- *o*)
- firstarg=`echo "$firstarg" | sed s/o//`
- tar "$firstarg" "$@" && exit 0
- ;;
- esac
- case "$firstarg" in
- *h*)
- firstarg=`echo "$firstarg" | sed s/h//`
- tar "$firstarg" "$@" && exit 0
- ;;
- esac
- fi
-
- echo 1>&2 "\
-WARNING: I can't seem to be able to run \`tar' with the given arguments.
- You may want to install GNU tar or Free paxutils, or check the
- command line arguments."
- exit 1
- ;;
-
- *)
- echo 1>&2 "\
-WARNING: \`$1' is needed, and is $msg.
- You might have modified some files without having the
- proper tools for further handling them. Check the \`README' file,
- it often tells you about the needed prerequisites for installing
- this package. You may also peek at any GNU archive site, in case
- some other package would contain this missing \`$1' program."
- exit 1
- ;;
-esac
-
-exit 0
-
-# Local variables:
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
+++ /dev/null
-#! /bin/sh
-# mkinstalldirs --- make directory hierarchy
-
-scriptversion=2005-06-29.22
-
-# Original author: Noah Friedman <friedman@prep.ai.mit.edu>
-# Created: 1993-05-16
-# Public domain.
-#
-# This file is maintained in Automake, please report
-# bugs to <bug-automake@gnu.org> or send patches to
-# <automake-patches@gnu.org>.
-
-errstatus=0
-dirmode=
-
-usage="\
-Usage: mkinstalldirs [-h] [--help] [--version] [-m MODE] DIR ...
-
-Create each directory DIR (with mode MODE, if specified), including all
-leading file name components.
-
-Report bugs to <bug-automake@gnu.org>."
-
-# process command line arguments
-while test $# -gt 0 ; do
- case $1 in
- -h | --help | --h*) # -h for help
- echo "$usage"
- exit $?
- ;;
- -m) # -m PERM arg
- shift
- test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
- dirmode=$1
- shift
- ;;
- --version)
- echo "$0 $scriptversion"
- exit $?
- ;;
- --) # stop option processing
- shift
- break
- ;;
- -*) # unknown option
- echo "$usage" 1>&2
- exit 1
- ;;
- *) # first non-opt arg
- break
- ;;
- esac
-done
-
-for file
-do
- if test -d "$file"; then
- shift
- else
- break
- fi
-done
-
-case $# in
- 0) exit 0 ;;
-esac
-
-# Solaris 8's mkdir -p isn't thread-safe. If you mkdir -p a/b and
-# mkdir -p a/c at the same time, both will detect that a is missing,
-# one will create a, then the other will try to create a and die with
-# a "File exists" error. This is a problem when calling mkinstalldirs
-# from a parallel make. We use --version in the probe to restrict
-# ourselves to GNU mkdir, which is thread-safe.
-case $dirmode in
- '')
- if mkdir -p --version . >/dev/null 2>&1 && test ! -d ./--version; then
- echo "mkdir -p -- $*"
- exec mkdir -p -- "$@"
- else
- # On NextStep and OpenStep, the `mkdir' command does not
- # recognize any option. It will interpret all options as
- # directories to create, and then abort because `.' already
- # exists.
- test -d ./-p && rmdir ./-p
- test -d ./--version && rmdir ./--version
- fi
- ;;
- *)
- if mkdir -m "$dirmode" -p --version . >/dev/null 2>&1 &&
- test ! -d ./--version; then
- echo "mkdir -m $dirmode -p -- $*"
- exec mkdir -m "$dirmode" -p -- "$@"
- else
- # Clean up after NextStep and OpenStep mkdir.
- for d in ./-m ./-p ./--version "./$dirmode";
- do
- test -d $d && rmdir $d
- done
- fi
- ;;
-esac
-
-for file
-do
- case $file in
- /*) pathcomp=/ ;;
- *) pathcomp= ;;
- esac
- oIFS=$IFS
- IFS=/
- set fnord $file
- shift
- IFS=$oIFS
-
- for d
- do
- test "x$d" = x && continue
-
- pathcomp=$pathcomp$d
- case $pathcomp in
- -*) pathcomp=./$pathcomp ;;
- esac
-
- if test ! -d "$pathcomp"; then
- echo "mkdir $pathcomp"
-
- mkdir "$pathcomp" || lasterr=$?
-
- if test ! -d "$pathcomp"; then
- errstatus=$lasterr
- else
- if test ! -z "$dirmode"; then
- echo "chmod $dirmode $pathcomp"
- lasterr=
- chmod "$dirmode" "$pathcomp" || lasterr=$?
-
- if test ! -z "$lasterr"; then
- errstatus=$lasterr
- fi
- fi
- fi
- fi
-
- pathcomp=$pathcomp/
- done
-done
-
-exit $errstatus
-
-# Local Variables:
-# mode: shell-script
-# sh-indentation: 2
-# eval: (add-hook 'write-file-hooks 'time-stamp)
-# time-stamp-start: "scriptversion="
-# time-stamp-format: "%:y-%02m-%02d.%02H"
-# time-stamp-end: "$"
-# End:
--- /dev/null
+SUBDIRS = templates images ext4 css manager
+
+all: ${SUBDIRS}
+
+%:
+ set -e && for i in ${SUBDIRS}; do ${MAKE} -C $$i $@; done
+
+++ /dev/null
-include $(top_builddir)/common.mk
-
-SUBDIRS = templates images ext4 css manager
-
-install-data-hook:
- chown -R www-data:www-data ${DESTDIR}${WWW_BASEDIR}
-
-CLEANFILES=*~
-
--- /dev/null
+include ../../defines.mk
+
+all:
+
+.PHONY: install
+install: ext-pve.css
+ install -d ${WWWCSSDIR}
+ install -m 0644 -o www-data -g www-data $< ${WWWCSSDIR}
+
+.PHONY: distclean
+distclean: clean
+
+.PHONY: clean
+clean:
+ rm -rf *~
+++ /dev/null
-include $(top_builddir)/common.mk
-
-
-css_DATA = \
- ext-pve.css
-
-cssdir = ${WWW_CSSDIR}
-
-install-data-hook:
- chown -R www-data:www-data ${DESTDIR}/${cssdir}
-
-CLEANFILES= *~
-
--- /dev/null
+include ../../defines.mk
+
+GNOME_IMAGES = \
+ display.png \
+ keyboard.png \
+ cdrom.png \
+ network.png \
+ drive-harddisk.png \
+ network-server.png \
+ computer.png
+
+IMAGES = ${GNOME_IMAGES} \
+ computer-on.png \
+ memory.png \
+ processor.png \
+ proxmox_logo.png \
+ blank.gif
+
+.PHONY: install
+install: ${IMAGES}
+ install -d ${WWWIMAGEDIR}
+ install -m 0644 -o www-data -g www-data ${IMAGES} ${WWWIMAGEDIR}
+
+.PHONY: distclean
+distclean: clean
+
+.PHONY: clean
+clean:
+ rm -rf *~
+++ /dev/null
-include $(top_builddir)/common.mk
-
-GNOME_IMAGES = \
- display.png \
- keyboard.png \
- cdrom.png \
- network.png \
- drive-harddisk.png \
- network-server.png \
- computer.png
-
-images_DATA = ${GNOME_IMAGES} \
- computer-on.png \
- memory.png \
- processor.png \
- proxmox_logo.png \
- blank.gif
-
-imagesdir = ${WWW_IMAGEDIR}
-
-install-data-hook:
- chown -R www-data:www-data ${DESTDIR}/${imagesdir}
-
-CLEANFILES=*~
-
--- /dev/null
+include ../../defines.mk
+
+JSSRC= \
+ Utils.js \
+ Parser.js \
+ StateProvider.js \
+ VNCConsole.js \
+ data/TimezoneStore.js \
+ data/reader/JsonObject.js \
+ data/PVEProxy.js \
+ data/UpdateQueue.js \
+ data/UpdateStore.js \
+ data/DiffStore.js \
+ data/ObjectStore.js \
+ data/ResourceStore.js \
+ form/Checkbox.js \
+ form/TextField.js \
+ form/RRDTypeSelector.js \
+ form/ComboGrid.js \
+ form/KVComboBox.js \
+ form/Boolean.js \
+ form/NetworkCardSelector.js \
+ form/DiskFormatSelector.js \
+ form/BusTypeSelector.js \
+ form/ControllerSelector.js \
+ form/RealmComboBox.js \
+ form/BondModeSelector.js \
+ form/ViewSelector.js \
+ form/NodeSelector.js \
+ form/FileSelector.js \
+ form/StorageSelector.js \
+ form/BridgeSelector.js \
+ form/CPUModelSelector.js \
+ form/VNCKeyboardSelector.js \
+ form/DisplaySelector.js \
+ form/CacheTypeSelector.js \
+ form/ContentTypeSelector.js \
+ dc/Tasks.js \
+ dc/Log.js \
+ panel/StatusPanel.js \
+ panel/RRDView.js \
+ panel/InputPanel.js \
+ window/Edit.js \
+ window/LoginWindow.js \
+ window/TaskViewer.js \
+ window/Wizard.js \
+ grid/SelectFeature.js \
+ grid/ObjectGrid.js \
+ grid/ResourceGrid.js \
+ tree/ResourceTree.js \
+ panel/ConfigPanel.js \
+ node/DNSEdit.js \
+ node/DNSView.js \
+ node/TimeView.js \
+ node/TimeEdit.js \
+ node/StatusView.js \
+ node/Summary.js \
+ node/ServiceView.js \
+ node/NetworkEdit.js \
+ node/NetworkView.js \
+ node/Syslog.js \
+ node/Tasks.js \
+ node/Config.js \
+ qemu/StatusView.js \
+ qemu/Summary.js \
+ qemu/OSTypeEdit.js \
+ qemu/ProcessorEdit.js \
+ qemu/BootOrderEdit.js \
+ qemu/MemoryEdit.js \
+ qemu/NetworkEdit.js \
+ qemu/CDEdit.js \
+ qemu/HDEdit.js \
+ qemu/DisplayEdit.js \
+ qemu/NotesEdit.js \
+ qemu/NotesView.js \
+ qemu/KeyboardEdit.js \
+ qemu/HardwareView.js \
+ qemu/Options.js \
+ qemu/Config.js \
+ qemu/CreateWizard.js \
+ openvz/CreateWizard.js \
+ storage/ContentView.js \
+ storage/StatusView.js \
+ storage/Summary.js \
+ storage/Browser.js \
+ storage/DirEdit.js \
+ storage/NFSEdit.js \
+ storage/IScsiEdit.js \
+ storage/LVMEdit.js \
+ dc/OptionView.js \
+ dc/StorageView.js \
+ dc/UserEdit.js \
+ dc/UserView.js \
+ dc/GroupView.js \
+ dc/GroupEdit.js \
+ dc/RoleView.js \
+ dc/ACLView.js \
+ dc/AuthView.js \
+ dc/AuthEdit.js \
+ dc/Config.js \
+ Workspace.js
+
+lint: ${JSSRC}
+ jslint ${JSSRC}
+
+pvemanagerlib.js: ${JSSRC}
+ cat ${JSSRC} >$@.tmp
+ mv $@.tmp $@
+
+all: pvemanagerlib.js
+
+.PHONY: install
+install: pvemanagerlib.js startup.pl index.pl
+ install -d ${WWWBASEDIR}
+ install -m 0755 -o www-data -g www-data startup.pl ${WWWBASEDIR}
+ install -d ${WWWROOTDIR}
+ install -m 0755 -o www-data -g www-data index.pl ${WWWROOTDIR}
+ install -d ${WWWEXT4DIR}
+ install -m 0644 -o www-data -g www-data pvemanagerlib.js ${WWWEXT4DIR}
+
+.PHONY: distclean
+distclean: clean
+
+.PHONY: clean
+clean:
+ find . -name '*~' -exec rm {} ';'
+ rm -rf pvemanagerlib.js
+
+
+
+++ /dev/null
-include $(top_builddir)/common.mk
-
-JSSRC= \
- Utils.js \
- Parser.js \
- StateProvider.js \
- VNCConsole.js \
- data/TimezoneStore.js \
- data/reader/JsonObject.js \
- data/PVEProxy.js \
- data/UpdateQueue.js \
- data/UpdateStore.js \
- data/DiffStore.js \
- data/ObjectStore.js \
- data/ResourceStore.js \
- form/Checkbox.js \
- form/TextField.js \
- form/RRDTypeSelector.js \
- form/ComboGrid.js \
- form/KVComboBox.js \
- form/Boolean.js \
- form/NetworkCardSelector.js \
- form/DiskFormatSelector.js \
- form/BusTypeSelector.js \
- form/ControllerSelector.js \
- form/RealmComboBox.js \
- form/BondModeSelector.js \
- form/ViewSelector.js \
- form/NodeSelector.js \
- form/FileSelector.js \
- form/StorageSelector.js \
- form/BridgeSelector.js \
- form/CPUModelSelector.js \
- form/VNCKeyboardSelector.js \
- form/DisplaySelector.js \
- form/CacheTypeSelector.js \
- form/ContentTypeSelector.js \
- dc/Tasks.js \
- dc/Log.js \
- panel/StatusPanel.js \
- panel/RRDView.js \
- panel/InputPanel.js \
- window/Edit.js \
- window/LoginWindow.js \
- window/TaskViewer.js \
- window/Wizard.js \
- grid/SelectFeature.js \
- grid/ObjectGrid.js \
- grid/ResourceGrid.js \
- tree/ResourceTree.js \
- panel/ConfigPanel.js \
- node/DNSEdit.js \
- node/DNSView.js \
- node/TimeView.js \
- node/TimeEdit.js \
- node/StatusView.js \
- node/Summary.js \
- node/ServiceView.js \
- node/NetworkEdit.js \
- node/NetworkView.js \
- node/Syslog.js \
- node/Tasks.js \
- node/Config.js \
- qemu/StatusView.js \
- qemu/Summary.js \
- qemu/OSTypeEdit.js \
- qemu/ProcessorEdit.js \
- qemu/BootOrderEdit.js \
- qemu/MemoryEdit.js \
- qemu/NetworkEdit.js \
- qemu/CDEdit.js \
- qemu/HDEdit.js \
- qemu/DisplayEdit.js \
- qemu/NotesEdit.js \
- qemu/NotesView.js \
- qemu/KeyboardEdit.js \
- qemu/HardwareView.js \
- qemu/Options.js \
- qemu/Config.js \
- qemu/CreateWizard.js \
- openvz/CreateWizard.js \
- storage/ContentView.js \
- storage/StatusView.js \
- storage/Summary.js \
- storage/Browser.js \
- storage/DirEdit.js \
- storage/NFSEdit.js \
- storage/IScsiEdit.js \
- storage/LVMEdit.js \
- dc/OptionView.js \
- dc/StorageView.js \
- dc/UserEdit.js \
- dc/UserView.js \
- dc/GroupView.js \
- dc/GroupEdit.js \
- dc/RoleView.js \
- dc/ACLView.js \
- dc/AuthView.js \
- dc/AuthEdit.js \
- dc/Config.js \
- Workspace.js
-
-lint: ${JSSRC}
- jslint ${JSSRC}
-
-pvemanagerlib.js: ${JSSRC}
- cat ${JSSRC} >$@.tmp
- mv $@.tmp $@
-
-pvelib_DATA = pvemanagerlib.js
-pvelibdir = ${WWW_EXTDIR}
-
-privatedir = ${WWW_BASEDIR}
-private_SCRIPTS = \
- startup.pl
-
-managerdir = ${WWW_ROOTDIR}
-manager_SCRIPTS = \
- index.pl
-
-install-data-hook:
- chown -R www-data:www-data ${DESTDIR}/${privatedir}
- chown -R www-data:www-data ${DESTDIR}/${managerdir}
- chown -R www-data:www-data ${DESTDIR}/${pvelibdir}
-
-clean-local:
- find . -name '*~' -exec rm {} ';'
- -rm -rf pvemanagerlib.js
-
-
--- /dev/null
+include ../../defines.mk
+
+all: ve-pve.auto.conf-sample
+
+ve-pve.auto.conf-sample: generate.pl
+ ./generate.pl 256 > $@.tmp
+ echo FIXME: vzcfgvalidate $@.tmp
+ mv $@.tmp $@
+
+.PHONY: install
+install: ve-pve.auto.conf-sample pve.conf pve-redirect.conf
+ install -d ${DESTDIR}/etc/vz/conf
+ install -m 0644 ve-pve.auto.conf-sample ${DESTDIR}/etc/vz/conf
+ install -d ${DESTDIR}/etc/apache2/sites-available/
+ install -m 0644 pve.conf pve-redirect.conf ${DESTDIR}/etc/apache2/sites-available/
+
+.PHONY: distclean
+distclean: clean
+
+.PHONY: clean
+clean:
+ rm -rf *~ ve-pve.auto.conf-sample ve-pve.auto.conf-sample.tmp
+++ /dev/null
-include $(top_builddir)/common.mk
-
-ve-pve.auto.conf-sample: generate.pl
- ./generate.pl 256 > $@.tmp
- vzcfgvalidate $@.tmp
- mv $@.tmp $@
-
-
-apache_DATA = $(BUILDDATA)
-
-apachedir = /etc/apache2/sites-available/
-
-vesample_DATA = ve-pve.auto.conf-sample
-
-vesampledir = /etc/vz/conf
-
-BUILDDATA = pve.conf pve-redirect.conf
-
-CLEANFILES=*~ ve-pve.auto.conf-sample.tmp
-
+++ /dev/null
-<IfModule mpm_prefork_module>
- StartServers 2
- MinSpareServers 1
- MaxSpareServers 2
- MaxClients 50
- MaxRequestsPerChild 30
-</IfModule>
-
-ServerName localhost
-ServerSignature Off
-ServerTokens Prod
-ServerAdmin root
-AddDefaultCharset On
-
-# Hint: Ajax use KeepAlive, which in effect disables MaxRequestsPerChild,
-# so we need to disable KeepAlive to prevent exhaustive memory usage, or
-# at least make sure that periodic updaters interval > KeepAliveTimeout
-# or maybe we should set "MaxKeepAliveRequests 20"
-
-KeepAlive Off
-
-DocumentRoot @WWW_ROOTDIR@
-<Directory />
- Options FollowSymLinks
- AllowOverride None
-</Directory>
-
-<Directory @WWW_ROOTDIR@>
- Options FollowSymLinks MultiViews
- AllowOverride None
- Order allow,deny
- allow from all
-</Directory>
-
-ErrorLog /var/log/apache2/error.log
-
-LogLevel warn
-
-# do not log access to our ajax services
-SetEnvIf Request_URI "^/ws/" dontlog
-
-CustomLog /var/log/apache2/access.log combined env=!dontlog
-
-Alias /images/ @WWW_IMAGEDIR@/
-Alias /css/ @WWW_CSSDIR@/
-Alias /ext/ @WWW_EXTDIR@/
-Alias /javascript/ /usr/share/javascript/
-Alias /vncterm/ /usr/share/vncterm/
-
-# avoid authentication when accessing favicon
-Alias /favicon.ico @WWW_IMAGEDIR@/favicon.ico
-
-PerlModule Embperl
-EMBPERL_SESSION_ARGS "config=DB_File Lock=Semaphore"
-
-AddType text/html .epl
-
-PerlRequire @WWW_ROOTDIR@/startup.pl
-
-PerlSetVar PVESatisfy any
-PerlSetVar PVEPath /
-PerlSetVar PVELoginScript /login.pl
-
-PerlTransHandler PVE::URLRewrite
-
-Alias /nrd/ /__no_real_dir__/
-
-<Directory "@WWW_ROOTDIR@">
- AuthType PVE::AuthCookieHandler
- AuthName PVE
- PerlSetVar PVECookieName PVEAuthCookie
- #PerlSetVar AuthCookieDebug 5
-
- PerlAuthenHandler PVE::AuthCookieHandler->authenticate
- PerlAuthzHandler PVE::AuthCookieHandler->authorize
-
- require group root
-
- DirectoryIndex index.htm index.pl
-
- <FilesMatch ".*\.htm$">
- EMBPERL_APPNAME PVE
- EMBPERL_SYNTAX EmbperlBlocks
- EMBPERL_OBJECT_BASE base.epl
- EMBPERL_INPUT_ESCMODE 0
- EMBPERL_ESCMODE 0
- SetHandler perl-script
- PerlHandler Embperl::Object
- Options ExecCGI
- </FilesMatch>
- <FilesMatch ".*\.epl$">
- Order allow,deny
- Deny From all
- </FilesMatch>
- <FilesMatch ".*\.pl$">
- SetHandler perl-script
- PerlHandler ModPerl::Registry
- Options +ExecCGI
- </FilesMatch>
-
-</Directory>
-
-<Location /nrd/LOGIN>
- AuthType PVE::AuthCookieHandler
- AuthName PVE
- PerlSetVar PVECookieName PVEAuthCookie
- #PerlSetVar AuthCookieDebug 5
- SetHandler perl-script
- PerlHandler PVE::AuthCookieHandler->login
-</Location>
-
-<Location /ws/>
- SetHandler perl-script
- PerlHandler $PVE::HTMLServices::Obj->handler
-</Location>
-
-<VirtualHost *:443>
-
- SSLEngine on
- SSLProtocol all -SSLv2
- SSLCertificateFile @PROXMOX_ETC@/pve-ssl.pem
- SSLCertificateKeyFile @PROXMOX_ETC@/pve-ssl.key
-
- RewriteEngine on
- RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
- RewriteRule .* - [F]
-
- </VirtualHost>
-
-<VirtualHost *:80>
- #RewriteLog "/root/rewrite.log"
- #RewriteLogLevel 10
- RewriteEngine on
- RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
- RewriteRule .* - [F]
- RewriteCond %{REQUEST_URI} !^/nrd/
- RewriteCond %{REQUEST_URI} !^/images/
- RewriteCond %{REQUEST_URI} !^/css/
- RewriteCond %{REQUEST_URI} !^/ext/
- RewriteCond %{REQUEST_URI} !^/javascript/
- RewriteCond %{REQUEST_URI} !^/vncterm/
- RewriteCond %{REQUEST_URI} !^/.*\.js$
- RewriteCond %{REQUEST_URI} !^/login.pl$
- RewriteRule ^/(.*) https://%{HTTP_HOST}/$1 [L,R]
-</VirtualHost>
-
--- /dev/null
+<VirtualHost *:80>
+ #RewriteLog "/root/rewrite.log"
+ #RewriteLogLevel 10
+ RewriteEngine on
+ RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
+ RewriteRule .* - [F]
+ RewriteRule ^/(.*) https://%{HTTP_HOST}:8006/$1 [L,R]
+</VirtualHost>
+
+<VirtualHost *:443>
+ SSLEngine on
+ SSLProtocol all -SSLv2
+ SSLCertificateFile /etc/pve/local/pve-ssl.pem
+ SSLCertificateKeyFile /etc/pve/local/pve-ssl.key
+
+ RewriteEngine on
+ RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
+ RewriteRule .* - [F]
+ RewriteRule ^/(.*) https://%{HTTP_HOST}:8006/$1 [L,R]
+</VirtualHost>
+
+++ /dev/null
-<VirtualHost *:80>
- #RewriteLog "/root/rewrite.log"
- #RewriteLogLevel 10
- RewriteEngine on
- RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
- RewriteRule .* - [F]
- RewriteRule ^/(.*) https://%{HTTP_HOST}:8006/$1 [L,R]
-</VirtualHost>
-
-<VirtualHost *:443>
- SSLEngine on
- SSLProtocol all -SSLv2
- SSLCertificateFile @PROXMOX_ETC@/local/pve-ssl.pem
- SSLCertificateKeyFile @PROXMOX_ETC@/local/pve-ssl.key
-
- RewriteEngine on
- RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
- RewriteRule .* - [F]
- RewriteRule ^/(.*) https://%{HTTP_HOST}:8006/$1 [L,R]
-</VirtualHost>
-
--- /dev/null
+<IfModule mpm_prefork_module>
+ StartServers 2
+ MinSpareServers 1
+ MaxSpareServers 2
+ MaxClients 50
+ MaxRequestsPerChild 200
+</IfModule>
+
+ServerName localhost
+ServerSignature Off
+ServerTokens Prod
+ServerAdmin root
+AddDefaultCharset On
+
+# Hint: Ajax use KeepAlive, which in effect disables MaxRequestsPerChild,
+# so we need to disable KeepAlive to prevent exhaustive memory usage, or
+# at least make sure that periodic updaters interval > KeepAliveTimeout
+# or maybe we should set "MaxKeepAliveRequests 20"
+
+KeepAlive Off
+
+<IfModule mod_deflate.c>
+ AddOutputFilterByType DEFLATE application/json
+</IfModule>
+
+CustomLog ${APACHE_LOG_DIR}/access.log combined
+
+Listen 8006
+<VirtualHost *:8006>
+ SSLEngine on
+ SSLProtocol all -SSLv2
+ SSLCertificateFile /etc/pve/local/pve-ssl.pem
+ SSLCertificateKeyFile /etc/pve/local/pve-ssl.key
+
+ RewriteEngine on
+ RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
+ RewriteRule .* - [F]
+
+ DocumentRoot /usr/share/pve-manager/root
+ <Directory />
+ Options FollowSymLinks
+ AllowOverride None
+ </Directory>
+
+ <Directory /usr/share/pve-manager/root>
+ Options FollowSymLinks MultiViews
+ AllowOverride None
+ Order allow,deny
+ allow from all
+ </Directory>
+
+ Alias /pve2/css/ /usr/share/pve-manager/css/
+ Alias /pve2/ext4 /usr/share/pve-manager/ext4/
+ Alias /pve2/images/ /usr/share/pve-manager/images/
+ Alias /vncterm/ /usr/share/vncterm/
+
+ # avoid authentication when accessing favicon
+ Alias /favicon.ico /usr/share/pve-manager/images/favicon.ico
+
+ PerlRequire /usr/share/pve-manager/startup.pl
+
+ <Location /index.pl>
+ SetHandler perl-script
+ PerlHandler ModPerl::Registry
+ Options ExecCGI
+ </Location>
+
+ <Location /api2/>
+ SetHandler perl-script
+ PerlHandler PVE::REST
+ </Location>
+
+</VirtualHost>
+
+++ /dev/null
-<IfModule mpm_prefork_module>
- StartServers 2
- MinSpareServers 1
- MaxSpareServers 2
- MaxClients 50
- MaxRequestsPerChild 200
-</IfModule>
-
-ServerName localhost
-ServerSignature Off
-ServerTokens Prod
-ServerAdmin root
-AddDefaultCharset On
-
-# Hint: Ajax use KeepAlive, which in effect disables MaxRequestsPerChild,
-# so we need to disable KeepAlive to prevent exhaustive memory usage, or
-# at least make sure that periodic updaters interval > KeepAliveTimeout
-# or maybe we should set "MaxKeepAliveRequests 20"
-
-KeepAlive Off
-
-<IfModule mod_deflate.c>
- AddOutputFilterByType DEFLATE application/json
-</IfModule>
-
-CustomLog ${APACHE_LOG_DIR}/access.log combined
-
-Listen 8006
-<VirtualHost *:8006>
- SSLEngine on
- SSLProtocol all -SSLv2
- SSLCertificateFile @PROXMOX_ETC@/local/pve-ssl.pem
- SSLCertificateKeyFile @PROXMOX_ETC@/local/pve-ssl.key
-
- RewriteEngine on
- RewriteCond %{REQUEST_METHOD} ^(TRACE|TRACK)
- RewriteRule .* - [F]
-
- DocumentRoot @WWW_ROOTDIR@
- <Directory />
- Options FollowSymLinks
- AllowOverride None
- </Directory>
-
- <Directory @WWW_ROOTDIR@>
- Options FollowSymLinks MultiViews
- AllowOverride None
- Order allow,deny
- allow from all
- </Directory>
-
- Alias /pve2/ @WWW_BASEDIR@/
- Alias /vncterm/ /usr/share/vncterm/
-
- # avoid authentication when accessing favicon
- Alias /favicon.ico @WWW_IMAGEDIR@/favicon.ico
-
- PerlRequire @WWW_BASEDIR@/startup.pl
-
- <Location /index.pl>
- SetHandler perl-script
- PerlHandler ModPerl::Registry
- Options ExecCGI
- </Location>
-
- <Location /api2/>
- SetHandler perl-script
- PerlHandler PVE::REST
- </Location>
-
-</VirtualHost>
-
+++ /dev/null
-# PVE default config for 256MB RAM
-
-ONBOOT="no"
-
-# Primary parameters
-NUMPROC="1024:1024"
-NUMTCPSOCK="9223372036854775807:9223372036854775807"
-NUMOTHERSOCK="9223372036854775807:9223372036854775807"
-VMGUARPAGES="65536:9223372036854775807"
-
-# Secondary parameters
-KMEMSIZE="9223372036854775807:9223372036854775807"
-OOMGUARPAGES="65536:9223372036854775807"
-PRIVVMPAGES="65536:72089"
-TCPSNDBUF="9223372036854775807:9223372036854775807"
-TCPRCVBUF="9223372036854775807:9223372036854775807"
-OTHERSOCKBUF="9223372036854775807:9223372036854775807"
-DGRAMRCVBUF="9223372036854775807:9223372036854775807"
-
-# Auxiliary parameters
-NUMFILE="9223372036854775807:9223372036854775807"
-NUMFLOCK="9223372036854775807:9223372036854775807"
-NUMPTY="255:255"
-NUMSIGINFO="1024:1024"
-DCACHESIZE="9223372036854775807:9223372036854775807"
-LOCKEDPAGES="9223372036854775807:9223372036854775807"
-SHMPAGES="9223372036854775807:9223372036854775807"
-NUMIPTENT="9223372036854775807:9223372036854775807"
-PHYSPAGES="0:9223372036854775807"
-
-# Disk quota parameters
-DISKSPACE="9223372036854775807:9223372036854775807"
-DISKINODES="9223372036854775807:9223372036854775807"
-QUOTATIME="0"
-QUOTAUGIDLIMIT="0"
-
-# CPU fair sheduler parameter
-CPUUNITS="1000"
-CPUS="1"