Skip to content

Commit

Permalink
Merge pull request #157 from chu11/redfishpower_setplugs
Browse files Browse the repository at this point in the history
redfishpower: support setplugs configuration
  • Loading branch information
mergify[bot] authored Mar 19, 2024
2 parents a28d07b + 05583dc commit a8908f2
Show file tree
Hide file tree
Showing 6 changed files with 275 additions and 39 deletions.
5 changes: 5 additions & 0 deletions man/redfishpower.8.in
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ Set path and optional post data to turn on plug.
.I "setoffpath <path> [postdata]"
Set path and optional post data to turn off plug.
.TP
.I "setplugs plugnames hostindices"
Associate a plug name with one of the hostnames specified on the
command line, referred to by its zero origin index Can be called
multiple times to configure all possible plugs.
.TP
.I "settimeout <seconds>"
Set command timeout in seconds.
.TP
Expand Down
114 changes: 114 additions & 0 deletions src/redfishpower/redfishpower.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@

static hostlist_t hosts = NULL;
static plugs_t *plugs = NULL;
/* flag to indicate if we wiped initial plugs */
static int initial_plugs_setup = 0;
static char *header = NULL;
static struct curl_slist *header_list = NULL;
static int verbose = 0;
Expand Down Expand Up @@ -155,6 +157,7 @@ void help(void)
printf(" setstatpath path\n");
printf(" setonpath path [postdata]\n");
printf(" setoffpath path [postdata]\n");
printf(" setplugs plugnames hostindices\n");
printf(" settimeout seconds\n");
printf(" stat [plugs]\n");
printf(" on [plugs]\n");
Expand Down Expand Up @@ -754,6 +757,113 @@ static void setpowerpath(char **av, char **path, char **postdata)
}
}

static void remove_initial_plugs(void)
{
hostlist_iterator_t itr;
char *hostname;

if (!initial_plugs_setup)
return;

if (!(itr = hostlist_iterator_create(hosts)))
err_exit(true, "hostlist_iterator_create");

while ((hostname = hostlist_next(itr))) {
plugs_remove(plugs, hostname);
free(hostname);
}

hostlist_iterator_destroy(itr);
initial_plugs_setup = 0;
return;
}

static int setup_plug(const char *plugname, const char *hostindexstr)
{
char *host;
char *endptr;
int hostindex;

errno = 0;
hostindex = strtol (hostindexstr, &endptr, 10);
if (errno
|| endptr[0] != '\0'
|| hostindex < 0) {
printf("setplugs: invalid hostindex %s specified\n", hostindexstr);
return -1;
}

if (!(host = hostlist_nth(hosts, hostindex))) {
printf("setplugs: hostindex %d out of range\n", hostindex);
return -1;
}

plugs_add(plugs, plugname, host);

/* initialize plug to "off" for testing */
if (test_mode)
zhashx_insert(test_power_status, plugname, STATUS_OFF);

free(host);
return 0;
}

static void setplugs(char **av)
{
hostlist_t lplugs = NULL;
hostlist_t hostindices = NULL;
int plugcount, hostindexcount;
hostlist_iterator_t lplugsitr = NULL;
hostlist_iterator_t hostindicesitr = NULL;
char *plug;
char *hostindexstr;

if (!av[0] || !av[1]) {
printf("Usage: setplugs <plugnames> <hostindices>\n");
return;
}

if (!(lplugs = hostlist_create(av[0]))) {
printf("setplugs: illegal plugnames input\n");
goto cleanup;
}
if (!(hostindices = hostlist_create(av[1]))) {
printf("setplugs: illegal hostindices input\n");
goto cleanup;
}

plugcount = hostlist_count(lplugs);
hostindexcount = hostlist_count(hostindices);
if (plugcount != hostindexcount) {
printf("setplugs: plugs count not equal to host index count");
goto cleanup;
}

if (!(lplugsitr = hostlist_iterator_create(lplugs)))
err_exit(true, "hostlist_iterator_create");
if (!(hostindicesitr = hostlist_iterator_create(hostindices)))
err_exit(true, "hostlist_iterator_create");

/* if user is electing to configure their own plugs, we must remove
* all of the initial ones configured in setup_hosts()
*/
remove_initial_plugs();

while ((plug = hostlist_next(lplugsitr))
&& (hostindexstr = hostlist_next(hostindicesitr))) {
if (setup_plug(plug, hostindexstr) < 0)
goto cleanup;
free(plug);
free(hostindexstr);
}

cleanup:
hostlist_iterator_destroy(lplugsitr);
hostlist_iterator_destroy(hostindicesitr);
hostlist_destroy(lplugs);
hostlist_destroy(hostindices);
}

