SSH error : name or service not known - ruby

I am getting this error because, there are 5 peripheral trays on 10 available slots(subjected to change at anytime) so i have no other option other than pinging all of them and performing a command(killall). Is there a way to disable viewing this error and just performing the operation if the tray is available and ignore other wise
PS: am writing ruby script
help me out
code goes like this
for i loop
ssh -f -n user#host_$i killall -9 process

Will this be a workable solution?? Added your code into a Exception handling block and not doing anything in the handle.
for i loop
Begin
ssh -f -n user#host_$i killall -9 process
Ensure Exception =>e
//Forget about logging anything
End

Curious if this block solves the problem, not a great solution , but tried to refine on the exception one ...
killports = 0
killedcount=false
if (killedcount===false)
while killports <= 10
begin
puts killports
killports=killports+1
killedcount=true
ssh -f -n user#host_$i killall -9 process rescue Exception =>e
puts "Comming to an exception"
if killports<=10 && killedcount===true then
killedcount=false
retry
else
raise
end
end
killedcount=false
end
end

Related

Does $argv behave the same between Centos and RHEL systems

I am trying to troubleshoot an old TCL accounting script called GOTS - Grant Of The System. What it does is creates a time stamped logfile entry for each user login and another for the logout. The problem is it is not creating the second log file entry on logout. I think I tracked down the area where it is going wrong and I have attached it here. FYI the log file exists and it does not exit with the error "GOTS was called incorrectly!!". It should be executing the if then for [string match "$argv" "end_session"]
This software runs properly on RHEL Linux 6.9 but fails as described on Centos 7. I am thinking that there is a system variable or difference in the $argv argument vector for the different systems that creates this behavior.
Am I correct in suspecting $argv and if not does anyone see the true problem?
How do I print or display the $argv values on logout?
# Find out if we're beginning or ending a session
if { [string match "$argv" "end_session"] } {
if { ![file writable $Log] } {
onErrorNotify "4 LOG"
}
set ifd [open $Log a]
puts $ifd "[clock format [clock seconds]]\t$Instrument\t$LogName\t$GroupName"
close $ifd
unset ifd
exit 0
} elseif { [string match "$argv" "begin_session"] == 0 } {
puts stderr "GOTS was called incorrectly!!"
exit -1
}
end_session is populated by the /etc/gdm/PostSession/Default file
#!/bin/sh
### Begin GOTS PostSession
# Do not run GOTS if root is logging out
if test "${USER}" == "root" ; then
exit 0
fi
/usr/local/lib/GOTS/gots end_session > /var/tmp/gots_postsession.log 2> /var/tmp/gots_postsession.log
exit 0
### End GOTS PostSession
This is the postsession log file:
Application initialization failed: couldn't connect to display ":1"
Error in startup script: invalid command name "option"
while executing
"option add *Font "-adobe-new century schoolbook-medium-r-*-*-*-140-*-*-*-*-*-*""
(file "/usr/local/lib/GOTS/gots" line 26)
After a lot of troubleshooting we have determined that for whatever reason Centos is not allowing part of the /etc/gdm/PostSession/default file to execute:
fi
/usr/local/lib/GOTS/gots end_session
But it does update the PostSession.log file as it should .. . Does anyone have any idea what could be interfering with only part of the PostSession/default?
Does anyone have any idea what could be interfereing with PostSession/default?
Could it be that you are hitting Bug 851769?
That said, am I correct in stating that, as your investigation shows, this is not a Tcl-related issue or question anymore?
So it turns out that our script has certain elements that depend upon the Xserver running on logout to display some of the GUI error messages. This from:
Gnome Configuration
"When a user terminates their session, GDM will run the PostSession script. Note that the Xserver will have been stopped by the time this script is run, so it should not be accessed.
Note that the PostSession script will be run even when the display fails to respond due to an I/O error or similar. Thus, there is no guarantee that X applications will work during script execution."
We are having to rewrite those error message callouts so they simply write the errors to a file instead of depending on the display. The errors are for things that should be there in the beginning anyway.

warning using Parallel::ForkManager but only in Windows

