-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathyum_remote_install.pl
335 lines (270 loc) · 12.7 KB
/
yum_remote_install.pl
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
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
#!/usr/bin/perl
#
# --- [yum_remote_install] Perl Script ---
#
# Author(s): Ryan Irujo
# Inception: 01.14.2013
# Last Modified: 01.17.2013
#
# Description: Script that queries a specified RPM (or RPMs) on a set of Servers (read from a text file) and
# does the following:
#
# 1. Remove older RPMs specified in the '$check_for_retired_rpms' variable.
# 2. Removes any instances of the new or different RPM specified in the '$check_for_updated_rpm' variable.
# 3. Installs/Reinstalls a new or different RPM specified in the '$install_updated_rpm' variable.
#
# Add of all of the Servers you would like to query into a single column in a file named 'servers.txt'.
# You can rename the text file by specifying a different name in the '$server_list' variable below.
# The Script will prompt for a username and password to use for logging into the remote Servers
# as soon as you run it.
#
#
# Changes: 1.17.2012 - [R. Irujo]
# - Added ReadKey Module in order to hide username and password credentials passed to the script
# from the terminal.
#
#
# Syntax: ./yum_remote_install
#
# Command Line: ./yum_remote_install
use warnings;
use Expect;
use Term::ReadKey;
#--------------------------------------------------------------
# Main Variables
#--------------------------------------------------------------
my $scp = "/usr/bin/scp";
my $ssh = "/usr/bin/ssh";
my $host_list = "servers.txt";
my $log_file = "yum_remote_install_log.txt";
my $results_file = "yum_remote_install_results.txt";
my $timeout = 10;
my $check_for_retired_rpms = "rpm -qa | grep [rpm_package_name] && echo RETIRED_RPMs found - Removing... || echo Retired RPM Check = Pass";
my $remove_retired_rpms = "sudo /bin/rpm -e [rpm_package_name] && echo REMOVED || echo CONTINUE...";
my $check_for_updated_rpm = "rpm -qa | grep [rpm_package_name] && echo UPDATED RPMs found - Removing... || echo Updated RPM NOT FOUND!";
my $remove_updated_rpm = "sudo /bin/rpm -e [rpm_package_name] && echo UNINSTALLED || echo CONTINUE...";
my $install_updated_rpm = "sudo /usr/bin/yum install [rpm_package_name]";
#----------------------------------------------------------------
# Gathering Credentials used to login to the Remote Servers.
#----------------------------------------------------------------
ReadMode('noecho');
print "Please provide a username:\n";
chomp(my $username = <STDIN>);
print "Please provide a password:\n";
chomp(my $password = <STDIN>);
ReadMode('normal');
#--------------------------------------------
# Making sure Credentials are not empty.
#--------------------------------------------
if (!defined $username || $username eq ""){
print "\nA [Username] must be provided.\n";exit 2;
}
if (!defined $password || $password eq ""){
print "\nA [Password] must be provided.\n";exit 2;
}
#--------------------------------------
# Adding/Recreating the Query File
#--------------------------------------
if (-e $log_file) {
system("rm ./$log_file");
if ($? == 0) {
print "\n$log_file found. Deleting it.\n";
system("touch ./$log_file");
if ($? == 0) {
print "New $log_file created successfully.\n";
}
elsif ($? != 0) {
print "There was a problem creating the $log_file\n";
exit 2;
}
}
}
else {
system("touch ./$log_file");
if ($? == 0) {
print "\nNew $log_file created successfully.\n";
}
elsif ($? != 0) {
print "There was a problem creating the $log_file.\n";
exit 2;
}
}
#----------------------------------------
# Adding/Recreating the Results File
#----------------------------------------
if (-e $results_file) {
system("rm ./$results_file");
if ($? == 0) {
print "\n$results_file found. Deleting it.\n";
system("touch ./$results_file");
if ($? == 0) {
print "New $results_file created successfully.\n\n";
}
elsif ($? != 0) {
print "There was a problem creating the $results_file\n";
exit 2;
}
}
}
else {
system("touch ./$results_file");
if ($? == 0) {
print "New $results_file created successfully.\n\n";
}
elsif ($? != 0) {
print "There was a problem creating the $results_file.\n";
exit 2;
}
}
#----------------------------------------------------------------------------
# Verifying Server List is Available and User is ready to Execute Script
#----------------------------------------------------------------------------
my $choice = &verify_ready_to_run();
if ($choice eq "yes") {
print "Starting NOW!\n";
}
if ($choice eq "no") {
print "Exiting Script...\n";
exit 2;
}
#--------------------------------------------------------------
# Remote Installation of RPM
#--------------------------------------------------------------
foreach $server (`cat ./$server_list`){
chomp($server);
&yum_remote_install ($scp, $username, $password, $server, $timeout);
}
# Parsing out relevant entries in the Query File and formatting them in readable format in the Results File.
my $final_results = system("cat ./$query_file | grep '>' | cut -d'>' -f2 | cut -c 2-300 > ./$results_file");
# Verifying that the entries in the Query File were transferred to the Results File and then exiting the script.
my $results_check = `cat ./$results_file | wc -l`;
if ($results_check < 1 ) {
warn "\nThere were NO Results written to the [$results_file] file.\n";
exit 0;
}
elsif ($results_check >= 1 ) {
warn "\nFinal Results are available in the [$results_file] file.\n";
exit 2;
}
#--------------------------------------------------------------
# Subroutines
#--------------------------------------------------------------
sub verify_ready_to_run () {
if (-e $server_list) {
system("cat ./$server_list\n");
print "\nThe Script will now query the Servers listed above. Do you want to continue? [yes/no]\n";
chomp(my $choice = <STDIN>);
if ($choice eq "yes") {
return $choice;
}
if ($choice eq "no") {
return $choice;
}
while ($choice ne "yes" && $choice ne "no") {
print "Please type in either 'yes' or 'no':\n";
chomp(my $choice = <STDIN>);
if ($choice eq "yes") {
return $choice;
}
if ($choice eq "no") {
return $choice;
}
}
}
else {
print "Unable to run as the file name listed in the [\$server_list] variable doesn't appear to exist.\n";
exit 2;
}
}
sub yum_remote_install (){
my $scp = shift;
my $username = shift;
my $password = shift;
my $server = shift;
my $timeout = shift;
my $prompt = '\$\s*';
# Creating new Expect Instance.
my $rpm_exp = new Expect;
# This sets Expect to not be so verbose on the output to the terminal. You can comment this
# out if you want to see all of the raw output.
$rpm_exp->raw_pty(1);
# Enabling STDOUT Logging which will redirect the results of the script to the Query File.
# for additional parsing later.
$stats_exp->log_stdout(1);
$stats_exp->log_file($log_file);
# Spawning SSH Session to Remote Host.
$rpm_exp->spawn("$ssh $username\@$server") or die "Cannot spawn ssh: $!\n";
# Running Expect Function.
$rpm_exp->expect($timeout,
# SSH - Add Key From Remote Host Prompt.
[qr'\(yes/no\)\s*' , sub {my $exph = shift;
print $exph "yes\n";
exp_continue; }],
# SSH Password Prompt.
[qr'word:\s*' , sub {my $action = shift;
$action->send("$password\n");
exp_continue; }],
# Check for Retired RPM Packages.
[qr'login:\s*' , sub {my $action = shift;
$action->send("$check_for_retired_rpms\n");
exp_continue; }],
# Check for Retired RPM Packages. This Occurs if the user account used to run this script
# has never logged into the Host before.
[qr'Creating directory\s*' , sub {my $action = shift;
$action->send("$check_for_retired_rpms\n");
exp_continue; }],
# Remove Retired RPM Packages.
[qr'RETIRED_RPMs\s*' , sub {my $action = shift;
$action->send("$remove_retired_rpms\n");
exp_continue; }],
# Check for Updated RPM Package.
[qr'Retired\s*' , sub {my $action = shift;
$action->send("$check_for_updated_rpm\n");
exp_continue; }],
# Remove Updated RPM Package.
[qr'UPDATED\s*' , sub {my $action = shift;
$action->send("$remove_updated_rpm\n");
exp_continue; }],
# Installing new RPM Package and Dependencies if required - POST Retired RPM Check.
[qr'CONTINUE\s*' , sub {my $action = shift;
$action->send("$install_updated_rpm\n");
exp_continue; }],
# Installing new RPM Package and Dependencies if required - POST Updated RPM Check.
[qr'RPM NOT FOUND\s*' , sub {my $action = shift;
$action->send("$install_updated_rpm\n");
exp_continue; }],
# Installing new RPM Package and Dependencies if required - POST Retired RPMs Uninstall.
[qr'REMOVED\s*' , sub {my $action = shift;
$action->send("$install_updated_rpm\n");
exp_continue; }],
# Installing new RPM Package and Dependencies if required - POST Updated RPM Uninstall.
[qr'UNINSTALLED\s*' , sub {my $action = shift;
$action->send("$install_updated_rpm\n");
exp_continue; }],
# Responding with 'Yes' to yum installation prompt.
[qr'\[y/N\]:\s*' , sub {my $action = shift;
print $action "y\n";
exp_continue; }],
# Exit out of Server once RPM Installation is Complete.
[qr'Complete\s*' , sub {my $action = shift;
$action->send("exit\n");
exp_continue; }],
# Exit Send Notification that Installation was successful to Terminal.
[qr'logout\s*' => sub {warn "[rpm_package_name] Installation on $server was Successful!.\n";
exp_continue; }],
# Exception Handling subroutines are below. All Errors are treated with 'warn' instead of 'die' to ensure that
# the Script keeps running for the the rest of the Servers in the Hosts.txt file.
# [qr'dependencies:\s*' => sub {warn "Unable to Install $lfile on $server due to missing RPM Dependencies.\n";}],
# [qr'Sorry\s*' => sub {warn "Unable to Install $lfile on $server.\n";}],
[qr'IOError\s*' => sub {warn "Unable to Install RPM as $server is currently in Read-Only Mode.\n";}],
[qr'OSError\s*' => sub {warn "Unable to Install RPM as $server is currently in Read-Only Mode.\n";}],
[qr'incident will be reported' => sub {warn "$username does not have sudo rights on $server.\n";}],
[qr'Nothing to do' => sub {warn "RPM Packages are missing from the Repository that $server is using.\n";}],
[qr'key ID 6b8d79e6' => sub {warn "The RPM key for perl-Crypt-DES-2.05-3.2.el5.rf.x86_64.rpm is missing on $server.\n";}],
[EOF => sub {warn "Error: Could not login!\n"; }],
[timeout => sub {warn "Error: Could not login!\n"; }],
$prompt,);
}
#------------------
# END of Script
#------------------