fence-agents: master - fence_amt: Adapt environment and build system to incorporate fence_amt
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=806d29...
Commit: 806d293da6ea7d5e5259faf806e17b40c45ae536
Parent: f37a64bd3f53f95358139b175d70269cf4f17850
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Jan 6 17:08:12 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Jan 6 17:08:12 2014 +0100
fence_amt: Adapt environment and build system to incorporate fence_amt
---
configure.ac | 1 +
fence/agents/amt/Makefile.am | 17 +++++++++++++++++
2 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/configure.ac b/configure.ac
index 02c46b8..c394690 100644
--- a/configure.ac
+++ b/configure.ac
@@ -255,6 +255,7 @@ AC_CONFIG_FILES([Makefile
fence/agents/alom/Makefile
fence/agents/apc/Makefile
fence/agents/apc_snmp/Makefile
+ fence/agents/amt/Makefile
fence/agents/baytech/Makefile
fence/agents/bladecenter/Makefile
fence/agents/brocade/Makefile
diff --git a/fence/agents/amt/Makefile.am b/fence/agents/amt/Makefile.am
new file mode 100644
index 0000000..9902731
--- /dev/null
+++ b/fence/agents/amt/Makefile.am
@@ -0,0 +1,17 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+TARGET = fence_amt
+
+SRC = $(TARGET).py
+
+EXTRA_DIST = $(SRC)
+
+sbin_SCRIPTS = $(TARGET)
+
+man_MANS = $(TARGET).8
+
+include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
+
+clean-local: clean-man
+ rm -f $(TARGET)
diff --git a/fence/agents/amt/fence_amt.py b/fence/agents/amt/fence_amt.py
old mode 100755
new mode 100644
10 years, 4 months
fence-agents: master - fence_amt: new fence agent for Intel AMT
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=f37a64...
Commit: f37a64bd3f53f95358139b175d70269cf4f17850
Parent: 821478ebcd1b6ee31636e7910bc35fb41b4834b1
Author: Ondrej Mular <omular(a)redhat.com>
AuthorDate: Mon Dec 30 11:24:54 2013 -0500
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Jan 6 17:05:00 2014 +0100
fence_amt: new fence agent for Intel AMT
New fence agent for Intel AMT.
---
fence/agents/amt/fence_amt.py | 149 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 149 insertions(+), 0 deletions(-)
diff --git a/fence/agents/amt/fence_amt.py b/fence/agents/amt/fence_amt.py
new file mode 100755
index 0000000..c164c66
--- /dev/null
+++ b/fence/agents/amt/fence_amt.py
@@ -0,0 +1,149 @@
+#!/usr/bin/python
+
+import sys, subprocess, re, os, stat
+from pipes import quote
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import *
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION="Fence agent for Intel AMT"
+REDHAT_COPYRIGHT=""
+BUILD_DATE=""
+#END_VERSION_GENERATION
+
+def get_power_status(_, options):
+
+ cmd = create_command(options, "status")
+
+ if options["log"] >= LOG_MODE_VERBOSE:
+ options["debug_fh"].write("executing: " + cmd + "\n")
+
+ try:
+ process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+ except OSError:
+ fail_usage("Amttool not found or not accessible")
+
+ process.wait()
+
+ output = process.communicate()
+ process.stdout.close()
+ options["debug_fh"].write(output)
+
+ match = re.search('Powerstate:[\\s]*(..)', str(output))
+ status = match.group(1) if match else None
+
+ if (status == None):
+ return "fail"
+ elif (status == "S0"): # SO = on; S3 = sleep; S5 = off
+ return "on"
+ else:
+ return "off"
+
+def set_power_status(_, options):
+
+ cmd = create_command(options, options["--action"])
+
+ if options["log"] >= LOG_MODE_VERBOSE:
+ options["debug_fh"].write("executing: " + cmd + "\n")
+
+ try:
+ process = subprocess.Popen(cmd, stdout=options["debug_fh"], stderr=options["debug_fh"], shell=True)
+ except OSError:
+ fail_usage("Amttool not found or not accessible")
+
+ process.wait()
+
+ return
+
+def reboot_cycle(_, options):
+ cmd = create_command(options, "cycle")
+
+ if options["log"] >= LOG_MODE_VERBOSE:
+ options["debug_fh"].write("executing: " + cmd + "\n")
+
+ try:
+ process = subprocess.Popen(cmd, stdout=options["debug_fh"], stderr=options["debug_fh"], shell=True)
+ except OSError:
+ fail_usage("Amttool not found or not accessible")
+
+ status = process.wait()
+
+ return not bool(status)
+
+def create_command(options, action):
+
+ # --password / -p
+ cmd = "AMT_PASSWORD=" + quote(options["--password"])
+
+ cmd += " " + options["--amttool-path"]
+
+ # --ip / -a
+ cmd += " " + options["--ip"]
+
+ # --action / -o
+ if action == "status":
+ cmd += " info"
+ elif action == "on":
+ cmd = "echo \"y\"|" + cmd
+ cmd += " powerup"
+ elif action == "off":
+ cmd = "echo \"y\"|" + cmd
+ cmd += " powerdown"
+ elif action == "cycle":
+ cmd = "echo \"y\"|" + cmd
+ cmd += " powercycle"
+ if action in ["on", "off", "cycle"] and options.has_key("--boot-option"):
+ cmd += options["--boot-option"]
+
+ # --use-sudo / -d
+ if options.has_key("--use-sudo"):
+ cmd = SUDO_PATH + " " + cmd
+
+ return cmd
+
+def define_new_opts():
+ all_opt["boot_option"] = {
+ "getopt" : "b:",
+ "longopt" : "boot-option",
+ "help" : "-b, --boot-option=[option] Change the default boot behavior of the machine. (pxe|hd|hdsafe|cd|diag)",
+ "required" : "0",
+ "shortdesc" : "Change the default boot behavior of the machine.",
+ "choices" : ["pxe", "hd", "hdsafe", "cd", "diag"],
+ "order" : 1
+ }
+ all_opt["amttool_path"] = {
+ "getopt" : "i:",
+ "longopt" : "amttool-path",
+ "help" : "--amttool-path=[path] Path to amttool binary",
+ "required" : "0",
+ "shortdesc" : "Path to amttool binary",
+ "default" : "@AMTTOOL_PATH@",
+ "order": 200
+ }
+
+def main():
+
+ atexit.register(atexit_handler)
+
+ device_opt = [ "ipaddr", "no_login", "passwd", "boot_option", "no_port",
+ "sudo", "amttool_path", "method" ]
+
+ define_new_opts()
+
+ options = check_input(device_opt, process_input(device_opt))
+
+ docs = { }
+ docs["shortdesc"] = "Fence agent for AMT"
+ docs["longdesc"] = "Fence agent for AMT"
+ docs["vendorurl"] = "http://www.intel.com/"
+ show_docs(options, docs)
+
+ if not is_executable(options["--amttool-path"]):
+ fail_usage("Amttool not found or not accessible")
+
+ result = fence_action(None, options, set_power_status, get_power_status, None, reboot_cycle)
+
+ sys.exit(result)
+
+if __name__ == "__main__":
+ main()
10 years, 4 months
fence-agents: master - fence_ipmilan: Remove old fence agent
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=821478...
Commit: 821478ebcd1b6ee31636e7910bc35fb41b4834b1
Parent: 625c42b5b8e16171f7efc65a4e88b3be92e04f18
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Jan 6 17:04:38 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Jan 6 17:04:38 2014 +0100
fence_ipmilan: Remove old fence agent
---
fence/agents/ipmilan/expect.c | 343 -----------
fence/agents/ipmilan/expect.h | 52 --
fence/agents/ipmilan/ipmilan.c | 1279 ----------------------------------------
3 files changed, 0 insertions(+), 1674 deletions(-)
diff --git a/fence/agents/ipmilan/expect.c b/fence/agents/ipmilan/expect.c
deleted file mode 100644
index 2ed40f0..0000000
--- a/fence/agents/ipmilan/expect.c
+++ /dev/null
@@ -1,343 +0,0 @@
-/** @file
- * Simple expect module for the STONITH library.
- */
-#include "clusterautoconfig.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-#include <string.h>
-#include <errno.h>
-#include <syslog.h>
-#include <libintl.h>
-#include <sys/wait.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stddef.h>
-#include <stdarg.h>
-#include <string.h>
-#include <unistd.h>
-#include <signal.h>
-#include <errno.h>
-#include <time.h>
-#include <sys/time.h>
-#include <sys/times.h>
-#ifdef _POSIX_PRIORITY_SCHEDULING
-# include <sched.h>
-#endif
-
-#include "expect.h"
-
-#ifndef EOS
-# define EOS '\0'
-#endif
-
-
-/*
- * Just incase we are on an out of date system
- */
-#ifndef CLOCKS_PER_SEC
-# ifndef CLK_TCK
-# error Neither CLOCKS_PER_SEC nor CLK_TCK (obsolete) are defined
-# endif /* CLK_TCK */
-# define CLOCKS_PER_SEC CLK_TCK
-#endif /* CLOCKS_PER_SEC */
-
-
-void close_all_files (void);
-
-/**
- * Look for ('expect') any of a series of tokens in the input
- * Return the token type for the given token or -1 on error.
- *
- * @param fd The file descriptor to watch.
- * @param toklist The series of tokens to look for.
- * @param to_secs Timeout (in seconds).
- * @param buf Receive buffer (preallocated).
- * @param maxline Length of receive buffer.
- */
-int
-ExpectToken(int fd, struct Etoken * toklist, int to_secs, char * buf
-, int maxline)
-{
- clock_t starttime;
- clock_t endtime;
- int wraparound=0;
- int tickstousec = (1000000/CLOCKS_PER_SEC);
- clock_t now;
- clock_t ticks;
- int nchars = 1; /* reserve space for an EOS */
- struct timeval tv;
- struct tms tms_unused; /*This tms is unused, but cygwin doesn't like NULL in times*/
- struct Etoken * this;
-
- /* Figure out when to give up. Handle lbolt wraparound */
- if (fd < 0) {
- errno = EINVAL;
- return -1;
- }
-
- starttime = times(&tms_unused);
- ticks = (to_secs*CLOCKS_PER_SEC);
- endtime = starttime + ticks;
-
- if (endtime < starttime) {
- wraparound = 1;
- }
-
- if (buf) {
- *buf = EOS;
- }
-
- for (this=toklist; this->string; ++this) {
- this->matchto = 0;
- }
-
-
- while (now = times(&tms_unused),
- (wraparound && (now > starttime || now <= endtime))
- || (!wraparound && now <= endtime)) {
-
- fd_set infds;
- char ch;
- clock_t timeleft;
- int retval;
-
- timeleft = endtime - now;
-
- tv.tv_sec = timeleft / CLOCKS_PER_SEC;
- tv.tv_usec = (timeleft % CLOCKS_PER_SEC) * tickstousec;
-
- if (tv.tv_sec == 0 && tv.tv_usec < tickstousec) {
- /* Give 'em a little chance */
- tv.tv_usec = tickstousec;
- }
-
- /* Watch our FD to see when it has input. */
- FD_ZERO(&infds);
- FD_SET(fd, &infds);
-
- retval = select(fd+1, &infds, NULL, NULL, &tv);
- if (retval <= 0) {
- errno = ETIMEDOUT;
- return(-1);
- }
- /* Whew! All that work just to read one character! */
-
- if (read(fd, &ch, sizeof(ch)) <= 0) {
- return(-1);
- }
- /* Save the text, if we can */
- if (buf && nchars < maxline-1) {
- *buf = ch;
- ++buf;
- *buf = EOS;
- ++nchars;
- }
-#if 0
- fprintf(stderr, "%c", ch);
-#endif
-
- /* See how this character matches our expect strings */
-
- for (this=toklist; this->string; ++this) {
-
- if (ch == this->string[this->matchto]) {
-
- /* It matches the current token */
-
- ++this->matchto;
- if (this->string[this->matchto] == EOS){
- /* Hallelujah! We matched */
- return(this->toktype);
- }
- }else{
-
- /* It doesn't appear to match this token */
-
- int curlen;
- int nomatch=1;
- /*
- * If we already had a match (matchto is
- * greater than zero), we look for a match
- * of the tail of the pattern matched so far
- * (with the current character) against the
- * head of the pattern.
- */
-
- /*
- * This is to make the string "aab" match
- * the pattern "ab" correctly
- * Painful, but nice to do it right.
- */
-
- for (curlen = (this->matchto)
- ; nomatch && curlen >= 0
- ; --curlen) {
- const char * tail;
- tail=(this->string)
- + this->matchto
- - curlen;
-
- if (strncmp(this->string, tail
- , curlen) == 0
- && this->string[curlen] == ch) {
-
- if (this->string[curlen+1]==EOS){
- /* We matched! */
- /* (can't happen?) */
- return(this->toktype);
- }
- this->matchto = curlen+1;
- nomatch=0;
- }
- }
- if (nomatch) {
- this->matchto = 0;
- }
- }
- }
- }
- errno = ETIMEDOUT;
- return(-1);
-}
-
-/**
- * Start a process with its stdin and stdout redirected to pipes
- * so the parent process can talk to it.
- *
- * @param cmd Command line to run.
- * @param readfd Filled with a pipe to the the output of the
- * new child.
- * @param writefd Filled with a pipe to the input of the new
- * child.
- * @param redir_err 0, 1 = stderr, 2 = setsid, 3 = both
- * @return -1 on failure (with errno set appropriately) or
- * or the PID of the new child process.
- */
-int
-StartProcess(const char * cmd, int * readfd, int * writefd, int flags)
-{
- pid_t pid;
- int wrpipe[2]; /* The pipe the parent process writes to */
- /* (which the child process reads from) */
- int rdpipe[2]; /* The pipe the parent process reads from */
- /* (which the child process writes to) */
-
- if (pipe(wrpipe) < 0) {
- perror("cannot create pipe\n");
- return(-1);
- }
- if (pipe(rdpipe) < 0) {
- perror("cannot create pipe\n");
- close(wrpipe[0]);
- close(wrpipe[1]);
- return(-1);
- }
- switch(pid=fork()) {
- case -1:
- perror("cannot StartProcess cmd");
- close(rdpipe[0]);
- close(rdpipe[1]);
- close(wrpipe[0]);
- close(wrpipe[1]);
- return(-1);
-
- case 0:
- /* We are the child */
- /* Redirect stdin */
- if (wrpipe[0] != 0) {
- close(0);
- if(dup2(wrpipe[0], 0) < 0) {
- syslog(LOG_CRIT,
- "StartProcess: dup2(%d,0) failed: %s\n",
- wrpipe[0],
- strerror(errno));
- exit(1);
- }
- close(wrpipe[0]);
- }
- close(wrpipe[1]);
-
- /* Redirect stdout */
- if (rdpipe[1] != 1) {
- close(1);
- if(dup2(rdpipe[1], 1) < 0) {
- syslog(LOG_CRIT,
- "StartProcess: dup2(%d,1) failed: %s\n",
- rdpipe[1],
- strerror(errno));
- exit(1);
- }
- close(rdpipe[1]);
- }
- close(rdpipe[0]);
-
- if (flags & EXP_STDERR) {
- /* Redirect stderr */
- close(2);
- if(dup2(1, 2) < 0) {
- syslog(LOG_CRIT,
- "StartProcess: dup2(1,2) failed: %s\n",
- strerror(errno));
- exit(1);
- }
- }
-
- if (flags & EXP_NOCTTY)
- setsid();
- close_all_files(); /* Workaround telnet bugs */
-#if defined(SCHED_OTHER)
- {
- /*
- * Try and (re)set our scheduling to "normal"
- * Sometimes our callers run in soft
- * real-time mode. The program we exec might
- * not be very well behaved - this is bad for
- * operation in high-priority (soft real-time)
- * mode. In particular, telnet is prone to
- * going into infinite loops when killed.
- */
- struct sched_param sp;
- memset(&sp, 0, sizeof(sp));
- sp.sched_priority = 0;
- sched_setscheduler(0, SCHED_OTHER, &sp);
- }
-#endif
- execlp("/bin/bash", "bash", "-c", cmd, NULL);
- perror("cannot exec shell!");
- exit(1);
-
- default: /* We are the parent */
- *readfd = rdpipe[0];
- close(rdpipe[1]);
- *writefd = wrpipe[1];
- close(wrpipe[0]);
- return(pid);
- }
- /*NOTREACHED*/
- return(-1);
-}
-
-/**
- * Close all file descriptors in a child process.
- *
- * Open fd's are inherited across exec unless they are
- * marked close on exec, which must be done explicitly
- * with fcntl(). While this should not affect the operation of
- * telnet, it was found that in some cases it did. Its easier to
- * just fix it this way than to fix telnet.
- */
-void
-close_all_files (void)
-{
- register int i, fd_table_size;
-
- fd_table_size = getdtablesize ();
- if (fd_table_size > 256)/* clamp to a reasonable value */
- fd_table_size = 256;
-
- for (i = 3; i < fd_table_size; i++)
- close (i);
-}
diff --git a/fence/agents/ipmilan/expect.h b/fence/agents/ipmilan/expect.h
deleted file mode 100644
index 41d398a..0000000
--- a/fence/agents/ipmilan/expect.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/** @file
- * Header for expect.c.
- *
- * Expect simple tokens. Simple expect infrastructure for STONITH API
- *
- */
-
-#ifndef __EXPECT_H
-# define __EXPECT_H
-/*
- * If we find any of the given tokens in the input stream,
- * we return it's "toktype", so we can tell which one was
- * found.
- *
- */
-
-/**
- * A token we pass to ExpectToken()
- */
-struct Etoken {
- const char * string; /**< The token to look for */
- int toktype; /**< The type to return on match */
- int matchto; /**< Modified during matches */
-};
-
-int ExpectToken(int fd
-, struct Etoken * toklist /* List of tokens to match against */
- /* Final token has NULL string */
-, int to_secs /* Timeout value in seconds */
-, char * buf /* If non-NULL, then all the text
- * matched/skipped over by this match */
-, int maxline); /* Size of 'buf' area in bytes */
-
-
-/*
- * A handy little routine. It runs the given process
- * with it's standard output redirected into our *readfd, and
- * its standard input redirected from our *writefd
- *
- * Doing this with all the pipes, etc. required for doing this
- * is harder than it sounds :-)
- */
-
-int StartProcess(const char * cmd, int* readfd, int* writefd, int redir_err);
-
-#define EXP_STDERR 1
-#define EXP_NOCTTY 2
-
-#ifndef EOS
-# define EOS '\0'
-#endif
-#endif /*__EXPECT_H*/
diff --git a/fence/agents/ipmilan/ipmilan.c b/fence/agents/ipmilan/ipmilan.c
deleted file mode 100644
index 83029e3..0000000
--- a/fence/agents/ipmilan/ipmilan.c
+++ /dev/null
@@ -1,1279 +0,0 @@
-/** @file
- * clumanager 1.2.x linux-cluster fence and/or GFS fence
- * module for Intel/Bull/Dell Tiger4 machines via IPMI over lan.
- * (Probably works with anything ipmitool can control, though.)
- *
- * Note: REQUIRES ipmitool to operate. On certain machines, the hardware
- * manufacturer provides this tool for you. Otherwise, check:
- *
- * http://ipmitool.sourceforge.net
- *
- */
-
-#include "clusterautoconfig.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <signal.h>
-#include <string.h>
-#include <errno.h>
-#include <limits.h>
-#include <sys/wait.h>
-#include <sys/stat.h>
-#include <libintl.h>
-
-/* fenced doesn't use the remote calls */
-#define ST_STATUS 0
-#define ST_POWERON 1
-#define ST_POWEROFF 2
-#define ST_GENERIC_RESET 3
-#define ST_CYCLE 4
-#define ST_DIAG 5
-
-#define DEFAULT_TIMEOUT 20
-#define DEFAULT_POWER_WAIT 2
-
-#define DEFAULT_METHOD "onoff"
-
-/* We should follow FenceAgentsAPI standard*/
-#define ERR_OFF_SUCCESSFUL 0
-#define ERR_OFF_FAIL 1
-
-#define ERR_ON_SUCCESSFUL 0
-#define ERR_ON_FAIL 1
-
-#define ERR_STATUS_ON 0
-#define ERR_STATUS_FAIL 1
-#define ERR_STATUS_OFF 2
-
-#define ERR_OK 0
-
-#define log(lvl, fmt, args...) fprintf(stderr, fmt, ##args)
-#include <libgen.h>
-#include "copyright.cf"
-
-#include "expect.h"
-
-#define IPMIID "IPMI over LAN driver"
-#define NOTIPMI "Destroyed IPMI over LAN driver"
-
-
-#define dbg_printf(i, lvl, fmt, args...) \
-do { \
- if ( (i)->i_verbose >= lvl) { \
- printf(fmt, ##args); \
- fflush(stdout); \
- } \
-} while (0)
-
-
-
-struct ipmi {
- const char *i_id;
- const char *i_ipmitool;
- char *i_host;
- char *i_user;
- char *i_authtype;
- char *i_password;
- char *i_privlvl;
- int i_rdfd;
- int i_wrfd;
- pid_t i_pid;
- int i_config;
- int i_verbose;
- int i_lanplus;
- int i_timeout;
- int i_power_wait;
- int i_cipher;
-};
-
-
-/*
- Supported installation paths
- */
-const char *ipmitool_paths[] = {
- "/usr/local/bull/NSMasterHW/bin/ipmitool",
- "/usr/bin/ipmitool",
- "/usr/sbin/ipmitool",
- "/bin/ipmitool",
- "/sbin/ipmitool",
- "/usr/local/bin/ipmitool",
- "/usr/local/sbin/ipmitool",
- NULL
-};
-
-
-#define ECIPHER 2048
-#define ESTATE (8192*2)
-static struct Etoken power_on_complete[] = {
- {"Password:", EPERM, 0},
- {"Unable to establish LAN", EAGAIN, 0}, /* Retry */
- {"IPMI mutex", EFAULT, 0}, /* Death */
- {"Unsupported cipher suite ID", ECIPHER,0},
- {"read_rakp2_message: no support for", ECIPHER,0},
- {"Up/On", 0, 0},
- {NULL, 0, 0}
-};
-
-static struct Etoken power_off_complete[] = {
- {"Password:", EPERM, 0},
- {"Unable to establish LAN", EAGAIN, 0}, /* Retry */
- {"IPMI mutex", EFAULT, 0}, /* Death */
- {"Unsupported cipher suite ID", ECIPHER,0},
- {"read_rakp2_message: no support for", ECIPHER,0},
- {"Down/Off", 0, 0},
- {NULL, 0, 0}
-};
-
-/** Powercycle operation */
-static struct Etoken power_cycle_complete[] = {
- {"Password:", EPERM, 0},
- {"Unable to establish LAN", EAGAIN, 0}, /* Retry */
- {"IPMI mutex", EFAULT, 0}, /* Death */
- {"Unsupported cipher suite ID", ECIPHER,0},
- {"read_rakp2_message: no support for", ECIPHER,0},
- {"Command not supported in present state", ESTATE, 0},
- {": Cycle", 0, 0},
- {NULL, 0, 0}
-};
-
-#define STATE_OFF 4096
-#define STATE_ON 8192
-static struct Etoken power_status[] = {
- {"Password:", EPERM, 0},
- {"Unable to establish LAN", EAGAIN, 0}, /* Retry */
- {"IPMI mutex", EFAULT, 0}, /* Death */
- {"Unsupported cipher suite ID", ECIPHER,0},
- {"read_rakp2_message: no support for", ECIPHER,0},
- {"Chassis Power is off", STATE_OFF, 0},
- {"Chassis Power is on", STATE_ON, 0},
- {NULL, 0, 0}
-};
-
-/* Structure describing one xml metadata value*/
-struct xml_parameter_s {
- const char *name;
- const char *getopt;
- const int required;
- const char *content_type;
- const char *default_value;
- const char *description;
-};
-
-/* Array of xml metadatas*/
-struct xml_parameter_s xml_parameters[]={
- {"auth","-A",0,"string",NULL,"IPMI Lan Auth type (md5, password, or none)"},
- {"ipaddr","-a",1,"string",NULL,"IPMI Lan IP to talk to"},
- {"passwd","-p",0,"string",NULL,"Password (if required) to control power on IPMI device"},
- {"passwd_script","-S",0,"string",NULL,"Script to retrieve password (if required)"},
- {"lanplus","-P",0,"boolean",NULL,"Use Lanplus to improve security of connection"},
- {"login","-l",0,"string",NULL,"Username/Login (if required) to control power on IPMI device"},
- {"action","-o",0,"string","reboot","Operation to perform. Valid operations: on, off, reboot, status, list, diag, monitor or metadata"},
- {"timeout","-t",0,"string",NULL,"Timeout (sec) for IPMI operation"},
- {"cipher","-C",0,"string",NULL,"Ciphersuite to use (same as ipmitool -C parameter)"},
- {"method","-M",0,"string",DEFAULT_METHOD,"Method to fence (onoff or cycle)"},
- {"power_wait","-T",0,"string","2","Wait X seconds after on/off operation"},
- {"delay","-f",0,"string",NULL,"Wait X seconds before fencing is started"},
- {"privlvl","-L",0,"string",NULL,"Privilege level on IPMI device"},
- {"verbose","-v",0,"boolean",NULL,"Verbose mode"}};
-
-/*
- Search for ipmitool
- */
-static const char *
-ipmitool_path(void)
-{
- char *p;
- int x = 0;
- struct stat sb;
-
- for (x = 0; ipmitool_paths[x]; x++) {
- p = (char *)ipmitool_paths[x];
- if (stat(p, &sb) != 0)
- continue;
-
- if (!S_ISREG(sb.st_mode))
- continue;
-
- /* executable? */
- if ((sb.st_mode & S_IXUSR) == 0)
- continue;
-
- return (const char *)p;
- }
-
- return NULL;
-}
-
-
-/** Prepare string for use in sh style environment. This function take source
- string and prepend/append quote (') to start/end of source string to dest
- string. Any occurence of quote in source string is replaced by '\'' sequence.
- Dest string must be preallocated.
-
- @param dest Destination string
- @param source Source string
- @param max_len Maximum length of data written to dest string (including end 0)
- @return Pointer to start of destination string.
-*/
-static char *str_prepare_for_sh(char *dest,char *source,int max_len) {
- char *dest_p=dest;
- char *max_dest=dest+max_len;
-
- if (dest_p+1>=max_dest) {*dest_p=0;return dest;}
- *dest_p++='\'';
-
- while (*source) {
- if (*source=='\'') {
- if (dest_p+4>=max_dest) {*dest_p=0;return dest;}
-
- memcpy(dest_p,"'\\''",4);dest_p+=4;
- } else {
- if (dest_p+1>=max_dest) {*dest_p=0;return dest;}
-
- *dest_p++=*source;
- }
- source++;
- }
-
- if (dest_p+2>=max_dest) {*dest_p=0;return dest;}
-
- *dest_p++='\'';*dest_p=0;
-
- return dest;
-}
-
-static int
-build_cmd(char *command, size_t cmdlen, struct ipmi *ipmi, int op, int nopass)
-{
- char cmd[2048];
- char arg[2048];
- char tmp[2048];
- int x;
-
- /* Store path */
- if (ipmi->i_lanplus) {
- snprintf(cmd, sizeof(cmd), "%s -I lanplus -H %s",
- ipmi->i_ipmitool,
- str_prepare_for_sh(tmp,ipmi->i_host,sizeof(tmp)));
- } else {
- snprintf(cmd, sizeof(cmd), "%s -I lan -H %s", ipmi->i_ipmitool,
- str_prepare_for_sh(tmp,ipmi->i_host,sizeof(tmp)));
- }
-
- if (ipmi->i_user) {
- snprintf(arg, sizeof(arg), " -U %s", str_prepare_for_sh(tmp,ipmi->i_user,sizeof(tmp)));
- strncat(cmd, arg, sizeof(cmd) - strlen(arg));
- }
-
- if (ipmi->i_authtype) {
- snprintf(arg, sizeof(arg), " -A %s", str_prepare_for_sh(tmp,ipmi->i_authtype,sizeof(tmp)));
- strncat(cmd, arg, sizeof(cmd) - strlen(arg));
- }
-
- if (ipmi->i_privlvl) {
- snprintf(arg, sizeof(arg), " -L %s", str_prepare_for_sh(tmp,ipmi->i_privlvl,sizeof(tmp)));
- strncat(cmd, arg, sizeof(cmd) - strlen(arg));
- }
-
- if (ipmi->i_cipher>=0) {
- snprintf(arg, sizeof(arg), " -C %d", ipmi->i_cipher);
- strncat(cmd, arg, sizeof(cmd) - strlen(arg));
- }
-
- if (ipmi->i_password) {
- if (nopass) {
- snprintf(arg, sizeof(arg), " -P %s", str_prepare_for_sh(tmp,(char *)"[set]",sizeof(tmp)));
- } else {
- snprintf(arg, sizeof(arg), " -P %s", str_prepare_for_sh(tmp,ipmi->i_password,sizeof(tmp)));
- }
- strncat(cmd, arg, sizeof(cmd) - strlen(arg));
- } else {
- snprintf(arg, sizeof(arg), " -P ''");
- strncat(cmd, arg, sizeof(cmd) - strlen(arg));
- }
-
- /* Tack on the -v flags for ipmitool; in most cases, i_verbose
- will be 0 */
- for (x = 0; x < ipmi->i_verbose; x++) {
- snprintf(arg, sizeof(arg), " -v");
- strncat(cmd, arg, sizeof(cmd) - strlen(arg));
- }
-
- switch(op) {
- case ST_POWERON:
- snprintf(arg, sizeof(arg),
- "%s chassis power on", cmd);
- break;
- case ST_POWEROFF:
- snprintf(arg, sizeof(arg),
- "%s chassis power off", cmd);
- break;
- case ST_STATUS:
- snprintf(arg, sizeof(arg),
- "%s chassis power status", cmd);
- break;
- case ST_CYCLE:
- snprintf(arg, sizeof(arg),
- "%s chassis power cycle", cmd);
- break;
- case ST_DIAG:
- snprintf(arg, sizeof(arg),
- "%s chassis power diag", cmd);
- break;
- }
-
- strncpy(command, arg, cmdlen);
- return 0;
-}
-
-
-static int
-ipmi_spawn(struct ipmi *ipmi, const char *cmd, const char *cmd_print)
-{
- if (!ipmi) {
- errno = EINVAL;
- return -1;
- }
- dbg_printf(ipmi, 1, "Spawning: '%s'...\n", cmd_print);
-
- if (ipmi->i_pid != -1) {
- dbg_printf(ipmi, 1, "Can't spawn: PID %d running\n",
- (int)ipmi->i_pid);
- errno = EINPROGRESS;
- return -1;
- }
-
- if ((ipmi->i_pid = StartProcess(cmd, &ipmi->i_rdfd,
- &ipmi->i_wrfd,
- EXP_STDERR|EXP_NOCTTY)) >= 0) {
- dbg_printf(ipmi, 2, "Spawned: '%s' - PID %d\n",
- cmd_print, (int)ipmi->i_pid);
- return 0;
- }
- return -1;
-}
-
-
-static int
-ipmi_reap(struct ipmi *ipmi)
-{
- if (ipmi->i_pid >= 0) {
- dbg_printf(ipmi, 2, "Reaping pid %d\n", ipmi->i_pid);
- kill(ipmi->i_pid, 9);
- waitpid(ipmi->i_pid, NULL, 0);
- }
- ipmi->i_pid = -1;
- if (ipmi->i_rdfd >= 0) {
- close(ipmi->i_rdfd);
- ipmi->i_rdfd = -1;
- }
- if (ipmi->i_wrfd >= 0) {
- close(ipmi->i_wrfd);
- ipmi->i_wrfd = -1;
- }
- return 0;
-}
-
-
-static int
-ipmi_expect(struct ipmi *ipmi, struct Etoken *toklist, int timeout)
-{
- int ret;
- char buf[32768]; /* XX hope this is enough */
-
- dbg_printf(ipmi, 3, "Looking for: \n");
- for (ret = 0; toklist[ret].string; ret++) {
- dbg_printf(ipmi, 3, " '%s', val = %d\n",
- toklist[ret].string,
- toklist[ret].toktype);
- }
-
- ret = ExpectToken(ipmi->i_rdfd, toklist, timeout, buf, sizeof(buf));
- dbg_printf(ipmi, 3, "ExpectToken returned %d\n", ret);
- if (ret == -1) {
- ret = errno;
- dbg_printf(ipmi, 3, "ExpectToken failed. Info returned:\n");
- dbg_printf(ipmi, 3, ">>>>>\n%s\n<<<<<\nError = %d (%s)\n",
- buf,
- ret,
- strerror(ret));
- }
-
- return ret;
-}
-
-
-static int
-ipmi_op(struct ipmi *ipmi, int op, struct Etoken *toklist)
-{
- char cmd[2048];
- char cmd_nopass[2048];
- char *cmd_print = cmd;
- int ret;
-
- build_cmd(cmd, sizeof(cmd), ipmi, op, 0);
- if (ipmi->i_verbose >= 1 && ipmi->i_password) {
- build_cmd(cmd_nopass, sizeof(cmd_nopass),
- ipmi, op, 1);
- cmd_print = cmd_nopass;
- }
-
- if (ipmi_spawn(ipmi, cmd, cmd_print) != 0)
- return -1;
- ret = ipmi_expect(ipmi, toklist, ipmi->i_timeout);
- ipmi_reap(ipmi);
-
- if (ret == EFAULT) {
- log(LOG_CRIT, "ipmilan: ipmitool failed to create "
- "mutex; unable to complete operation\n");
- return ret;
- }
-
- if (ret == ECIPHER) {
- log(LOG_CRIT, "ipmilan: ipmitool failed to operate "
- "with ciphersuite %d; unable to complete operation\n",ipmi->i_cipher);
- return ret;
- }
-
- if (ret == ESTATE) {
- log(LOG_CRIT, "ipmilan: ipmitool failed to complete "
- "command in current state\n");
- return ret;
- }
-
- if (ret == ETIMEDOUT) {
- /*!!! Still couldn't get through?! */
- log(LOG_WARNING,
- "ipmilan: Failed to connect after %d seconds\n",ipmi->i_timeout);
- }
-
- return ret;
-}
-
-
-static int
-ipmi_off(struct ipmi *ipmi)
-{
- int ret, retries = 7;
-
- ret = ipmi_op(ipmi, ST_STATUS, power_status);
- switch(ret) {
- case STATE_ON:
- break;
- case STATE_OFF:
- return 0;
- default:
- return ret;
- }
-
- while (retries>=0) {
- ret = ipmi_op(ipmi, ST_POWEROFF, power_off_complete);
- if (ret != 0)
- return ret;
-
- sleep(ipmi->i_power_wait);
- --retries;
- ret = ipmi_op(ipmi, ST_STATUS, power_status);
-
- switch(ret) {
- case STATE_OFF:
- return 0;
- case EFAULT:
- /* We're done. */
- retries = 0;
- break;
- case STATE_ON:
- default:
- continue;
- }
- }
- log(LOG_WARNING, "ipmilan: Power still on\n");
-
- return ret;
-}
-
-
-static int
-ipmi_on(struct ipmi *ipmi)
-{
- int ret, retries = 7;
-
- ret = ipmi_op(ipmi, ST_STATUS, power_status);
- switch(ret) {
- case STATE_ON:
- return 0;
- case STATE_OFF:
- break;
- default:
- return ret;
- }
-
- while (retries>=0) {
- ret = ipmi_op(ipmi, ST_POWERON, power_on_complete);
- if (ret != 0)
- return ret;
-
- sleep(ipmi->i_power_wait);
- --retries;
- ret = ipmi_op(ipmi, ST_STATUS, power_status);
-
- switch(ret) {
- case STATE_ON:
- return 0;
- case EFAULT:
- /* We're done. */
- retries = 0;
- break;
- case STATE_OFF:
- default:
- continue;
- }
- }
- log(LOG_WARNING, "ipmilan: Power still off\n");
-
- return ret;
-}
-
-static int
-ipmi_cycle(struct ipmi *ipmi)
-{
- int ret;
-
- ret = ipmi_op(ipmi, ST_CYCLE, power_cycle_complete);
-
- return ret;
-}
-
-static int
-ipmi_diag(struct ipmi *ipmi)
-{
- int ret;
-
- ret = ipmi_op(ipmi, ST_DIAG, power_off_complete);
-
- return ret;
-}
-
-
-/**
- Squash all our private data
- */
-static void
-ipmi_destroy(struct ipmi *i)
-{
- ipmi_reap(i);
- if (i->i_user) {
- free(i->i_user);
- i->i_user = NULL;
- }
- if (i->i_password) {
- free(i->i_password);
- i->i_password= NULL;
- }
- if (i->i_host) {
- free(i->i_host);
- i->i_host = NULL;
- }
- if (i->i_privlvl) {
- free(i->i_privlvl);
- i->i_privlvl = NULL;
- }
- i->i_config = 0;
- i->i_id = NOTIPMI;
-}
-
-
-/**
- Multipurpose initializer. Used to either create a new, blank ipmi,
- or update an existing one, or both.
- */
-static struct ipmi *
-ipmi_init(struct ipmi *i, char *host, char *authtype,
- char *user, char *password, int lanplus, int verbose,int timeout,
- int power_wait,
- int cipher, char *privlvl)
-{
- const char *p;
-
- if (!i || !i->i_ipmitool)
- p = ipmitool_path();
- else
- p = i->i_ipmitool;
-
- if (!p) {
- log(LOG_WARNING, "ipmilan: ipmitool not found!\n");
- return NULL;
- }
-
- if (!i)
- i = malloc (sizeof(*i));
- if (!i)
- return NULL;
-
- if (host && strlen(host)) {
- i->i_host = strdup(host);
- if (!i->i_host) {
- free(i);
- return NULL;
- }
- } else
- i->i_host = NULL;
-
- if (password && strlen(password)) {
- i->i_password = strdup(password);
- if (!i->i_password) {
- free(i->i_host);
- free(i);
- return NULL;
- }
- } else
- i->i_password = NULL;
-
- if (authtype && strlen(authtype)) {
- i->i_authtype = strdup(authtype);
- if (!i->i_authtype) {
- free(i->i_host);
- if (i->i_password)
- free(i->i_password);
- free(i);
- return NULL;
- }
- } else
- i->i_authtype = NULL;
-
- if (privlvl && strlen(privlvl)) {
- i->i_privlvl = strdup(privlvl);
- } else
- i->i_privlvl = NULL;
-
- if (user && strlen(user)) {
- i->i_user= strdup(user);
- if (!i->i_user) {
- free(i->i_host);
- if (i->i_authtype)
- free(i->i_authtype);
- if (i->i_password)
- free(i->i_password);
- free(i);
- return NULL;
- }
- } else
- i->i_user = NULL;
- i->i_ipmitool = p;
- i->i_rdfd = -1;
- i->i_wrfd = -1;
- i->i_pid = -1;
- i->i_id = IPMIID;
- i->i_verbose = verbose;
- i->i_lanplus = lanplus;
- i->i_timeout = timeout;
- i->i_power_wait = power_wait;
- i->i_cipher = cipher;
-
- return i;
-}
-
-
-/**
- Remove leading and trailing whitespace from a line of text.
- */
-static int
-cleanup(char *line, size_t linelen)
-{
- char *p;
- size_t x;
-
- /* Remove leading whitespace. */
- p = line;
- for (x = 0; x <= linelen; x++) {
- switch (line[x]) {
- case '\t':
- case ' ':
- break;
- case '\n':
- case '\r':
- return -1;
- default:
- goto eol;
- }
- }
-eol:
- /* Move the remainder down by as many whitespace chars as we
- chewed up */
- if (x)
- memmove(p, &line[x], linelen-x);
-
- /* Remove trailing whitespace. */
- for (x=0; x <= linelen; x++) {
- switch(line[x]) {
- case '\t':
- case '\r':
- case '\n':
- line[x] = 0;
- case 0:
- /* End of line */
- return 0;
- }
- }
-
- return -1;
-}
-
-
-/**
- Parse args from stdin. Dev + devlen + op + oplen must be valid.
- */
-static int
-get_options_stdin(char *ip, size_t iplen,
- char *authtype, size_t atlen,
- char *passwd, size_t pwlen,
- char *pwd_script, size_t pwd_script_len,
- char *user, size_t userlen,
- char *op, size_t oplen,
- int *lanplus, int *verbose,int *timeout,
- int *power_wait,
- int *cipher, char *method, int methodlen,
- char *delay, size_t delaylen,
- char *privlvl, size_t privlen)
-{
- char in[256];
- int line = 0;
- char *name, *val;
-
- op[0] = 0;
- method[0] = 0;
-
- while (fgets(in, sizeof(in), stdin)) {
- ++line;
-
- if (in[0] == '#')
- continue;
-
- if (cleanup(in, sizeof(in)) == -1)
- continue;
-
- name = in;
- if ((val = strchr(in, '='))) {
- *val = 0;
- ++val;
- }
-
- if (!strcasecmp(name, "agent")) {
- /* Used by fenced? */
- } else if (!strcasecmp(name, "verbose")) {
- *verbose = 1;
- } else if (!strcasecmp(name, "ipaddr")) {
- /* IP address to use. E.g. 10.1.1.2 */
- if (val)
- strncpy(ip, val, iplen);
- else
- ip[0] = 0;
-
- } else if (!strcasecmp(name, "auth")) {
- /* Authtype to use */
- if (val)
- strncpy(authtype, val, atlen);
- else
- authtype[0] = 0;
-
- } else if (!strcasecmp(name, "passwd")) {
- /* password */
- if (val)
- strncpy(passwd, val, pwlen);
- else
- passwd[0] = 0;
-
- } else if (!strcasecmp(name, "passwd_script")) {
- if (val) {
- strncpy(pwd_script, val, pwd_script_len);
- pwd_script[pwd_script_len - 1] = '\0';
- } else
- pwd_script[0] = '\0';
- } else if (!strcasecmp(name, "privlvl")) {
- if (val) {
- strncpy(privlvl, val, privlen);
- } else
- privlvl[0] = '\0';
- } else if (!strcasecmp(name, "user") || !strcasecmp(name, "login")) {
- /* username */
- if (val)
- strncpy(user, val, userlen);
- else
- user[0] = 0;
- } else if (!strcasecmp(name, "lanplus")) {
- (*lanplus) = 1;
- } else if (!strcasecmp(name,"timeout")) {
- if ((!val) || (sscanf(val,"%d",timeout)!=1) || *timeout<1) {
- *timeout=DEFAULT_TIMEOUT;
- }
- } else if (!strcasecmp(name,"power_wait")) {
- if ((!val) || (sscanf(val,"%d",power_wait)!=1) || *power_wait<1) {
- *power_wait=DEFAULT_POWER_WAIT;
- }
- } else if (!strcasecmp(name,"cipher")) {
- if ((!val) || (sscanf(val,"%d",cipher)!=1) || *cipher<0) {
- *cipher=-1;
- }
- } else if (!strcasecmp(name,"method")) {
- if (val)
- strncpy (method, val, methodlen);
- else
- method[0] = 0;
- } else if (!strcasecmp(name, "option") ||
- !strcasecmp(name, "operation") ||
- !strcasecmp(name, "action")) {
- if (val)
- strncpy(op, val, oplen);
- else
- op[0] = 0;
- } else if (!strcasecmp(name,"delay")) {
- if (val)
- strncpy(delay, val, delaylen);
- else
- delay[0] = 0;
- }
- }
-
- return 0;
-}
-
-
-/**
- Print a message to stderr and call exit(1).
- */
-static void
-fail_exit(const char *msg)
-{
- fprintf(stderr, "failed: %s\n", msg);
- exit(1);
-}
-
-static void
-usage_exit(char *pname)
-{
-printf("usage: %s <options>\n", pname);
-printf(" -A <authtype> IPMI Lan Auth type (md5, password, or none)\n");
-printf(" -a <ipaddr> IPMI Lan IP to talk to\n");
-printf(" -i <ipaddr> IPMI Lan IP to talk to (deprecated, use -a)\n");
-printf(" -p <password> Password (if required) to control power on\n"
- " IPMI device\n");
-printf(" -P Use Lanplus to improve security of connection\n");
-printf(" -S <path> Script to retrieve password (if required)\n");
-printf(" -l <login> Username/Login (if required) to control power\n"
- " on IPMI device\n");
-printf(" -L <privlvl> IPMI privilege level. Defaults to ADMINISTRATOR.\n"
- " See ipmitool(1) for more info.\n");
-printf(" -o <op> Operation to perform.\n");
-printf(" Valid operations: on, off, reboot, status,\n");
-printf(" diag, list or monitor\n");
-printf(" -t <timeout> Timeout (sec) for IPMI operation (default %d)\n",DEFAULT_TIMEOUT);
-printf(" -T <timeout> Wait X seconds after on/off operation\n");
-printf(" -f <timeout> Wait X seconds before fencing is started\n");
-printf(" -C <cipher> Ciphersuite to use (same as ipmitool -C parameter)\n");
-printf(" -M <method> Method to fence (onoff or cycle (default %s)\n", DEFAULT_METHOD);
-printf(" -V Print version and exit\n");
-printf(" -v Verbose mode\n\n");
-printf("If no options are specified, the following options will be read\n");
-printf("from standard input (one per line):\n\n");
-printf(" auth=<auth> Same as -A\n");
-printf(" ipaddr=<#> Same as -a\n");
-printf(" passwd=<pass> Same as -p\n");
-printf(" passwd_script=<path> Same as -S\n");
-printf(" lanplus Same as -P\n");
-printf(" login=<login> Same as -l\n");
-printf(" option=<op> Same as -o\n");
-printf(" operation=<op> Same as -o\n");
-printf(" action=<op> Same as -o\n");
-printf(" delay=<seconds> Same as -f\n");
-printf(" timeout=<timeout> Same as -t\n");
-printf(" power_wait=<time> Same as -T\n");
-printf(" cipher=<cipher> Same as -C\n");
-printf(" method=<method> Same as -M\n");
-printf(" privlvl=<privlvl> Same as -L\n");
-printf(" verbose Same as -v\n\n");
- exit(1);
-}
-
-
-/** Print XML metadata of fence agent*/
-static void print_xml_metadata(char *pname) {
- int i;
-
- printf("%s\n","<?xml version=\"1.0\" ?>");
- printf("%s%s%s\n","<resource-agent name=\"",pname,"\" shortdesc=\"Fence agent for IPMI over LAN\">");
- printf("<symlink name=\"fence_ilo3\" shortdesc=\"Fence agent for HP iLO3\"/>\n");
- printf("<symlink name=\"fence_ilo4\" shortdesc=\"Fence agent for HP iLO4\"/>\n");
- printf("<symlink name=\"fence_idrac\" shortdesc=\"Fence agent for Dell iDRAC\"/>\n");
- printf("<symlink name=\"fence_imm\" shortdesc=\"Fence agent for IBM Integrated Management Module\"/>\n");
- printf("<longdesc>\n");
- printf("fence_ipmilan is an I/O Fencing agent which can be used with "
- "machines controlled by IPMI. This agent calls support software "
- "using ipmitool (http://ipmitool.sf.net/).\n\n"
- "To use fence_ipmilan with HP iLO 3 or HP iLO 4 you have to enable lanplus "
- "option (lanplus / -P) and increase wait after operation to "
- "4 seconds (power_wait=4 / -T 4)");
- printf("</longdesc>\n");
- printf("<vendor-url>http://www.intel.com</vendor-url>\n");
- printf("%s\n","<parameters>");
-
- for (i=0;i<(sizeof(xml_parameters)/sizeof(struct xml_parameter_s));i++) {
- printf("\t<parameter name=\"%s\" unique=\"0\" required=\"%d\">\n",xml_parameters[i].name, xml_parameters[i].required);
-
- printf("\t\t<getopt mixed=\"%s\" />\n",xml_parameters[i].getopt);
- if (xml_parameters[i].default_value == NULL) {
- printf("\t\t<content type=\"%s\" />\n",xml_parameters[i].content_type);
- } else {
- printf("\t\t<content type=\"%s\" default=\"%s\"/>\n", \
- xml_parameters[i].content_type, \
- xml_parameters[i].default_value );
- }
-
- printf("\t\t<shortdesc lang=\"en\">");
- printf("%s",xml_parameters[i].description);
- printf("</shortdesc>\n");
- printf("\t</parameter>\n");
- }
- printf("%s\n","</parameters>");
- printf("%s\n","<actions>");
- printf("\t<action name=\"%s\" />\n", "on");
- printf("\t<action name=\"%s\" />\n", "off");
- printf("\t<action name=\"%s\" />\n", "reboot");
- printf("\t<action name=\"%s\" />\n", "status");
- printf("\t<action name=\"%s\" />\n", "diag");
- printf("\t<action name=\"%s\" />\n", "list");
- printf("\t<action name=\"%s\" />\n", "monitor");
- printf("\t<action name=\"%s\" />\n", "metadata");
- printf("%s\n","</actions>");
- printf("%s\n","</resource-agent>");
-}
-
-int
-main(int argc, char **argv)
-{
- extern char *optarg;
- int opt, ret = -1;
- char authtype[64];
- char ip[64];
- char passwd[64];
- char user[64];
- char op[64];
- char privlvl[64];
- char method[64];
- char delay[64];
- char pwd_script[PATH_MAX] = { 0, };
- int lanplus=0;
- int verbose=0;
- char *pname = basename(argv[0]);
- struct ipmi *i;
- int timeout=DEFAULT_TIMEOUT;
- int down_sleep=DEFAULT_POWER_WAIT;
- int cipher=-1;
- int print_final_status=1;
- int translated_ret = -1;
- char *filename;
-
- memset(ip, 0, sizeof(ip));
- memset(authtype, 0, sizeof(authtype));
- memset(passwd, 0, sizeof(passwd));
- memset(user, 0, sizeof(user));
- memset(op, 0, sizeof(op));
- memset(privlvl, 0, sizeof(privlvl));
- memset(method, 0, sizeof(method));
- memset(delay, 0, sizeof(delay));
-
- if (!strcmp(pname, "fence_ilo3")) {
- lanplus = 1;
- down_sleep = 4;
- strncpy(method, "cycle\0", 6);
- } else if (!strcmp(pname, "fence_ilo4")) {
- lanplus = 1;
- }
-
- if (argc > 1) {
- /*
- Parse command line options if any were specified
- */
- while ((opt = getopt(argc, argv, "A:a:i:l:p:S:Po:vV?hHt:T:C:M:f:L:")) != EOF) {
- switch(opt) {
- case 'A':
- /* Auth type */
- strncpy(authtype, optarg, sizeof(authtype));
- authtype[sizeof(authtype)-1] = 0;
- break;
- case 'L':
- /* Privilege level - ipmitool defaults
- * to ADMINISTRATOR if nothing is given
- */
- strncpy(privlvl, optarg, sizeof(privlvl));
- privlvl[sizeof(privlvl)-1] = 0;
- break;
- case 'a':
- case 'i':
- /* IP address */
- strncpy(ip, optarg, sizeof(ip));
- ip[sizeof(ip)-1] = 0;
- break;
- case 'l':
- /* user / login */
- strncpy(user, optarg, sizeof(user));
- user[sizeof(user)-1] = 0;
- break;
- case 'p':
- /* password */
- strncpy(passwd, optarg, sizeof(passwd));
- passwd[sizeof(passwd)-1] = 0;
- break;
- case 'P':
- lanplus = 1;
- break;
- case 'S':
- strncpy(pwd_script, optarg, sizeof(pwd_script));
- pwd_script[sizeof(pwd_script)-1] = 0;
- break;
- case 'o':
- /* Operation */
- strncpy(op, optarg, sizeof(op));
- op[sizeof(op)-1] = 0;
- break;
- case 'f':
- /* Delay */
- strncpy(delay, optarg, sizeof(delay));
- delay[sizeof(delay)-1] = 0;
- break;
- case 't':
- /* Timeout */
- if ((sscanf(optarg,"%d",&timeout)!=1) || timeout<1) {
- fail_exit("Timeout option expects positive number parameter");
- }
- break;
- case 'T':
- /* Shutdown Sleep Time */
- if ((sscanf(optarg,"%d",&down_sleep)!=1) || down_sleep<1) {
- fail_exit("Shutdown time option expects positive number parameter");
- }
- break;
- case 'C':
- /* Ciphersuite */
- if ((sscanf(optarg,"%d",&cipher)!=1) || cipher<0) {
- fail_exit("Ciphersuite option expects positive number parameter");
- }
- break;
- case 'M':
- /* Reboot method */
- strncpy(method, optarg, sizeof(method));
- method[sizeof(method)-1] = 0;
- break;
- case 'v':
- verbose++;
- break;
- case 'V':
- printf("%s %s (built %s %s)\n", pname,
- VERSION,
- __DATE__, __TIME__);
- printf("%s\n",
- REDHAT_COPYRIGHT);
- return 0;
- default:
- usage_exit(pname);
- }
- }
- } else {
- /*
- No command line args? Get stuff from stdin
- */
- if (get_options_stdin(ip, sizeof(ip),
- authtype, sizeof(authtype),
- passwd, sizeof(passwd),
- pwd_script, sizeof(pwd_script),
- user, sizeof(user),
- op, sizeof(op), &lanplus, &verbose,&timeout,
- &down_sleep,
- &cipher, method, sizeof(method),
- delay, sizeof(delay),
- privlvl, sizeof(privlvl)) != 0)
- return 1;
- }
-
- if (pwd_script[0] != '\0') {
- char pwd_buf[1024];
- FILE *fp;
- fp = popen(pwd_script, "r");
- if (fp != NULL) {
- ssize_t len = fread(pwd_buf, 1, sizeof(pwd_buf), fp);
- pwd_buf[sizeof(pwd_buf)-1] = 0;
- if (len > 0) {
- char *p;
- p = strchr(pwd_buf, '\n');
- if (p != NULL)
- *p = '\0';
- p = strchr(pwd_buf, '\r');
- if (p != NULL)
- *p = '\0';
- strncpy(passwd, pwd_buf, sizeof(passwd));
- passwd[sizeof(passwd) - 1] = '\0';
- }
- pclose(fp);
- }
- }
-
- if (!strcasecmp(op, "metadata")) {
- print_xml_metadata(pname);
- translated_ret = ERR_OK;
- ret=0;
- print_final_status=0;
- goto metaout;
- }
-
- /*
- Validate the operating parameters
- */
- if (strlen(ip) == 0)
- fail_exit("no IP address specified");
-
- if (!strlen(op))
- snprintf(op,sizeof(op), "reboot");
-
- if (!strlen(method))
- snprintf(method, sizeof(method), "onoff");
-
- if (strcasecmp(op, "off") && strcasecmp(op, "on") &&
- strcasecmp(op, "status") && strcasecmp(op, "reboot") &&
- strcasecmp(op, "monitor") && strcasecmp(op, "list") &&
- strcasecmp(op, "metadata") && strcasecmp(op, "diag")) {
- fail_exit("operation must be 'on', 'off', 'status', "
- "'reboot', 'diag', 'list', 'monitor' or 'metadata'");
- }
-
- if (strlen(authtype) &&
- strcasecmp(authtype, "md5") &&
- strcasecmp(authtype, "password") &&
- strcasecmp(authtype, "none")) {
- fail_exit("authtype, if included, must be 'md5', 'password',"
- " 'none'.");
- }
-
- if (strcasecmp(method, "onoff") &&
- strcasecmp(method, "cycle")) {
- fail_exit("method, if included, must be 'onoff', 'cycle'.");
- }
-
- if (!strcasecmp(method, "cycle") &&
- (!strcasecmp(op, "on") || !strcasecmp(op, "off"))) {
- fail_exit("cycle method supports only 'reboot' operation (not 'on' or 'off').");
- }
-
- /* Delay fencing if requested */
- if (delay[0] != '\0') {
- if (!strcasecmp(op, "reboot") || !strcasecmp(op, "off")) {
- sleep(atoi(delay));
- }
- }
-
- /* Ok, set up the IPMI struct */
- i = ipmi_init(NULL, ip, authtype, user, passwd, lanplus, verbose, timeout, down_sleep, cipher, privlvl);
- if (!i)
- fail_exit("Failed to initialize\n");
-
- /*
- Perform the requested operation
- */
- if (!strcasecmp(op, "reboot")) {
- printf("Rebooting machine @ IPMI:%s...", ip);
- fflush(stdout);
- if (!strcasecmp(method, "cycle")) {
- ret = ipmi_op(i, ST_STATUS, power_status);
-
- if (ret == STATE_OFF) {
- /* State is off -> use onoff method because cycle is not able to turn on*/
- snprintf(method, sizeof(method), "onoff");
- }
- }
-
- if (!strcasecmp(method, "cycle")) {
- ret = ipmi_cycle(i);
- translated_ret = (ret==0?ERR_OFF_SUCCESSFUL:ERR_OFF_FAIL);
- } else {
- /* Original onoff method */
- ret = ipmi_off(i);
- translated_ret = (ret==0?ERR_OFF_SUCCESSFUL:ERR_OFF_FAIL);
- if (ret != 0) {
- goto out;
- }
- ret = ipmi_on(i);
- }
- } else if (!strcasecmp(op, "on")) {
- printf("Powering on machine @ IPMI:%s...", ip);
- fflush(stdout);
- ret = ipmi_on(i);
- translated_ret = (ret==0?ERR_ON_SUCCESSFUL:ERR_ON_FAIL);
- } else if (!strcasecmp(op, "off")) {
- printf("Powering off machine @ IPMI:%s...", ip);
- fflush(stdout);
- ret = ipmi_off(i);
- translated_ret = (ret==0?ERR_ON_SUCCESSFUL:ERR_ON_FAIL);
- } else if (!strcasecmp(op, "status") || !strcasecmp(op, "monitor")) {
- printf("Getting status of IPMI:%s...",ip);
- fflush(stdout);
- ret = ipmi_op(i, ST_STATUS, power_status);
- switch(ret) {
- case STATE_ON:
- if (!strcasecmp(op, "status"))
- printf("Chassis power = On\n");
- translated_ret = ERR_STATUS_ON;
- ret = 0;
- break;
- case STATE_OFF:
- if (!strcasecmp(op, "status"))
- printf("Chassis power = Off\n");
- translated_ret = ERR_STATUS_OFF;
- ret = 0;
- break;
- default:
- if (!strcasecmp(op, "status"))
- printf("Chassis power = Unknown\n");
- translated_ret = ERR_STATUS_FAIL;
- ret = 1;
- break;
- }
- } else if (!strcasecmp(op, "list")) {
- printf("%s\n","N/A");
- ret=0;
- translated_ret = ERR_OK;
- print_final_status=0;
- } else if (!strcasecmp(op, "diag")) {
- printf("Pulsing diagnostic interrupt to machine @ IPMI:%s...", ip);
- fflush(stdout);
- ret = ipmi_diag(i);
- translated_ret = (ret==0?ERR_ON_SUCCESSFUL:ERR_ON_FAIL);
- ret = 0;
- }
-
-
-out:
- ipmi_destroy(i);
- free(i);
-
-metaout:
- if (print_final_status) {
- if (ret == 0)
- printf("Done\n");
- else
- printf("Failed\n");
- }
-
- if (!strcasecmp(op, "monitor"))
- translated_ret = ret;
-
- if (!strcasecmp(op, "diag")) {
- /** .. but when a system receive the DIAG signal , it
- ** switches to a kdump kernel, but the machine is always
- ** "on" during the dump phase. It only become temporarily
- ** "off" at the end of the dump just before rebooting.
- **/
- translated_ret = 0;
- }
-
- return translated_ret;
-}
10 years, 4 months
fence-agents: master - fence_ipmilan: Adapt Makefile from C to Python fence agent
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=625c42...
Commit: 625c42b5b8e16171f7efc65a4e88b3be92e04f18
Parent: 3945eaad8141a333c88e956a2a5e8edc1b396221
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Jan 6 17:03:38 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Jan 6 17:03:38 2014 +0100
fence_ipmilan: Adapt Makefile from C to Python fence agent
---
fence/agents/ipmilan/Makefile.am | 11 +++++------
1 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/fence/agents/ipmilan/Makefile.am b/fence/agents/ipmilan/Makefile.am
index 9e71858..be3509e 100644
--- a/fence/agents/ipmilan/Makefile.am
+++ b/fence/agents/ipmilan/Makefile.am
@@ -4,20 +4,19 @@ TARGET = fence_ipmilan
SYMTARGET = fence_ilo3 fence_ilo4 fence_imm fence_idrac
-sbin_PROGRAMS = $(TARGET)
+SRC = $(TARGET).py
-sbin_SCRIPTS = $(SYMTARGET)
+EXTRA_DIST = $(SRC)
-noinst_HEADERS = expect.h
-
-fence_ipmilan_SOURCES = expect.c ipmilan.c
+sbin_SCRIPTS = $(TARGET) $(SYMTARGET)
man_MANS = $(TARGET).8 $(SYMTARGET:%=%.8)
$(SYMTARGET): $(TARGET)
cp $^ $@
-include $(top_srcdir)/make/fencemanc.mk
+include $(top_srcdir)/make/fencebuild.mk
+include $(top_srcdir)/make/fenceman.mk
clean-local: clean-man
rm -f $(TARGET) $(SYMTARGET)
10 years, 4 months
fence-agents: master - fencing: Fix replacement of path to ipmitool/amttool
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=3945ea...
Commit: 3945eaad8141a333c88e956a2a5e8edc1b396221
Parent: a99d3b565e0c72d0ac8ae2b0f5cf6569a47cd0ae
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Jan 6 17:02:38 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Jan 6 17:02:38 2014 +0100
fencing: Fix replacement of path to ipmitool/amttool
---
fence/agents/ipmilan/fence_ipmilan.py | 2 +-
make/fencebuild.mk | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/fence/agents/ipmilan/fence_ipmilan.py b/fence/agents/ipmilan/fence_ipmilan.py
index b4e29fc..ece5d97 100644
--- a/fence/agents/ipmilan/fence_ipmilan.py
+++ b/fence/agents/ipmilan/fence_ipmilan.py
@@ -156,7 +156,7 @@ def define_new_opts():
"help" : "--ipmitool-path=[path] Path to ipmitool binary",
"required" : "0",
"shortdesc" : "Path to ipmitool binary",
- "default" : "#@IPMITOOL_PATH@",
+ "default" : "@IPMITOOL_PATH@",
"order": 200
}
diff --git a/make/fencebuild.mk b/make/fencebuild.mk
index 5cbe3bd..14e33b7 100644
--- a/make/fencebuild.mk
+++ b/make/fencebuild.mk
@@ -9,8 +9,8 @@ $(TARGET): $(SRC)
-e 's#@''LOGDIR@#${LOGDIR}#g' \
-e 's#@''SBINDIR@#${sbindir}#g' \
-e 's#@''LIBEXECDIR@#${libexecdir}#g' \
- -e 's#@''IPMITOOL_PATH#${IPMITOOL_PATH}#g' \
- -e 's#@''AMTTOOL_PATH#${AMTTOOL_PATH}#g' \
+ -e 's#@''IPMITOOL_PATH@#${IPMITOOL_PATH}#g' \
+ -e 's#@''AMTTOOL_PATH@#${AMTTOOL_PATH}#g' \
> $@
if [ 0 -eq `echo "$(SRC)" | grep fence_ &> /dev/null; echo $$?` ]; then \
10 years, 4 months
fence-agents: master - fence_ipmilan: port to fencing library
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=a99d3b...
Commit: a99d3b565e0c72d0ac8ae2b0f5cf6569a47cd0ae
Parent: e4dfd762a9c92231c002e4739752bc8baf738c2b
Author: Ondrej Mular <omular(a)redhat.com>
AuthorDate: Mon Dec 30 11:24:51 2013 -0500
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Jan 6 16:40:49 2014 +0100
fence_ipmilan: port to fencing library
Port of fence_ipmilan to fencing library.
---
fence/agents/ipmilan/fence_ipmilan.py | 199 +++++++++++++++++++++++++++++++++
1 files changed, 199 insertions(+), 0 deletions(-)
diff --git a/fence/agents/ipmilan/fence_ipmilan.py b/fence/agents/ipmilan/fence_ipmilan.py
new file mode 100644
index 0000000..b4e29fc
--- /dev/null
+++ b/fence/agents/ipmilan/fence_ipmilan.py
@@ -0,0 +1,199 @@
+#!/usr/bin/python
+
+import sys, shlex, stat, subprocess, re, os
+from pipes import quote
+sys.path.append("@FENCEAGENTSLIBDIR@")
+from fencing import *
+
+#BEGIN_VERSION_GENERATION
+RELEASE_VERSION=""
+REDHAT_COPYRIGHT=""
+BUILD_DATE=""
+#END_VERSION_GENERATION
+
+def get_power_status(_, options):
+
+ cmd = create_command(options, "status")
+
+ if options["log"] >= LOG_MODE_VERBOSE:
+ options["debug_fh"].write("executing: " + cmd + "\n")
+
+ try:
+ process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ except OSError:
+ fail_usage("Ipmitool not found or not accessible")
+
+ process.wait()
+
+ out = process.communicate()
+ process.stdout.close()
+ options["debug_fh"].write(out)
+
+ match = re.search('[Cc]hassis [Pp]ower is [\\s]*([a-zA-Z]{2,3})', str(out))
+ status = match.group(1) if match else None
+
+ return status
+
+def set_power_status(_, options):
+
+ cmd = create_command(options, options["--action"])
+
+ if options["log"] >= LOG_MODE_VERBOSE:
+ options["debug_fh"].write("executing: " + cmd + "\n")
+
+ try:
+ process = subprocess.Popen(shlex.split(cmd), stdout=options["debug_fh"], stderr=options["debug_fh"])
+ except OSError:
+ fail_usage("Ipmitool not found or not accessible")
+
+ process.wait()
+
+ return
+
+def reboot_cycle(_, options):
+ cmd = create_command(options, "cycle")
+
+ if options["log"] >= LOG_MODE_VERBOSE:
+ options["debug_fh"].write("executing: " + cmd + "\n")
+
+ try:
+ process = subprocess.Popen(shlex.split(cmd), stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+ except OSError:
+ fail_usage("Ipmitool not found or not accessible")
+
+ process.wait()
+
+ out = process.communicate()
+ process.stdout.close()
+ options["debug_fh"].write(out)
+
+ return bool(re.search('chassis power control: cycle', str(out).lower()))
+
+def create_command(options, action):
+ cmd = options["--ipmitool-path"]
+
+ # --lanplus / -L
+ if options.has_key("--lanplus") and options["--lanplus"] in ["", "1"]:
+ cmd += " -I lanplus"
+ else:
+ cmd += " -I lan"
+ # --ip / -a
+ cmd += " -H " + options["--ip"]
+
+ # --username / -l
+ if options.has_key("--username") and len(options["--username"]) != 0:
+ cmd += " -U " + quote(options["--username"])
+
+ # --auth / -A
+ if options.has_key("--auth"):
+ cmd += " -A " + options["--auth"]
+
+ # --password / -p
+ if options.has_key("--password"):
+ cmd += " -P " + quote(options["--password"])
+
+ # --cipher / -C
+ cmd += " -C " + options["--cipher"]
+
+ # --port / -n
+ if options.has_key("--ipport"):
+ cmd += " -p " + options["--ipport"]
+
+ if options.has_key("--privlvl"):
+ cmd += " -L " + options["--privlvl"]
+
+ # --action / -o
+ cmd += " chassis power " + action
+
+ # --use-sudo / -d
+ if options.has_key("--use-sudo"):
+ cmd = SUDO_PATH + " " + cmd
+
+ return cmd
+
+def define_new_opts():
+ all_opt["lanplus"] = {
+ "getopt" : "L",
+ "longopt" : "lanplus",
+ "help" : "-L, --lanplus Use Lanplus to improve security of connection",
+ "required" : "0",
+ "default" : "0",
+ "shortdesc" : "Use Lanplus to improve security of connection",
+ "order": 1
+ }
+ all_opt["auth"] = {
+ "getopt" : "A:",
+ "longopt" : "auth",
+ "help" : "-A, --auth=[auth] IPMI Lan Auth type (md5|password|none)",
+ "required" : "0",
+ "shortdesc" : "IPMI Lan Auth type.",
+ "default" : "none",
+ "choices" : ["md5", "password", "none"],
+ "order": 1
+ }
+ all_opt["cipher"] = {
+ "getopt" : "C:",
+ "longopt" : "cipher",
+ "help" : "-C, --cipher=[cipher] Ciphersuite to use (same as ipmitool -C parameter)",
+ "required" : "0",
+ "shortdesc" : "Ciphersuite to use (same as ipmitool -C parameter)",
+ "default" : "0",
+ "order": 1
+ }
+ all_opt["privlvl"] = {
+ "getopt" : "P:",
+ "longopt" : "privlvl",
+ "help" : "-P, --privlvl=[level] Privilege level on IPMI device (callback|user|operator|administrator)",
+ "required" : "0",
+ "shortdesc" : "Privilege level on IPMI device",
+ "default" : "administrator",
+ "choices" : ["callback", "user", "operator", "administrator"],
+ "order": 1
+ }
+ all_opt["ipmitool_path"] = {
+ "getopt" : "i:",
+ "longopt" : "ipmitool-path",
+ "help" : "--ipmitool-path=[path] Path to ipmitool binary",
+ "required" : "0",
+ "shortdesc" : "Path to ipmitool binary",
+ "default" : "#@IPMITOOL_PATH@",
+ "order": 200
+ }
+
+def main():
+
+ atexit.register(atexit_handler)
+
+ device_opt = ["ipaddr", "login", "no_login", "no_password", "passwd",
+ "lanplus", "auth", "cipher", "privlvl", "sudo", "ipmitool_path", "method"]
+ define_new_opts()
+
+ if os.path.basename(sys.argv[0]) == "fence_ilo3":
+ all_opt["power_wait"]["default"] = "4"
+ all_opt["method"]["default"] = "cycle"
+ all_opt["lanplus"]["default"] = "1"
+ elif os.path.basename(sys.argv[0]) == "fence_ilo4":
+ all_opt["lanplus"]["default"] = "1"
+
+ all_opt["ipport"]["default"] = "623"
+
+ options = check_input(device_opt, process_input(device_opt))
+
+ docs = { }
+ docs["shortdesc"] = "Fence agent for IPMI"
+ docs["longdesc"] = "Fence agent for IPMI"
+ docs["vendorurl"] = ""
+ docs["symlink"] = [("fence_ilo3", "Fence agent for HP iLO3"),
+ ("fence_ilo4", "Fence agent for HP iLO4"),
+ ("fence_imm", "Fence agent for IBM Integrated Management Module"),
+ ("fence_idrac", "Fence agent for Dell iDRAC")]
+ show_docs(options, docs)
+
+ if not is_executable(options["--ipmitool-path"]):
+ fail_usage("Ipmitool not found or not accessible")
+
+ result = fence_action(None, options, set_power_status, get_power_status, None, reboot_cycle)
+ sys.exit(result)
+
+if __name__ == "__main__":
+ main()
10 years, 4 months
fence-agents: master - fencing: add function is_executale
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=e4dfd7...
Commit: e4dfd762a9c92231c002e4739752bc8baf738c2b
Parent: 5e1e49d35903417fd974acfb670bc27075c28697
Author: Ondrej Mular <omular(a)redhat.com>
AuthorDate: Mon Dec 30 11:24:46 2013 -0500
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Jan 6 16:37:30 2014 +0100
fencing: add function is_executale
New function is_executable added to fencing library.
Function checks if path is reachable and executable.
Used for example in fence_amt to check path to amttool.
---
fence/agents/lib/fencing.py.py | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index c8b9bda..ad5dd10 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -1,6 +1,6 @@
#!/usr/bin/python
-import sys, getopt, time, os, uuid, pycurl
+import sys, getopt, time, os, uuid, pycurl, stat
import pexpect, re, atexit, syslog
import __main__
@@ -1079,3 +1079,10 @@ def fence_login(options, re_login_string = "(login\s*: )|(Login Name: )|(userna
except pexpect.TIMEOUT:
fail(EC_LOGIN_DENIED)
return conn
+
+def is_executable(path):
+ if os.path.exists(path):
+ stats = os.stat(path)
+ if stat.S_ISREG(stats.st_mode) and os.access(path, os.X_OK):
+ return True
+ return False
10 years, 4 months
fence-agents: master - fence_apc_snmp: Add Tripplite PDU support
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=5e1e49...
Commit: 5e1e49d35903417fd974acfb670bc27075c28697
Parent: cfd1f7490d7958ee25ad5937c9f2072adaa9862e
Author: Bogdan Dobrelya <bogdando(a)mail.ru>
AuthorDate: Tue Dec 24 13:13:53 2013 +0200
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Jan 6 13:57:12 2014 +0100
fence_apc_snmp: Add Tripplite PDU support
Tested with Tripplite PDUMH20HVNET 12.04.0055 - SNMP v1, v2c, v3
Signed-off-by: Bogdan Dobrelya <bogdando(a)mail.ru>
Signed-off-by: Marek 'marx' Grac <mgrac(a)redhat.com>
---
fence/agents/apc_snmp/fence_apc_snmp.py | 28 +++++++++++++++++++++-------
1 files changed, 21 insertions(+), 7 deletions(-)
diff --git a/fence/agents/apc_snmp/fence_apc_snmp.py b/fence/agents/apc_snmp/fence_apc_snmp.py
index f312ebe..da02066 100644
--- a/fence/agents/apc_snmp/fence_apc_snmp.py
+++ b/fence/agents/apc_snmp/fence_apc_snmp.py
@@ -7,6 +7,7 @@
# AF1:v3.5.7 AN1:apc_hw02_rpdu_357.bin MN:AP7900 HR:B2) - SNMP v1 and v3 (noAuthNoPrivacy,authNoPrivacy, authPrivacy)
# - APC Switched Rack PDU (MB:v3.7.0 PF:v2.7.0 PN:apc_hw02_aos_270.bin AF1:v2.7.3 AN1:apc_hw02_rpdu_273.bin
# MN:AP7951 HR:B2) - SNMP v1
+# - Tripplite PDUMH20HVNET 12.04.0055 - SNMP v1, v2c, v3
import sys
sys.path.append("@FENCEAGENTSLIBDIR@")
@@ -24,7 +25,7 @@ BUILD_DATE=""
OID_SYS_OBJECT_ID = '.1.3.6.1.2.1.1.2.0'
### GLOBAL VARIABLES ###
-# Device - see ApcRPDU, ApcMSP, ApcMS
+# Device - see ApcRPDU, ApcMSP, ApcMS, TripplitePDU
device = None
# Port ID
@@ -33,6 +34,18 @@ port_id = None
switch_id = None
# Classes describing Device params
+class TripplitePDU:
+ # Rack PDU
+ status_oid= '.1.3.6.1.4.1.850.10.2.3.5.1.2.1.%d'
+ control_oid= '.1.3.6.1.4.1.850.10.2.3.5.1.4.1.%d'
+ outlet_table_oid='.1.3.6.1.4.1.850.10.2.3.5.1.5'
+ ident_str="Tripplite"
+ state_on=2
+ state_off=1
+ turn_on=2
+ turn_off=1
+ has_switches=False
+
class ApcRPDU:
# Rack PDU
status_oid = '.1.3.6.1.4.1.318.1.1.12.3.5.1.1.4.%d'
@@ -74,8 +87,9 @@ def apc_set_device(conn, options):
global device
agents_dir = {'.1.3.6.1.4.1.318.1.3.4.5':ApcRPDU,
- '.1.3.6.1.4.1.318.1.3.4.4':ApcMSP,
- None:ApcMS}
+ '.1.3.6.1.4.1.318.1.3.4.4':ApcMSP,
+ '.1.3.6.1.4.1.850.1':TripplitePDU,
+ None:ApcMS}
# First resolve type of APC
apc_type = conn.walk(OID_SYS_OBJECT_ID)
@@ -179,11 +193,11 @@ def main():
options["--switch"] = "1"
docs = { }
- docs["shortdesc"] = "Fence agent for APC over SNMP"
+ docs["shortdesc"] = "Fence agent for APC, Tripplite PDU over SNMP"
docs["longdesc"] = "fence_apc_snmp is an I/O Fencing agent \
-which can be used with the APC network power switch. It logs \
-into a device via SNMP and reboots a specified outlet. It supports \
-SNMP v1 and v3 with all combinations of authenticity/privacy settings."
+which can be used with the APC network power switch or Tripplite PDU devices.\
+It logs into a device via SNMP and reboots a specified outlet. It supports \
+SNMP v1, v2c, v3 with all combinations of authenticity/privacy settings."
docs["vendorurl"] = "http://www.apc.com"
show_docs(options, docs)
10 years, 4 months
fence-agents: master - fencing: Do not use public keys when identity-file is not defined
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=cfd1f7...
Commit: cfd1f7490d7958ee25ad5937c9f2072adaa9862e
Parent: 6484b090d44811c4d2d2f59f62444ab44346c200
Author: Marek 'marx' Grac <mgrac(a)redhat.com>
AuthorDate: Mon Jan 6 13:25:43 2014 +0100
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Mon Jan 6 13:30:51 2014 +0100
fencing: Do not use public keys when identity-file is not defined
Previously, fence agent (ssh) tried to use keys before it asks for password. This lead to a situation
when fence agent did not work correctly as it was waiting for 'Password' which did not occur.
---
fence/agents/lib/fencing.py.py | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index a570203..c8b9bda 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -979,7 +979,7 @@ def fence_login(options, re_login_string = "(login\s*: )|(Login Name: )|(userna
syslog.syslog(syslog.LOG_ERR, str(ex))
sys.exit(EC_GENERIC_ERROR)
elif options.has_key("--ssh") and 0 == options.has_key("--identity-file"):
- command = '%s %s %s@%s -p %s' % (SSH_PATH, force_ipvx, options["--username"], options["--ip"], options["--ipport"])
+ command = '%s %s %s@%s -p %s -o PubkeyAuthentication=no' % (SSH_PATH, force_ipvx, options["--username"], options["--ip"], options["--ipport"])
if options.has_key("--ssh-options"):
command += ' ' + options["--ssh-options"]
try:
10 years, 4 months
fence-agents: master - fencing: new option --method
by Marek Grác
Gitweb: http://git.fedorahosted.org/git/?p=fence-agents.git;a=commitdiff;h=6484b0...
Commit: 6484b090d44811c4d2d2f59f62444ab44346c200
Parent: 908fd921599b4e494028f3972a71c99c0aed674f
Author: Ondrej Mular <omular(a)redhat.com>
AuthorDate: Fri Nov 29 11:32:14 2013 -0500
Committer: Marek 'marx' Grac <mgrac(a)redhat.com>
CommitterDate: Thu Dec 19 16:11:01 2013 +0100
fencing: new option --method
Add new option method --method for cycle reboot
---
fence/agents/lib/fencing.py.py | 76 +++++++++++++++++++++++++++++----------
1 files changed, 56 insertions(+), 20 deletions(-)
diff --git a/fence/agents/lib/fencing.py.py b/fence/agents/lib/fencing.py.py
index 2b914f2..a570203 100644
--- a/fence/agents/lib/fencing.py.py
+++ b/fence/agents/lib/fencing.py.py
@@ -342,7 +342,16 @@ all_opt = {
"help" : "--use-sudo Use sudo (without password) when calling 3rd party software",
"required" : "0",
"shortdesc" : "Use sudo (without password) when calling 3rd party sotfware.",
- "order" : 205}
+ "order" : 205},
+ "method" : {
+ "getopt" : "m:",
+ "longopt" : "method",
+ "help" : "-m, --method=[method] Method to fence (onoff|cycle) (Default: onoff)",
+ "required" : "0",
+ "shortdesc" : "Method to fence (onoff|cycle) (Default: onoff)",
+ "default" : "onoff",
+ "choices" : [ "onoff", "cycle" ],
+ "order" : 1}
}
# options which are added automatically if 'key' is encountered ("default" is always added)
@@ -780,6 +789,23 @@ def set_multi_power_fn(tn, options, set_power_fn):
else:
set_power_fn(tn, options)
+def multi_reboot_cycle_fn(tn, options, reboot_cycle_fn):
+ success = False;
+ if options.has_key("--plugs"):
+ for plug in options["--plugs"]:
+ try:
+ options["--uuid"] = str(uuid.UUID(plug))
+ except ValueError:
+ pass
+ except KeyError:
+ pass
+ options["--plug"] = plug
+ plug_status = reboot_cycle_fn(tn, options)
+ if plug_status:
+ success = plug_status
+ else:
+ success = reboot_cycle_fn(tn, options)
+ return success
def show_docs(options, docs = None):
device_opt = options["device_opt"]
@@ -804,7 +830,7 @@ def show_docs(options, docs = None):
print __main__.REDHAT_COPYRIGHT
sys.exit(0)
-def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list = None):
+def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list = None, reboot_cycle_fn = None):
result = 0
try:
@@ -863,28 +889,38 @@ def fence_action(tn, options, set_power_fn, get_power_fn, get_outlet_list = None
else:
fail(EC_WAITING_OFF)
elif options["--action"] == "reboot":
- if status != "off":
- options["--action"] = "off"
- set_multi_power_fn(tn, options, set_power_fn)
- time.sleep(int(options["--power-wait"]))
- if wait_power_status(tn, options, get_power_fn) == 0:
- fail(EC_WAITING_OFF)
- options["--action"] = "on"
-
power_on = False
- try:
+ if options.has_key("--method") and options["--method"].lower() == "cycle":
for _ in range(1, 1 + int(options["--retry-on"])):
- set_multi_power_fn(tn, options, set_power_fn)
- time.sleep(int(options["--power-wait"]))
- if wait_power_status(tn, options, get_power_fn) == 1:
+ if multi_reboot_cycle_fn(tn, options, reboot_cycle_fn):
power_on = True
break
- except Exception, ex:
- # an error occured during power ON phase in reboot
- # fence action was completed succesfully even in that case
- sys.stderr.write(str(ex))
- syslog.syslog(syslog.LOG_NOTICE, str(ex))
- pass
+
+ if not power_on:
+ fail(EC_TIMED_OUT)
+
+ else:
+ if status != "off":
+ options["--action"] = "off"
+ set_multi_power_fn(tn, options, set_power_fn)
+ time.sleep(int(options["--power-wait"]))
+ if wait_power_status(tn, options, get_power_fn) == 0:
+ fail(EC_WAITING_OFF)
+ options["--action"] = "on"
+
+ try:
+ for _ in range(1, 1 + int(options["--retry-on"])):
+ set_multi_power_fn(tn, options, set_power_fn)
+ time.sleep(int(options["--power-wait"]))
+ if wait_power_status(tn, options, get_power_fn) == 1:
+ power_on = True
+ break
+ except Exception, ex:
+ # an error occured during power ON phase in reboot
+ # fence action was completed succesfully even in that case
+ sys.stderr.write(str(ex))
+ syslog.syslog(syslog.LOG_NOTICE, str(ex))
+ pass
if power_on == False:
# this should not fail as node was fenced succesfully
10 years, 4 months