I sometimes get this warning when using Parallel::ForkManager but only in Windows, not on a Unix based system. What does it mean and should I worry about it?
child process '-17108' disappeared. A call to waitpid outside of
Parallel::ForkManager might have reaped it.
Here is the sample code from the docs that my code is based on:
use LWP::Simple;
use Parallel::ForkManager;
my #links=(
["http://www.foo.bar/rulez.data","rulez_data.txt"],
["http://new.host/more_data.doc","more_data.doc"],
);
# Max 30 processes for parallel download
my $pm = Parallel::ForkManager->new(30);
LINKS:
foreach my $linkarray (#links) {
$pm->start and next LINKS; # do the fork
my ($link, $fn) = #$linkarray;
warn "Cannot get $fn from $link"
if getstore($link, $fn) != RC_OK;
$pm->finish; # do the exit in the child process
}
$pm->wait_all_children;
I had the similar issue and placing a sleep 1 before "$pm->start and next LINKS;"
fixed the issue. I guess its due to continues forking, where Perl lost track of the fork processes. I may be wrong!

Ruby - checking ping status featback with ssh, backtick via ssh?

In my project I want to write a script to check if every device in my network is online/reachable. I have a method called pingtest and it works for now..
def pingtest(destination)
system("ping -n 2 #{destination}")
if $? == 0 #checking status of the backtick
puts "\n Ping was successful!"
else
close("Device is unreachable. Check the config.txt for the correct IPs.")
#close() is just print & exit..
end
end
Now I wanted to ping via a ssh session with an other device in my network:
#--------------------------------
require 'net/ssh'
Net::SSH.start(#ip, #user, :password => #password)
#--------------------------------
#ssh = Ssh.new(#config)
#ssh.cmd("ping -c 3 #{#IP}")
The ping works fine but how can I use my backtrack idea now to determine if it was succesful or not?
I thought about using a sftp connection..
"ping -c 3 #{#IP} => tmpfile.txt" => download => check/compare => delete
(or something like that) to check if it was correct, but im not statusfied with that. Is there a possibility to check the success status like I did before?
I also tried something like this..
result = #ssh.cmd("ping -c 3 #{#IP}")
if result.success? == 0 # and so on..
I startet learning ruby some days ago, so im a newbie looking forward for your ideas to help me with this problem.
You can use Net::SSH to run the command remotely, similarly to what you've already got there.
The result returned from running the command will be whatever is written to both stdout and stderr.
You can use the contents of that returned value to check if it was successful or not.
Net::SSH.start(#ip, #user. password: #password) do |ssh|
response = ssh.exec! "ping -c 3 #{#other_ip}"
if response.include? 'Destination Host Unreachable'
close("Host unreachable. Result was: #{result}")
else
puts "\n Ping was successful"
end
end

How to ignore error and continue with rest of the script

Some background. I want to delete AWS Redshift cluster and the process takes more than 30 minute. So this is what I want to do:
Start the deletion
Every 1 minute, check the cluster status (it should be “deleting”)
When the cluster is deleted, the command would fail (because it
cannot find the cluster anymore). So log some message and continue with rest of the script
This is the command I run in a while loop to check the cluster status after I start the deletion:
resp = redshift.client.describe_clusters(:cluster_identifier=>"blahblahblah")
Above command will get me cluster status as deleting while the deletion process continues. But once the cluster is completely deleted, then the command itself will fail as it cannot find the cluster blahblahblah.
Here is the error from command once the cluster is deleted:
/var/lib/gems/1.9.1/gems/aws-sdk-1.14.1/lib/aws/core/client.rb:366:in `return_or_raise': Cluster blahblahblah not found. (AWS::Redshift::Errors::ClusterNotFound)
I agree with this error. But this makes my script exit abruptly. So I want to log a message saying The cluster is deleted....continuing and continue with my script.
I tried below settings
resp = redshift.client.describe_clusters(:cluster_identifier=>"blahblahblah")
|| raise (“The cluster is deleted....continuing”)
I also tried couple of suggestion mentioned at https://www.ruby-forum.com/topic/133876
But this is not working. My script exits once above command fails to find the cluster.
Questions:
How to ignore the error, print my own message saying “The cluster is deleted....continuing” and continue with the script ?
Thanks.
def delete_clusters clusters=[]
cluster.each do |target_cluster|
puts "will delete #{target_clust}"
begin
while (some_condition) do
resp = redshift.client.describe_clusters(:cluster_identifier => target_clust)
# break condition
end
rescue AWS::Redshift::Errors::ClusterNotFound => cluster_exception
raise ("The cluster, #{target_clust} (#{cluster_excption.id}), is deleted....continuing")
end
puts "doing other things now"
# ....
end
end
#NewAlexandria, I changed your code to look like below:
puts "Checking the cluster status"
begin
resp = redshift.client.describe_clusters(:cluster_identifier=>"blahblahblah")
rescue AWS::Redshift::Errors::ClusterNotFound => cluster_exception
puts "The cluster is deleted....continuing"
end
puts "seems like the cluster is deleted and does not exist"
OUTPUT:
Checking the cluster status
The cluster is deleted....continuing
seems like the cluster is deleted and does not exist
I changed the raise to puts in the line that immediately follows the rescue line in your response. This way I got rid of the RuntimeError that I mentioned in my comment above.
I do not know what are the implication of this. I do not even know whether this is the right way to do it. But It shows the error when the cluster is not found and then continues with the script.
Later I read a lot of articles on ruby exception/rescue/raise/throw.... but that was just too much for me to understand as I do not belong to programming background at all. So, if you could explain what is going on here, it will really helpful for me to get more confidence in ruby.
Thanks for your time.

How can I check from Ruby whether a process with a certain pid is running?

If there is more than one way, please list them. I only know of one, but I'm wondering if there is a cleaner, in-Ruby way.
The difference between the Process.getpgid and Process::kill approaches seems to be what happens when the pid exists but is owned by another user. Process.getpgid will return an answer, Process::kill will throw an exception (Errno::EPERM).
Based on that, I recommend Process.getpgid, if just for the reason that it saves you from having to catch two different exceptions.
Here's the code I use:
begin
Process.getpgid( pid )
true
rescue Errno::ESRCH
false
end
If it's a process you expect to "own" (e.g. you're using this to validate a pid for a process you control), you can just send sig 0 to it.
>> Process.kill 0, 370
=> 1
>> Process.kill 0, 2
Errno::ESRCH: No such process
from (irb):5:in `kill'
from (irb):5
>>
#John T, #Dustin: Actually, guys, I perused the Process rdocs, and it looks like
Process.getpgid( pid )
is a less violent means of applying the same technique.
For child processes, other solutions like sending a signal won't behave as expected: they will indicate that the process is still running when it actually exited.
You can use Process.waitpid if you want to check on a process that you spawned yourself. The call won't block if you're using the Process::WNOHANG flag and nil is going to be returned as long as the child process didn't exit.
Example:
pid = Process.spawn('sleep 5')
Process.waitpid(pid, Process::WNOHANG) # => nil
sleep 5
Process.waitpid(pid, Process::WNOHANG) # => pid
If the pid doesn't belong to a child process, an exception will be thrown (Errno::ECHILD: No child processes).
The same applies to Process.waitpid2.
This is how I've been doing it:
def alive?(pid)
!!Process.kill(0, pid) rescue false
end
You can try using
Process::kill 0, pid
where pid is the pid number, if the pid is running it should return 1.
Under Linux you can obtain a lot of attributes of running programm using proc filesystem:
File.read("/proc/#{pid}/cmdline")
File.read("/proc/#{pid}/comm")
A *nix-only approach would be to shell-out to ps and check if a \n (new line) delimiter exists in the returned string.
Example IRB Output
1.9.3p448 :067 > `ps -p 56718`
" PID TTY TIME CMD\n56718 ttys007 0:03.38 zeus slave: default_bundle \n"
Packaged as a Method
def process?(pid)
!!`ps -p #{pid.to_i}`["\n"]
end
I've dealt with this problem before and yesterday I compiled it into the "process_exists" gem.
It sends the null signal (0) to the process with the given pid to check if it exists. It works even if the current user does not have permissions to send the signal to the receiving process.
Usage:
require 'process_exists'
pid = 12
pid_exists = Process.exists?(pid)

Resources