How to detect and drop an idle connection with Fabric? - python

#import ssh
import socket
from fabric.operations import run
def connect_and_wait():
#ssh.config.socket.setdefaulttimeout(5)
socket.setdefaulttimeout(5)
print('SSTART')
run('echo START')
run('sleep 10')
run('echo END')
print('EEND')
The script above prints everything without any error/exception.
Python 2.6.5, Fabric 1.4.2.
socket.setdefaulttimeout() does not work.
ssh.config.socket.setdefaulttimeout() does not work.
fabric.api.env['timeout'] is for connecting phase only I suppose.

Fabric uses "lazy" connections to remote hosts and can automatically reconnect when executing task on a host and connection is lost. Seems there is no way to explicitly drop idling connections, but you can close all connections and let fabric reconnect to "active" hosts. fabric.network.disconnect_all() do the trick.

Related

How to keep paramiko ssh session open after loggin in using python?

I am trying to ssh to a test cisco router in a test environment using python paramiko, and run cisco commands in that test router.
Everything works great except for 1 small detail.
After running the script I want the ssh session to remain open. (so I can run other commands manually).
I want to keep the ssh session open until I type "exit"
I found another link with a similar issue but I cant understand the solution.
(See here Python ssh - keep connection open after script terminates)
I would appreciate if someone can help me out here
My code
import paramiko
import time
def ssh_session(ip):
try:
session = paramiko.SSHClient() #Open the session
session.set_missing_host_key_policy(paramiko.AutoAddPolicy())
session.connect(ip, username = "ciscouser1", password = "password")
connection = session.invoke_shell()
####Running Cisco IOS commands###
connection.send("enable\n")
connection.send("password1") #sending
connection.send("\n")
connection.send("configure terminal\n\n")
time.sleep(1)
connection.send("do show ip int brief\n")
time.sleep(1)
except paramiko.AuthenticationException:
print "wrong credentials"
ssh_session("10.10.10.1")
The session timeout would be controlled by the SSH server. To the best of my knowledge, the only way to keep your session alive on the client side is to not be inactive, which can be accomplished by sending null packets. As to how to do this specifically with paramiko I am not certain. Perhaps you could send some kind of dummy command (or maybe even an empty string?) every so often?

How to start a server from the command line in a Python unittest

I'm building a tester for a Python script which performs works with a RethinkDB database. As part of the setUp() method, I'm trying to make the tester start up the RethinkDB server on localhost on port 28016 in case that has not yet been done.
I'm using subprocess to start the server. The problem is that, according to https://docs.python.org/2/library/subprocess.html, subprocess waits for the command to complete. In this case, it seems that as long as the server is up and running, the process is not complete and testing does not continue beyond the setUp() stage.
Here is the script I'm trying:
import unittest
import rethinkdb as r
import subprocess
class TestController(unittest.TestCase):
HOST = "localhost"
PORT_OFFSET = 1
PORT = 28015 + PORT_OFFSET
DB = "ipercron"
TABLE = "sensor_data"
def setUp(self):
try:
self.conn = r.connect(self.HOST, self.PORT)
except r.ReqlDriverError:
print("The RethinkDB server is not yet ready. Starting it up...")
subprocess.call(["rethinkdb", "--port-offset", str(TestController.PORT_OFFSET)])
self.conn = r.connect(self.HOST, self.PORT)
if TestController.DB not in r.db_list().run(self.conn):
r.db_create(TestController.DB).run(self.conn)
self.conn.use(TestController.DB)
if TestController.TABLE not in r.table_list().run(self.conn):
r.table_create(TestController.TABLE).run(self.conn) # Create the table if it does not yet exist
r.table(TestController.TABLE).delete().run(self.conn) # Empty the table to start with a clean slate
def test_upper(self):
self.assertEqual('foo'.upper(), 'FOO')
suite = unittest.TestLoader().loadTestsFromTestCase(TestController)
unittest.TextTestRunner(verbosity=2).run(suite)
The subprocess is meant to perform the rethinkdb --port-offset 1 command at the command line and then continue with the script. However, when I run the script I get the usual message that the server is ready:
kurt#kurt-ThinkPad:~/dev/clones/ipercron-compose/controller$ python unittest_controller.py
test_upper (__main__.TestController) ... The RethinkDB server is not yet ready. Starting it up...
Running rethinkdb 2.3.5~0xenial (GCC 5.3.1)...
Running on Linux 4.4.0-42-generic x86_64
Loading data from directory /home/kurt/dev/clones/ipercron-compose/controller/rethinkdb_data
Listening for intracluster connections on port 29016
Listening for client driver connections on port 28016
Listening for administrative HTTP connections on port 8081
Listening on cluster addresses: 127.0.0.1, 127.0.1.1, ::1
Listening on driver addresses: 127.0.0.1, 127.0.1.1, ::1
Listening on http addresses: 127.0.0.1, 127.0.1.1, ::1
To fully expose RethinkDB on the network, bind to all addresses by running rethinkdb with the `--bind all` command line option.
Server ready, "kurt_ThinkPad_a0k" 07bb35f6-3a33-4e8b-9e9c-a78504457969
Without any further action. How can I make the unittest proceed with the testing?
The problem is as you said, that subprocess.call is blocking and will wait for the command to finish. For scenarios where you need to spawn a child process without waiting for it to finish, you can use subprocess.Popen:
process = subprocess.Popen(["rethinkdb", "--port-offset", str(TestController.PORT_OFFSET)])
This gives you back a Popen object that provides a whole bunch of very useful methods to communicate with the child process. For example, you will probably want to use process.kill() in your unit test's tearDown() function to shut down your database.
Try with the following code
subprocess.call(["rethinkdb", "--port-offset", str(TestController.PORT_OFFSET)], shell = True)