static void settimeout(char **av)
{
if (av[0]) {
Expand Down Expand Up @@ -787,6 +897,8 @@ static void process_cmd(CURLM *mh, char **av, int *exitflag)
setpowerpath(av + 1, &onpath, &onpostdata);
else if (strcmp(av[0], "setoffpath") == 0)
setpowerpath(av + 1, &offpath, &offpostdata);
else if (strcmp(av[0], "setplugs") == 0)
setplugs(av + 1);
else if (strcmp(av[0], "settimeout") == 0)
settimeout(av + 1);
else if (strcmp(av[0], CMD_STAT) == 0)
Expand Down Expand Up @@ -1104,6 +1216,8 @@ static void setup_hosts(void)
}

hostlist_iterator_destroy(itr);

initial_plugs_setup = 1;
}

int main(int argc, char *argv[])
Expand Down
6 changes: 4 additions & 2 deletions t/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ TESTSCRIPTS = \
t0030-heartbeat-stonith.t \
t0031-llnl-mcr-cluster.t \
t0032-list.t \
t0033-valgrind.t
t0033-valgrind.t \
t0034-redfishpower.t

# make check runs these TAP tests directly (both scripts and programs)
TESTS = \
Expand All @@ -59,7 +60,8 @@ EXTRA_DIST= \
sharness.sh \
etc/sierra_plugs.conf \
etc/mcr_plugs.conf \
etc/vpc.dev
etc/vpc.dev \
etc/redfishpower-setplugs.dev


AM_CFLAGS = @WARNING_CFLAGS@
Expand Down
48 changes: 48 additions & 0 deletions t/etc/redfishpower-setplugs.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Variant of redfishpower-cray-r272z30.dev that covers use of setplugs
# configuration
specification "redfishpower-setplugs" {
timeout 60

script login {
expect "redfishpower> "
send "auth USER:PASS\n"
expect "redfishpower> "
send "setheader Content-Type:application/json\n"
expect "redfishpower> "
send "setplugs Node[0-15] [0-15]\n"
expect "redfishpower> "
send "setstatpath redfish/v1/Systems/Self\n"
expect "redfishpower> "
send "setonpath redfish/v1/Systems/Self/Actions/ComputerSystem.Reset {\"ResetType\":\"On\"}\n"
expect "redfishpower> "
send "setoffpath redfish/v1/Systems/Self/Actions/ComputerSystem.Reset {\"ResetType\":\"ForceOff\"}\n"
expect "redfishpower> "
send "setcyclepath redfish/v1/Systems/Self/Actions/ComputerSystem.Reset {\"ResetType\":\"ForceRestart\"}\n"
expect "redfishpower> "
send "settimeout 60\n"
expect "redfishpower> "
}
script logout {
send "quit\n"
}
script status_all {
send "stat\n"
foreachnode {
expect "([^\n:]+): ([^\n]+\n)"
setplugstate $1 $2 on="^on\n" off="^off\n"
}
expect "redfishpower> "
}
script on_ranged {
send "on %s\n"
expect "redfishpower> "
}
script off_ranged {
send "off %s\n"
expect "redfishpower> "
}
script cycle_ranged {
send "cycle %s\n"
expect "redfishpower> "
}
}
37 changes: 0 additions & 37 deletions t/t0029-redfish.t
Original file line number Diff line number Diff line change
Expand Up @@ -107,43 +107,6 @@ test_expect_success 'stop powerman daemon' '
wait
'

#
# redfishpower fail hosts coverage
#

test_expect_success 'create powerman.conf for 16 cray redfish nodes (failhosts)' '
cat >powerman_fail_hosts.conf <<-EOT
listen "$testaddr"
include "$devicesdir/redfishpower-cray-r272z30.dev"
device "d0" "redfishpower-cray-r272z30" "$redfishdir/redfishpower -h t[0-15] --test-mode --test-fail-power-cmd-hosts=t[8-15] |&"
node "t[0-15]" "d0"
EOT
'
test_expect_success 'start powerman daemon and wait for it to start (failhosts)' '
$powermand -Y -c powerman_fail_hosts.conf &
echo $! >powermand.pid &&
$powerman --retry-connect=100 --server-host=$testaddr -d
'
test_expect_success 'powerman -q shows t[0-7] off, t[8-15] unknown' '
$powerman -h $testaddr -q >test_failhosts_query.out &&
makeoutput "" "t[0-7]" "t[8-15]" >test_failhosts_query.exp &&
test_cmp test_failhosts_query.exp test_failhosts_query.out
'
test_expect_success 'powerman -1 t[0-15] completes' '
$powerman -h $testaddr -1 t[0-15] >test_failhosts_on.out &&
echo Command completed successfully >test_failhosts_on.exp &&
test_cmp test_failhosts_on.exp test_failhosts_on.out
'
test_expect_success 'powerman -q shows t[0-7] on' '
$powerman -h $testaddr -q >test_failhosts_query2.out &&
makeoutput "t[0-7]" "" "t[8-15]" >test_failhosts_query2.exp &&
test_cmp test_failhosts_query2.exp test_failhosts_query2.out
'
test_expect_success 'stop powerman daemon (failhosts)' '
kill -15 $(cat powermand.pid) &&
wait
'

