Paramiko does not allow to see Motion Streaming - python

I'm using motion to run a rudimentary livestream. It works perfectly when i start it in server side with:
sudo motion -c livestream.conf
This starts a video server in 8081 port and i can access perfectly from wherever i want inside my network.
The issue comes when i want to write a little script which will ssh using paramiko to server, start motion with the same command and open default browser directly in video stream url. Here the sample code:
import paramiko
import subprocess
import time
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect('192.168.1.111', username = 'pi', password = 'raspberry')
ssh.exec_command('sudo motion -c livestream.conf')
time.sleep(4)
subprocess.call('xdg-open "http://192.168.1.111:8081"', shell= True)
ssh.close()
a pidof motion in server shows that the service is running,but i can't access it!!! Because motion is running, i think is not the common problem with sudo/paramiko, but i don't have any idea why this does not work.
WORKAROUND
Motion has a daemon mode. Enabling it from
/etc/default/motion
it starts on boot and i can call it perfectly with:
subprocess.call('xdg-open "http://192.168.1.111:8081"', shell= True)
But is not exactly what i'm looking for, because i'd like to launch(and close, but this will be another thread sure!!) the daemon, not just access the stream.
This workaround executes
/etc/motion/motion.conf
as daemon.I copied my motion script in there and everything good.
But when i try to start the script as daemon (not on boot, with the code above), it tells me that it can't create PID file. Everything done as root. I'm getting close to the answer by myself, just a little more.

Related

How to correctly configure and close an SSH session with paramiko

I have an Onion Omega2 device acting as a linux server that has a UART stream from an Arduino chip. Through the terminal on my laptop I can connect via SSH and stream the data from the UART coming into the device. I then attempted to create an SSH shell in Python using Paramiko. Code shown below:
import paramiko
def ssh_comm(ip, usr, passwd):
client = paramiko.SSHClient();
client.set_missing_host_key_policy(paramiko.AutoAddPolicy());
client.connect(ip, username=usr, password=passwd);
channel = client.invoke_shell();
channel.send("screen /dev/ttyS1 9600 \n");
print("/n");
points = 0;
while points < 100:
if channel.recv_ready():
print(channel.recv(1024));
points = points + 1;
channel.shutdown(2);
client.close();
return;
ssh_comm("192.xxx.x.x", "root", "password");
First time around it connects well and all data is streamed back to my laptop. However when I let the shell close and then re-open it I only recieve a few packets every now and then back from the Omega2. (It still connects fine though) After connecting through python the transmission is also intermittent when forming the SSH connection on the terminal using: ssh root#192.xxx.x.x.
Restarting the Omega 2 fixes this however since I can repeatedly connect though the terminal with no issues I beleive the problem must be to do with closing the session within the python code. Or not configuring it properly. Having looked through the paramiko docs and tried my best to configure it correctly I still get the same issue. Any ideas as to what could be causing it?
I found that the error is not to do with the SSH configuration but rather not closing the screen command before closing the channel. this was done by sending CTRL-A then k then y.
channel.send("\x01");
channel.send("k");
channel.send("y");
The \x01 represents CTRL-A. Without this re-running the program causes a second screen to be created and they both fight over the UART stream. Solution was found with reference to: Python Paramiko send CTRL+C to an ssh shell And provides a second method of fixing the problem.

accessing Putty outputstream with pywinauto

I am trying to automate a ssh connection with pywinauto. I am connecting via Putty to my server and can execute commands. However, I need to get the output of the Putty to verify what exactly is going on the server. Below you find my example code so far which I find on stackoverflow:
import time
import sys
app = Application ().Start (cmd_line=u'putty -ssh root#host')
putty = app.PuTTY
putty.Wait ('ready')
time.sleep (1)
putty.TypeKeys ("cd{SPACE}/")
putty.TypeKeys ("{ENTER}")
time.sleep (1)
putty.TypeKeys ("ls")
putty.TypeKeys ("{ENTER}")
I need a function that gives me the outputstream of the putty window. Something like:
stream = putty.ReadConsoleOutputStream()
lines = stream.readLines()
I tried it with:
print(putty.window_text())
but it only gives me the title of the window back. I have heard about paramiko but since the connection is passwordless, I couldn't access it via paramiko because i couldn't find a way to connect it without a password.
Thank you in advance for your help.

Keeping ports open in a python script that is run continuously