Python ssh - keep connection open after script terminates

I'm trying to write a script that will ssh into a box for me. I'm using Python and leveraging the paramiko library. I can successfully ssh on the box, but as soon as the script terminates, the ssh connection also terminates. I want to keep the connection open after the script has completed running.
Python:
self.ssh = paramiko.SSHClient()
self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.ssh.connect(host, username=self.username, password=self.password)
stdout = execute(self.ssh, 'pwd') # test command for now to verify i'm on box
print stdout
sys.exit()
Console:
$ ssh.py
[u'/home/myuser\n']
myuser#xxxx ~
$
I haven't been able to find similar examples online, so any help would be appreciated.
Try this:
import subprocess
subprocess.call(["ssh", "myuser#myserver"])

RabbitMQ Message/Topic Receiver Crashing when RabbitMQ is not running

I am using python and pika on linux OS Environment.
Message/Topic Receiver keeps crashing when RabbitMQ is not running.
I am wondering is there a way to keep the Message/Topic Receiver running when RabbitMQ is not because RabbitMQ would not be on the same Virtual Machine as the Message/Topic Receiver.
This cover if RabbitMQ crashes for some reason but the Message/Topic Receiver should keep running. Saving having to start/restart the Message/Topic Receiver again.
As far as I understand "Message/Topic Reciever" in your case is the consumer.
You are responsible to make an application in such a way that it will catch an exception if it is trying to connect to the not running RabbitMQ.
for example:
creds = pika.PlainCredentials(**creds)
params = pika.ConnectionParameters(credentials=creds,
**conn_params)
try:
connection = pika.BlockingConnection(params)
LOG.info("Connection to Rabbit was established")
return connection
except (ProbableAuthenticationError, AuthenticationError):
LOG.error("Authentication Failed", exc_info=True)
except ProbableAccessDeniedError:
LOG.error("The Virtual Host configured wrong!", exc_info=True)
except ChannelClosed:
LOG.error("ChannelClosed error", exc_info=True)
except AMQPConnectionError:
LOG.error("RabbitMQ server is down or Host Unreachable")
LOG.error("Connection attempt timed out!")
LOG.error("Trying to re-connect to RabbitMQ...")
time.sleep(reconnection_interval)
# <here goes your reconnection logic >
And as far as making sure that you Rabbit server is always up and running:
you can create a cluster make you queue durable, HA
install some type of supervision (let say monit or supervisord) and configure it to check rabbit process. for example:
check process rabbitmq with pidfile /var/run/rabbitmq/pid
start program = "/etc/init.d/rabbitmq-server stop"
stop program = "/etc/init.d/rabbitmq-server start"
if 3 restarts within 5 cycles then alert

Paramiko change IP of remote machine

I have to change the IP of a remote machine running Gentoo. For this I use a code that looks like
try:
guest.connect("10.22.254.200", username='root',password='root')
except SSHException as detail:
session.flash = detail.message
else:
sftp = guest.open_sftp()
sftp.put('./scripts/change-ip', '/root/change-ip')
sftp.close()
guest.exec_command('chmod +x /root/change-ip')
time.sleep(5)
try:
stdin,stdout,stderr = guest.exec_command('/root/change-ip 10.22.254.200 &')
My change-ip script looks like
set -x
cp /etc/conf.d/net /etc/conf.d/net.bak
sed "s/10.22.254.200/$1/g" /etc/conf.d/net.bak > /etc/conf.d/net
/etc/init.d/net.eth0 restart
I am able to ssh directly and execute the script successfully changing the ip, but for some reason cant do it in the code.
Any help would be greatly appreciated
Restarting the network over the network is a dangerous thing. What happens here is that after stopping the network interface in the command /etc/init.d/net.eth0 restart the script receive a HANGUP signal stating that the connection has been closed, and stops before starting the network interface.
To avoid this problem, you can use nohup, which "run a command immune to hangups".

Categories

Resources