test_done

# vi: set ft=sh
104 changes: 104 additions & 0 deletions t/t0034-redfishpower.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#!/bin/sh

test_description='Cover redfishpower specific configurations'

. `dirname $0`/sharness.sh

powermand=$SHARNESS_BUILD_DIRECTORY/src/powerman/powermand
powerman=$SHARNESS_BUILD_DIRECTORY/src/powerman/powerman
redfishdir=$SHARNESS_BUILD_DIRECTORY/src/redfishpower
devicesdir=$SHARNESS_TEST_SRCDIR/../etc/devices
testdevicesdir=$SHARNESS_TEST_SRCDIR/etc

# Use port = 11000 + test number
# That way there won't be port conflicts with make -j
testaddr=localhost:11034


makeoutput() {
printf "on: %s\n" $1
printf "off: %s\n" $2
printf "unknown: %s\n" $3
}

#
# redfishpower fail hosts coverage
#

test_expect_success 'create powerman.conf for 16 cray redfish nodes (failhosts)' '
cat >powerman_fail_hosts.conf <<-EOT
listen "$testaddr"
include "$devicesdir/redfishpower-cray-r272z30.dev"
device "d0" "redfishpower-cray-r272z30" "$redfishdir/redfishpower -h t[0-15] --test-mode --test-fail-power-cmd-hosts=t[8-15] |&"
node "t[0-15]" "d0"
EOT
'
test_expect_success 'start powerman daemon and wait for it to start (failhosts)' '
$powermand -Y -c powerman_fail_hosts.conf &
echo $! >powermand.pid &&
$powerman --retry-connect=100 --server-host=$testaddr -d
'
test_expect_success 'powerman -q shows t[0-7] off, t[8-15] unknown' '
$powerman -h $testaddr -q >test_failhosts_query.out &&
makeoutput "" "t[0-7]" "t[8-15]" >test_failhosts_query.exp &&
test_cmp test_failhosts_query.exp test_failhosts_query.out
'
test_expect_success 'powerman -1 t[0-15] completes' '
$powerman -h $testaddr -1 t[0-15] >test_failhosts_on.out &&
echo Command completed successfully >test_failhosts_on.exp &&
test_cmp test_failhosts_on.exp test_failhosts_on.out
'
test_expect_success 'powerman -q shows t[0-7] on' '
$powerman -h $testaddr -q >test_failhosts_query2.out &&
makeoutput "t[0-7]" "" "t[8-15]" >test_failhosts_query2.exp &&
test_cmp test_failhosts_query2.exp test_failhosts_query2.out
'
test_expect_success 'stop powerman daemon (failhosts)' '
kill -15 $(cat powermand.pid) &&
wait
'

#
# redfishpower setplugs coverage
#

test_expect_success 'create powerman.conf for 16 cray redfish nodes (setplugs)' '
cat >powerman_setplugs.conf <<-EOT
listen "$testaddr"
include "$testdevicesdir/redfishpower-setplugs.dev"
device "d0" "redfishpower-setplugs" "$redfishdir/redfishpower -h t[0-15] --test-mode |&"
node "t[0-15]" "d0" "Node[0-15]"
EOT
'
test_expect_success 'start powerman daemon and wait for it to start (setplugs)' '
$powermand -Y -c powerman_setplugs.conf &
echo $! >powermand.pid &&
$powerman --retry-connect=100 --server-host=$testaddr -d
'
test_expect_success 'powerman -q shows all off' '
$powerman -h $testaddr -q >test_setplugs_query.out &&
makeoutput "" "t[0-15]" "" >test_setplugs_query.exp &&
test_cmp test_setplugs_query.exp test_setplugs_query.out
'
test_expect_success 'powerman -T -q shows plugs are being used' '
$powerman -h $testaddr -T -q > test_setplugs_query_T.out &&
grep "Node15: off" test_setplugs_query_T.out
'
test_expect_success 'powerman -1 t[0-15] works' '
$powerman -h $testaddr -1 t[0-15] >test_setplugs_on.out &&
echo Command completed successfully >test_setplugs_on.exp &&
test_cmp test_setplugs_on.exp test_setplugs_on.out
'
test_expect_success 'powerman -q shows all on' '
$powerman -h $testaddr -q >test_setplugs_query2.out &&
makeoutput "t[0-15]" "" "" >test_setplugs_query2.exp &&
test_cmp test_setplugs_query2.exp test_setplugs_query2.out
'
test_expect_success 'stop powerman daemon (setplugs)' '
kill -15 $(cat powermand.pid) &&
wait
'

test_done

# vi: set ft=sh

0 comments on commit a8908f2

Please sign in to comment.