We are going to make this script control PDUs other than APC ones.
No overall functional change for internal callers. Anyone out-of-tree
using this script will need to change the name of the program they run.
Signed-off-by: Ian Jackson <iwj@xenproject.org>
sub pdu_power_state {
my ($mo, $on) = @_;
my $onoff= $on ? "on" : "off";
- system_checked("./pdu-msw @{ $mo->{Args} } $onoff");
+ system_checked("./pdu-snmp @{ $mo->{Args} } $onoff");
}
1;
msw [--apc6] <pdu> <port-name-regexp|port-num>
Control an APC masterswitch via SNMP. The SNMP
- community is `private'. See the `pdu-msw' script.
+ community is `private'. See the `pdu-snmp' script.
ipmi <mgmt> [<user> [<pass> [<ipmitool options...>]]]
Use IPMI by (by running ipmitool). <mgmt> is the name or
+++ /dev/null
-#!/usr/bin/perl -w
-
-# This is part of "osstest", an automated testing framework for Xen.
-# Copyright (C) 2009-2013 Citrix Inc.
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU Affero General Public License as published by
-# the Free Software Foundation, either version 3 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 Affero General Public License for more details.
-#
-# You should have received a copy of the GNU Affero General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-
-
-my $usagemsg= <<END;
-usage:
- pdu-msw SWITCH-DNS-NAME PORT-NAME-REGEXP|PORT [[delayed-]on|off|0|1|reboot]
-END
-
-use strict qw(refs vars);
-use Net::SNMP;
-use Data::Dumper;
-
-my $community= 'private';
-my $baseoid= '.1.3.6.1.4.1.318.1.1.4.4.2.1';
-my $baseoid_write= "$baseoid.3";
-
-while (@ARGV && $ARGV[0] =~ m/^-/) {
- $_ = shift @ARGV;
- if (m/^--apc6$/) {
- $baseoid_write= '.1.3.6.1.4.1.318.1.1.12.3.3.1.1.4';
- } else {
- die "$_ ?";
- }
-}
-
-if (@ARGV<2 || @ARGV>3 || $ARGV[0] =~ m/^-/) { die "bad usage\n$usagemsg"; }
-
-our ($max_retries) = 16; # timeout = 0.05 * max_retries^2
-our ($dnsname,$outlet,$action) = @ARGV;
-
-my ($session,$error) = Net::SNMP->session(
- -hostname => $dnsname,
- -community => $community,
- );
-die "SNMP error $error " unless defined $session;
-
-sub getname ($) {
- my ($port) = @_;
- my $oid= "$baseoid.4.$port";
- my $res= $session->get_request($oid);
- if ($res) {
- my $name= $res->{$oid};
- die unless defined $name;
- return $name;
- } elsif ($port>1 && $session->error_status() == 2) {
- return undef;
- } else {
- die "SNMP error on $oid ".$session->error()." ";
- }
-}
-
-my $useport;
-my $usename;
-if ($outlet =~ m/^\d+$/) {
- $useport= $outlet;
- $usename= getname($outlet);
- $usename= '?' unless defined $usename;
-} else {
- my (@found,@all);
- my $ix=1;
- for (;; $ix++) {
- my $name= getname($ix);
- last unless defined $name;
- my $match= !!($name =~ m/$outlet/o);
- my $t= [ $ix, $name, $match ];
- push @all, $t;
- push @found, $t if $match;
- next;
- }
- if (@found!=1) {
- foreach my $t (@all) {
- printf("%1s %2d %s\n",
- ($t->[2] ? '*' : ''),
- $t->[0], $t->[1]);
- }
- die "pdu-msw $dnsname: ".
- (@found ? "multiple ports match" : "no ports match").
- "\n";
- }
- ($useport,$usename)= @{ $found[0] };
-}
-
-my $read_oid= "$baseoid.3.$useport";
-my $write_oid= "$baseoid_write.$useport";
-
-my @map= (undef, qw(
- on
- off
- reboot
- delayed-on
- delayed-off
- delayed-reboot));
-
-sub get () {
- my $got= $session->get_request($read_oid);
- die "SNMP error reading $read_oid ".$session->error()." " unless $got;
- my $val= $got->{$read_oid};
- die unless $val;
- my $mean= $map[$val];
- die "$val ?" unless defined $mean;
- return $mean;
-}
-
-sub show () {
- my $mean = get();
- printf "pdu-msw $dnsname: #%s \"%s\" = %s\n", $useport, $usename, $mean;
- return $mean;
-}
-
-sub action_value () {
- my $delayadd= ($action =~ s/^delayed-// ? 3 : 0);
- my $valset= ($action =~ m/^(?:0|off)$/ ? 2 :
- $action =~ m/^(?:1|on)$/ ? 1 :
- $action =~ m/^(?:reboot)$/ ? 3 :
- die "unknown action $action\n$usagemsg");
- return $valset + $delayadd;
-}
-
-sub set ($) {
- my ($valset) = @_;
- my $res= $session->set_request(-varbindlist => [ $write_oid, INTEGER, $valset ]);
- die "SNMP set ".$session->error()." " unless $res;
-}
-
-if (!defined $action) {
- show();
-} else {
- my $valset = action_value();
- print "was: "; show();
-
- my $retries = 0;
- for (;;) {
- set($valset);
- sleep $retries * 0.1;
- print "now: "; my $got = show();
- if ($got eq $map[$valset]) { last; }
- if ($map[$valset] !~ m{^(?:off|on)$}) {
- print
- "^ note, PDUs often do not update returned info immediately\n";
- last;
- }
- if ($retries >= $max_retries) {
- die "PDU does not seem to be changing state!\n";
- }
- $retries++;
- }
-}
--- /dev/null
+#!/usr/bin/perl -w
+
+# This is part of "osstest", an automated testing framework for Xen.
+# Copyright (C) 2009-2013 Citrix Inc.
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License as published by
+# the Free Software Foundation, either version 3 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 Affero General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+
+my $usagemsg= <<END;
+usage:
+ pdu-snmp SWITCH-DNS-NAME PORT-NAME-REGEXP|PORT [[delayed-]on|off|0|1|reboot]
+END
+
+use strict qw(refs vars);
+use Net::SNMP;
+use Data::Dumper;
+
+my $community= 'private';
+my $baseoid= '.1.3.6.1.4.1.318.1.1.4.4.2.1';
+my $baseoid_write= "$baseoid.3";
+
+while (@ARGV && $ARGV[0] =~ m/^-/) {
+ $_ = shift @ARGV;
+ if (m/^--apc6$/) {
+ $baseoid_write= '.1.3.6.1.4.1.318.1.1.12.3.3.1.1.4';
+ } else {
+ die "$_ ?";
+ }
+}
+
+if (@ARGV<2 || @ARGV>3 || $ARGV[0] =~ m/^-/) { die "bad usage\n$usagemsg"; }
+
+our ($max_retries) = 16; # timeout = 0.05 * max_retries^2
+our ($dnsname,$outlet,$action) = @ARGV;
+
+my ($session,$error) = Net::SNMP->session(
+ -hostname => $dnsname,
+ -community => $community,
+ );
+die "SNMP error $error " unless defined $session;
+
+sub getname ($) {
+ my ($port) = @_;
+ my $oid= "$baseoid.4.$port";
+ my $res= $session->get_request($oid);
+ if ($res) {
+ my $name= $res->{$oid};
+ die unless defined $name;
+ return $name;
+ } elsif ($port>1 && $session->error_status() == 2) {
+ return undef;
+ } else {
+ die "SNMP error on $oid ".$session->error()." ";
+ }
+}
+
+my $useport;
+my $usename;
+if ($outlet =~ m/^\d+$/) {
+ $useport= $outlet;
+ $usename= getname($outlet);
+ $usename= '?' unless defined $usename;
+} else {
+ my (@found,@all);
+ my $ix=1;
+ for (;; $ix++) {
+ my $name= getname($ix);
+ last unless defined $name;
+ my $match= !!($name =~ m/$outlet/o);
+ my $t= [ $ix, $name, $match ];
+ push @all, $t;
+ push @found, $t if $match;
+ next;
+ }
+ if (@found!=1) {
+ foreach my $t (@all) {
+ printf("%1s %2d %s\n",
+ ($t->[2] ? '*' : ''),
+ $t->[0], $t->[1]);
+ }
+ die "pdu-snmp $dnsname: ".
+ (@found ? "multiple ports match" : "no ports match").
+ "\n";
+ }
+ ($useport,$usename)= @{ $found[0] };
+}
+
+my $read_oid= "$baseoid.3.$useport";
+my $write_oid= "$baseoid_write.$useport";
+
+my @map= (undef, qw(
+ on
+ off
+ reboot
+ delayed-on
+ delayed-off
+ delayed-reboot));
+
+sub get () {
+ my $got= $session->get_request($read_oid);
+ die "SNMP error reading $read_oid ".$session->error()." " unless $got;
+ my $val= $got->{$read_oid};
+ die unless $val;
+ my $mean= $map[$val];
+ die "$val ?" unless defined $mean;
+ return $mean;
+}
+
+sub show () {
+ my $mean = get();
+ printf "pdu-snmp $dnsname: #%s \"%s\" = %s\n", $useport, $usename, $mean;
+ return $mean;
+}
+
+sub action_value () {
+ my $delayadd= ($action =~ s/^delayed-// ? 3 : 0);
+ my $valset= ($action =~ m/^(?:0|off)$/ ? 2 :
+ $action =~ m/^(?:1|on)$/ ? 1 :
+ $action =~ m/^(?:reboot)$/ ? 3 :
+ die "unknown action $action\n$usagemsg");
+ return $valset + $delayadd;
+}
+
+sub set ($) {
+ my ($valset) = @_;
+ my $res= $session->set_request(-varbindlist => [ $write_oid, INTEGER, $valset ]);
+ die "SNMP set ".$session->error()." " unless $res;
+}
+
+if (!defined $action) {
+ show();
+} else {
+ my $valset = action_value();
+ print "was: "; show();
+
+ my $retries = 0;
+ for (;;) {
+ set($valset);
+ sleep $retries * 0.1;
+ print "now: "; my $got = show();
+ if ($got eq $map[$valset]) { last; }
+ if ($map[$valset] !~ m{^(?:off|on)$}) {
+ print
+ "^ note, PDUs often do not update returned info immediately\n";
+ last;
+ }
+ if ($retries >= $max_retries) {
+ die "PDU does not seem to be changing state!\n";
+ }
+ $retries++;
+ }
+}