I wanted to create a desktop launcher for my Python application. The application executes various ssh operations over pexpect with publickey-authentication. The problem is however, when I start my app with the .desktop launcher it doesn't work properly. The ssh connections ask for a password and don't use the publickeys. But it works fine via commandline execution.
The .desktop File looks like this:
[Desktop Entry]
Version=1.0
Name=SSH-Manager
Comment=XYZ
Exec=python /home/userx/SSH-Manager/startup.py
Icon=/home/userx/SSH-Manager/resources/icon.png
Path=/home/userx/repos/SSH-Manager
Terminal=true
Type=Application
Categories=Utility;Application;
StartupNotify=false
The desktop environment is KDE and the desktop user is the same as the commandline user.
Can someone explain why I get such strange behavior with the launcher?
Edit: Example function
def run(self):
self.a_signal.emit("Retrieving Data")
try:
session = pxssh()
session.force_password = False
hostname = self.client
username = "root"
session.login(hostname, username)
session.sendline("ls -a")
session.prompt()
session.logout()
except ExceptionPxssh as e:
print ("pxssh failed: ")
self.error_signal.emit("failed", str(e))
print e
return
self.process_output()
self.finish_signal.emit("done")
As Mirosław Zalewski suspected in the comments, the problem was the ssh-agent was not running for the desktop-environment because ssh-add was initially used in the /etc/sources. Executing ssh-add in the X-users ~./profile therefore solves the problem.
Related
I first posted an answer in this post, but it didn't conform to the forum standards. I hope this time te answer fits the forum standards. This code should be more clear and easy to read.
In Python 3+ I have the following class that I use to build a Windows Service (it does nothing, just writes a log file):
#MyWindowsService.py
import win32serviceutil
import servicemanager
import win32service
import win32event
import sys
import logging
import win32api
class MyWindowsService(win32serviceutil.ServiceFramework):
_svc_name_ = 'ServiceName'
_svc_display_name_ = 'Service Display Name'
_svc_description_ = 'Service Full Description'
logging.basicConfig(
filename = 'c:\\Temp\\{}.log'.format(_svc_name_),
level = logging.DEBUG,
format = '%(levelname)-7.7s # %(asctime)s: %(message)s'
)
def __init__(self, *args):
self.log('Initializing service {}'.format(self._svc_name_))
win32serviceutil.ServiceFramework.__init__(self, *args)
self.stop_event = win32event.CreateEvent(None, 0, 0, None)
def SvcDoRun(self):
self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
try:
self.log('START: Service start')
self.ReportServiceStatus(win32service.SERVICE_RUNNING)
self.start()
win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE)
except Exception as e:
self.log('Exception: {}'.format(e))
self.SvcStop()
def SvcStop(self):
self.log('STOP: Service stopping...')
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
self.stop()
win32event.SetEvent(self.stop_event)
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
def log(self, msg):
servicemanager.LogInfoMsg(str(msg)) #system log
logging.info(str(msg)) #text log
def start(self):
self.runflag = True
while self.runflag:
win32api.Sleep((2*1000), True)
self.log('Service alive')
def stop(self):
self.runflag = False
self.log('Stop received')
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(MyWindowsService)
In the script I use a log file to check if it's working properly. I'm running python3.6 (also tried with python3.4) on Windows 7 and I'm experiencing the following problem. When I run python MyWindowsService.py install the prompt says that the service has been installed (but nothing is written in the log file). If I try to start the service, I get Service Error: 1 - More info NET HELPMSG 3547 which doesn't say much about the error. If I run python MyWindowsService.py debug, the program runs just fine (the log file is written), but still I don't have any control over the service: if I open another prompt and try to stop/start the service I still got the same results as stated above.
I also tryed to insert some debug code inside the init function, and when I run python MyWindowsService.py install it seems it doesn't get called. Is it possible?
I've checked for multiple solution and workarounds around the net, but I didn't find anything suitable. What am I missing?
As pointed out by eriksun in the comment to the first post, the problem came from the location of the python script, that was in a drive mapped with an UNC path - I'm working with a virtual machine. Moving the python script in the same drive as the python installation did the job.
To sum it up for future uses, if the service fails to start and you're pretty sure about your code, these are helpful actions to try and solve your issues:
use sc start ServiceName, sc query ServiceName and sc stop ServiceName to get info about the service.
check if your file is in a physical drive or in a UNC-mapped drive. If the latter try to run the script using the UNC path (for example python \\Server\share\python\your-folder\script.py) or move your script in the same drive as the python installation
make sure that "python36.dll", "vcruntime140.dll", and "pywintypes36.dll" are either symlink'd to the directory that has PythonService.exe; or symlink'd to the System32 directory; or that the directories with these DLLs are in the system (not user) Path
Check the system register with command reg query HKLM\System\CurrentControlSet\Services\your_service_name /s to get more information about the script
PLease, feel free to complete, change, modify the last so that it can be usefull for anyone that like me encounder this issue.
EDIT: One more thing... My project was thought to work actually with network folders (and UNC-mapped drive) and it failed when I tried to make it run as service. One very useful (day-saving) resource that I used to make it work is the SysinternalsSuite by Mark Russinovich that I found in this post. Hope this helps.
I am writing a program in python on Ubuntu, to remove a file from remote machine(raspberrypi) by accessing it, connected with network.
For file selection I am using a command called askopenfilename.
But I am struggling in specifying the Path of RaspberryPi correctly.
Can you please guide me on how do I specify Raspberrypi path correctly?
IP = "192.168.2.34"
Username = "pi"
Password ="raspberry"
Path="/home/pi/python"
Below is my code
from tkFileDialog import askopenfilename
import paramiko
client = paramiko.SSHClient()
client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
client.connect('192.168.2.34', username='pi', password='raspberry')
checkdir = "/home/pi/python"
name1= askopenfilename(title = "Select File For Removal", initialdir = checkdir)
stdin, stdout, stderr = client.exec_command('ls -l')
for line in stdout:
print '... ' + line.strip('\n')
client.close()
I am fairly sure the tk file dialog is only able to browse the Ubuntu machine (which it seems to run on) filesystem - not the RPi filesystem over SSH, so you will never see RPi directories.
if You can read the RPi directory listing there, so you could create your own file browser component or try to find an existing one that works over SSH.
Then again it looks like you are 'inventing the wheel again' (which of course is ok for learning purposes) - gFTP, FileZilla, many of the Linux desktop file browsers etc. (or WinSCP if you were using a Windows box) are ready made tools for this.
I have a vanilla python that connects to a sqlite database.
Everything works fine until I try to run it as a daemon. Here is the code I'm using to do that:
def start(self):
if self.lockfile.is_locked():
exit_with_code(7, self.pid_file)
# If we're running in debug, run in the foreground, else daemonise
if self.options['debug']:
try:
self.main()
except KeyboardInterrupt:
pass
finally:
self.close_gracefully()
else:
context = daemon.DaemonContext(
files_preserve = [self.logger.socket(), self.lockfile]
)
context.signal_map = {
signal.SIGTERM: self.close_gracefully
}
with context: self.main()
I can run it in the foreground with python -m starter -debug and everything is fine, my app writes into the database, but when I leave the debug flag off I see the following when I try to write:
no such table: Frontends
I know that the frontends table exists because I've opened the database up. I assume that python is finding the database, because there would be an entirely different error message otherwise.
All my files are owned by vagrant, and ls -l shows the following:
-rwxrwxrwx 1 vagrant vagrant 9216 Nov 9 18:09 development.sqlite
Anyone got any tips?
Update
As requested, here is the code for my db
import os
import sqlite3
class Database(object):
def __init__(self, db_file='/vagrant/my_daemon/db/development.sqlite'):
self.db = sqlite3.connect(db_file)
if os.path.exists(db_file):
print "db exists"
And when I run this it prints "db exists". I instantiate the database in starter.py with a call to Database().
Python daemon closes all open file descriptors (except stdin, stout and stderr) when you daemonise.
I spent ages trying to figure out which files to keep open to prevent my database from being inaccessible, and in the end I found that it's easier to initialise the database inside the daemon context rather than outside. That way I don't need to worry about which files should stay open.
Now everything is working fine.
How can I fetch the title of a screen session from the command line?
I came up with a very small and simple python script with pexpect to do it.
It is handy in multiuser environments where some host is reserved and status is written to screen title by user.
It works for me, feel free to make it better.
In order to fetch specific session title, you need to modify the script and call for correct session.
If you run this through remote connection as local script (through SSH for example), remember to set export TERM=xterm before execution.
try:
import pexpect
import sys
child=pexpect.spawn('screen -x')
child.sendcontrol('a');
child.send('A');
i = child.expect('Set window.*')
child.sendcontrol('c');
child.sendcontrol('a');
child.send('d');
TITLE=str(child.after)
TITLE_P=TITLE.split('7m')
if str(TITLE_P[-1]) == '':
print 'Title not found'
else:
print str(TITLE_P[-1])
except:
print 'Could not check screen Title'
all python code service can install but cannot start
Error 1053: The service did not respond to the start or control request in a timely fashion".
since my service can install and start in my server.
i think my code has no problem.
but i still wonder is there a solution that i can solve this error in code
my service:
import win32serviceutil
import win32service
import win32event
import time
import traceback
import os
import ConfigParser
import time
import traceback
import os
import utils_func
from memcache_synchronizer import *
class MyService(win32serviceutil.ServiceFramework):
"""Windows Service."""
os.chdir(os.path.dirname(__file__))
conf_file_name = "memcache_sync_service.ini"
conf_parser = ConfigParser.SafeConfigParser()
conf_parser.read(conf_file_name)
_svc_name_, _svc_display_name_, _svc_description_ = utils_func.get_win_service(conf_parser)
def __init__(self, args):
if os.path.dirname(__file__):
os.chdir(os.path.dirname(__file__))
win32serviceutil.ServiceFramework.__init__(self, args)
# create an event that SvcDoRun can wait on and SvcStop can set.
self.stop_event = win32event.CreateEvent(None, 0, 0, None)
def SvcDoRun(self):
self.Run()
win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE)
def SvcStop(self):
self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
win32event.SetEvent(self.stop_event)
LoggerInstance.log("memcache_sync service is stopped")
self.ReportServiceStatus(win32service.SERVICE_STOPPED)
sys.exit()
def Run(self):
try:
LoggerInstance.log("\n******\n\memcache_sync_service is running, configuration: %s\n******" % (self.conf_file_name,))
if ((not self.conf_parser.has_section('Memcache')) or
(not self.conf_parser.has_option('Memcache', 'check_interval'))):
LoggerInstance.log('memcache_sync_service : no Memcache service parameters')
self.SvcStop()
# set configuration parameters from ini configuration
self.check_interval = self.conf_parser.getint('Memcache', 'check_interval')
ms = MemcacheSynchronizer()
while 1:
ms.Sync()
time.sleep(self.check_interval)
except:
LoggerInstance.log("Unhandled Exception \n\t%s" % (traceback.format_exc(),))
if __name__ == '__main__':
win32serviceutil.HandleCommandLine(MyService)
execute result of "sc query [name]" cmd:
SERVICE_NAME: NewsMonitoringMemcacheSynchronizer
TYPE : 10 WIN32_OWN_PROCESS
STATE : 1 STOPPED
(NOT_STOPPABLE,NOT_PAUSABLE,IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x0
WAIT_HINT : 0x0
update:
i can run this service with debug mode, cmd:
memcache_syn_service.py debug
Had the same problem using pypiwin32 (version: 220) and python (version: 3.6). I had to copy :
"\Python36-32\Lib\site-packages\pypiwin32_system32\pywintypes36.dll"
to
"\Python36-32\Lib\site-packages\win32"
for the service to start (was working in debug mode)
If:
python your_service.py debug works, whilst
python your_service.py install + start it as a service fails with error 1053,
this command may help python C:\Python27\Scripts\pywin32_postinstall.py.
all my python coded windows service cannot run on my computer.
but all of them can start at our dev-server which means my code is correct.
but i found a alternative solution, run in debug mode:
any_service.py debug
Make sure you run the application with a different user than the default Local System user. Replace it with the user you successfully be able to run the debug command with.
To replace the user go to the windows services (start > services.msc)
Right click on the service you created > properties > Log On
Uncheck the Local System Account and enter your own.
All of the known fixes have failed me, and this one worked:
In services window:
right-click your installed service;
Go to Log On tab;
Select "This Account" and enter your user ID and pass;
Restart PC.
Has to do with Windows Permissions I was explained...
Method won't work if there's no password set for Windows User.
In my case the problem was from python37.dll not being at C:\Python37-x64\Lib\site-packages\win32.
Just copy it there and it will solve the problem
I had similar problem with a python service and found out that it was missing DLLs since the 'System Path' (not the user path) was not complete. Check the path in your dev-server and whether it matches the one at your computer (System path if service is installed as a LocalSystem service). For me I was missing python dlls' path c:\python27 (windows).
I had this issue and solved it two times in the same way, simply adding the Environment Variables.
I opened Environment Variables, and in system variable PATH added
C:\Users\MyUser\AppData\Local\Programs\Python\PythonXXX
C:\Users\MyUser\AppData\Local\Programs\Python\PythonXXX\Scripts
(Obviously change User name and XXX with Python version)