File: blade

package info (click to toggle)
conmux 0.12.0-5
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 372 kB
  • sloc: exp: 1,772; perl: 1,361; python: 202; sh: 124; makefile: 52
file content (251 lines) | stat: -rwxr-xr-x 5,022 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
#!/usr/bin/expect --
#
# blade -- console and management control for IBM blade servers.
#
# Obtain consoles for and hard reset support for blades in
# IBM blade centres.  Blades are identified by their blade centre ids.
#
# usage:
#  blade reboot|console <blade id> <user> <password> <connect command> ...
#
# example:
#  blade reboot blade[4] FOO BAR telnet 1.2.3.4
#  blade console blade[4] FOO BAR telnet 1.2.3.4
#
# (C) Copyright IBM Corp. 2004, 2005, 2006
# Author: Andy Whitcroft <andyw@uk.ibm.com>
#
# The Console Multiplexor is released under the GNU Public License V2
#
set P "blade"

if { [llength $argv] < 5 } {
	puts stderr "Usage: $P <command> <blade> <login> <password> <connect command ...>"
	exit 1
}

log_user 0

set cmd			[lindex $argv 0]
set system		[lindex $argv 1]
set username		[lindex $argv 2]
set password		[lindex $argv 3]
set command		[lrange $argv 4 end]

# Validate the command.
switch -- $cmd {
	console		{}
	reboot		{}
	default		{
		puts stderr "$P: $cmd: unrecognised command";
		exit 1
	}
}
# Ensure the blade name is fully qualified.  This ensures that
# the console prompt detection as reliable as possible.  Add the system
# prefix if it was not specified.
switch -re -- "$system" {
	system:.*	{ }
	.*		{ set system "system:$system" }
}

#log_file -a "$logfile"

set elapsed_time 0
set timeout 30

proc note {m} {
	global P
	puts "$P: $m"
}
proc warn {m} {
	global P
	puts "$P: WARNING: $m"
}
proc winge {m} {
	global P
	puts "$P: ERROR: $m"
}

note "Logging into blade centre with command \"$command\" to restart it";

# CONNECT: connect to the remote console.
eval spawn $command
expect {
	default {
		winge "login prompt not issued"
		exit 2
	}
	"Connection closed by foreign host." {
		winge "Telnet connection closed."
		exit 1
	}
	"Unable to connect to remote host:" {
		winge "Connection to remote console failed"
		exit 2
	}
	"username:" {
		#note "saw login prompt"
	}
}

# AUTHENTICATE: send username and password at the relevant prompts
note "sending login ..."
send -- "$username\r"
expect {
	default {
		winge "password prompt not issued"
		exit 2
	}
	"password:" {
		#note "password prompt found"
	}
}

note "sending password ..."
send -- "$password\r"
expect {
	default {
		winge "command prompt not issued"
		exit 2
	}
	"Invalid login!"  {
		winge "login/password incorrect ... aborting"
		exit 1
	}
	-- "system>" {
		#note "command prompt found"
	}
}

# SYSTEM: first validate the system specifier, if it does not
# exist get a listing and print that out whilst we are connected.
note "selecting system '$system' ..."
send "env -T $system\r"
set found 0
set prompt "$system>"
expect {
	default {
		winge "command prompt not issued"
		exit 2
	}
	OK {
		set found 1
		exp_continue
	}
	-- "system>" {
		#note "command prompt found"
	}
	-ex $prompt {
		#note "command prompt found"
	}
}

# The system the user specified was not found, give them a hand by
# getting  a list of systems.
if {$found == 0} {
	note "Defined systems:"
	send "list -l 2\r"
	expect {
		default {
			winge "command prompt not issued"
			exit 2
		}
		-- "system>" {
			#note "command prompt found"
		}
		"\n$" {
			puts -nonewline "$expect_out(buffer)"
			exp_continue
		}
	}
	note "complete ... exiting"
	send "exit\r"
	exit 1
}

# CONSOLE: open a console channel
if {[string compare $cmd "console"] == 0} {
	set ts_start 1
	set ts_cur 1
	set retry 0;
	note "connecting to console ..."

	# Unless console session lasts for more than two seconds, retry every
	# thirty seconds for up to a day.  This prevents repeated login events
	# which fill logs and cause loss of useful event log information.
	while {($ts_cur - $ts_start < 2) && ($retry < 2880)} {
		# 30 second delay between attempts, except for the first one
		if {$ts_start != 1} {
			note "connection failed, retrying after 30 second delay"
			after 30000
		}
		set ts_start [timestamp];
		send "console -o\r"
		interact {
			-o -ex $prompt {
				return
			}
		}
		set ts_cur [timestamp];
		incr retry
	}
	winge "console lost"
	exit 0
}

# Function to wait until the issued power command has taken effect.
proc powerWait {s} {
	global prompt
	set ok 0
	for {set retry 1} {$ok == 0 && $retry < 30} {incr retry} {
		note "checking for power state $s ..."
		after 2000
		send "power -state\r"
		expect {
			default {
				winge "command prompt not issued"
				exit 2
			}
			-ex $s {
				set ok 1
				exp_continue
			}
			-ex "$prompt" {
				#note "command prompt found"
			}
		}
	}
	if {$ok == 0} {
		winge "system did not enter power $s state ... aborting"
		exit 2
	}
}

# DOWN: shut the system down ... hard.  Expect to OK before the 
# prompt in the case of success.
note "powering cycling the system ..."
send "power -cycle\r"
set fail 1
expect {
	default {
		winge "command prompt not issued"
		exit 2
	}
	"OK" {
		set fail 0
		exp_continue
	}
	-ex "$prompt" {
		#note "command prompt found"
	}
}
if {$fail == 1} {
	winge "power cycle failed ... system not rebooted"
	exit 2
}
powerWait On

note "complete ... exiting"
send "exit"
exit 0