I'm trying to develop a server script using python 3.4 that runs perpetually and responds to client requests on up to 5 separate ports. My preferred platform is Debian 8.0. The platform currently runs on a virtual machine in the cloud. My script works fine when I run it off the command line - I need to now (1) keep it running once I log off the server and (2) keep several ports open through the script so that a windows client can connect to them.
For (1),
After trying several options [I tried using upstart, added the script to rc.local, used nohup with & to run it off the terminal, etc] that didn't seem to work, I eventually found something that does seem to keep the script running, even if it's not very elegant - I wrote an hourly cron script that checks to see if the script is running in the process list, and if not, to execute it.
Whenever I login to the VM now, I see the following output when I type 'ps -ef':
root 22007 21992 98 Nov10 14-12:52:59 /usr/bin/python3.4 /home/userxyz/cronserver.py
I assume that the script is running based on the fact that there is an active process in the system. I mention this part because I suspect that there could be a correlation with part (2) of my issue.
For (2),
The script is supposed to open ports 49100 - 49105 and listen for connection requests, etc. When I run the script from the terminal, zenmap from my client machine verifies that these ports are open. However, when the cron job initiates the script, these ports don't seem to stay open. My windows client program can't connect to the script either.
The python code I use for listening to a port:
f = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
f.bind((serviceIP, 49101))
f.listen(5)
while True:
scName, address = f.accept()
[code to handle request]
scName.shutdown(socket.SHUT_WR)
scName.close()
Any insight or assistance would be greatly appreciated!
What you ask is not easy because it depends on a variety of factors:
What is the frequency of the data received?
How many clients are expected to connect to this server?
Is there a chance two clients try to connect at the same time?
How long it takes to handle some received data?
What do you need to do with your data?
Write to a database?
Write to a file?
Calculate something?
Etc.
Depending on your answer you'll have some design decisions to make for your solution.
But since you need an answer, here's a hack that represent a way to do things:
import socketserver
import threading
import datetime
class SleepyGaryReceptionHandler(socketserver.BaseRequestHandler):
log_file_name = "/tmp/sleepygaryserver.log"
def handle(self):
# self.request is defined in BaseRequestHandler
data_received = self.request.recv(1024)
# self.client_address is also defined in BaseRequestHandler
sender_address = self.client_address[0]
# This is where you are supposed to do something with your data
# This is an example
self.write_to_log('Someone from {} sent us "{}"'.format(sender_address,
data_received))
# A way to stop the server from going on forever
# But you could do this other ways but it depends what condition
# should cause the shutdown
if data_received.startswith(b"QUIT"):
finishing_thread = threading.Thread(target=self.finish_in_another_thread)
finishing_thread.start()
# This will be called in another thread to terminate the server
# self.server is also defined in BaseRequestHandler
def finish_in_another_thread(self):
self.write_to_log("Shutting down the server")
self.server.shutdown()
# Write something (with a timestamp) to a text file so that we
# know something is happenning
def write_to_log(self, message):
timestamp = datetime.datetime.now()
timestamp_text = timestamp.isoformat(sep=' ', timespec='seconds')
with open(self.log_file_name, mode='a') as log_file:
log_file.write("{}: {}\n".format(timestamp_text, message))
service_address = "localhost"
port_number = 49101
server = socketserver.TCPServer((service_address, port_number),
SleepyGaryReceptionHandler)
server.serve_forever()
I'm using here the socketserver module instead of listening directly at a socket. This standard library module has been written to simplify writing a server. so use it!
All I do here is write to a text file what has been received. You would have to adapt it to your use.
But to have it running continuously use a cron job but to start it at the startup of the computer. Since this script will block until the server is stopped, we have to run it in the background. It would look something like that:
#reboot /usr/bin/python3 /home/sleepygary/sleppys_server.py &
I have tested it and after 5 hours it still does his thing.
Now like I said, it is a hack. If you want to go all the way and do things like any other services on your computer you have to program it in a certain way. You can find more information on this page: https://www.freedesktop.org/software/systemd/man/daemon.html
I'm really tired so there may be some errors here and there.

How to properly exit from an interactive SSH session with forwarded ports launched via Python?

I'm trying to write a wrapper Python script that automatically sets up port forwards to a remote host based on some parameters, and then gives me that shell. Everything works great, up until I want to exit the shell -- at which point, the session hangs and never returns me back to Python. Here's a toy example that does the same thing:
>>> import os
>>> os.system('ssh -L8080:localhost:80 fooserver.net')
user#fooserver.net password:
[fooserver.net]$ hostname
fooserver.net
[fooserver.net]$ exit
(hangs)
I believe this has something to do with the forwarded TCP port being in "TIME_WAIT" and keeping the SSH session alive until it closes, because this doesn't happen if I never request that forwarded port locally. What's the right way to handle this? Can I capture the "exit" from inside Python and then kill the os.system() pipe or something?

If I run the following script, will my ssh session not be terminated?

So I wrote this script called py_script.py that I ran over an ssh session on a school machine:
import time
import os
while True:
os.system("echo still_alive")
time.sleep(60)
... by doing:
bash $ python py_script.py &.
Is this going to prevent the dreaded broken pipe message from happening?
The problem is, after a period of inactivity when I am over an ssh connection, my connection will be dropped. To prevent this, I wrote the above script that automatically writes a message to the console to count for an "action" so that I don't have to press enter every 5 minutes. (I'm idle on a machine and need to run a process for a good amount of time.)
If your connection is timing out then it is more advisable to look at SSH configuration options which can keep your connection alive.
As a starter example, put the following in a file called ~/.ssh/config:
Host *
ServerAliveInterval 20
TCPKeepAlive=yes
You can read more here.

Categories

Resources