I am writing a simple script which restarts a hadoop slave. In the script, I have to do some initial changes as a root user. After that I have to change to user "hadoop" and perform set of commands. I was using os.system to run commands but I doubt whether it works well. For example:
uid=pwd.getpwnam('hadoop')[2]
os.setuid(uid)
os.system('whoami')
os.chdir('/home/hadoop/hadoop/')
os.system('bin/hadoop-daemon.sh stop tasktracker')
Again I have to perform some commands as root after this and again become user "hadoop" and execute :
os.system('bin/hadoop-daemon.sh stop tasktracker')
I have three questions here ,
Is os.system is the best command that I can use to issue linux commands ?
I am able to change from root user to user hadoop by the commands above but I am not able to change to root user (I can understand there will be security issues if they permit this, I want to know is there any possibility to do that , atleast by passing password) ?
Does os.setuid() work ? whoami prints user hadoop but the process "tasktracker" is not stopped using those command, but if i perform the same commands manually it works fine (I use "su hadoop" instead of setuid while trying it out manually).
Thanks for all your help.
you could use:
os.system('sudo -u hadoop bin/hadoop-daemon.sh stop tasktracker')
or if you dont have sudo, but have su
os.system('su hadoop -c "bin/hadoop-daemon.sh stop tasktracker"')
It is a much better idea to use "su" than to switch the user ID using os.setuid().
Why?
- "su" will set up the login credentials correctly, including the group ID, and supplemental groups
- "su" will also do other useful things, such as setting environment variables (particularly if you use su - ). Maybe it will also set ulimit limits according to limits.conf.
This kind of scripts can be implemented much cleaner with use of fabric library: http://docs.fabfile.org/en/1.3.1/index.html
Additionally it provides nice command-line interface and capabilities of remote servers management via ssh. All the python is available so you can connect to databases for example or import whatever you need.
Exactly the question about running commands as some other user can be implemented with sudo command with user arg: http://docs.fabfile.org/en/1.3.1/api/core/operations.html#fabric.operations.sudo
I haven't done this myself but I see several os functions that may apply. They start here: http://docs.python.org/library/os.html#os.setegid
Also, there was a thread on the tutor list that addressed the topic: http://mail.python.org/pipermail/tutor/2002-December/018981.html
The os.system approach is limited because it only returns an error code. The subprocess.Popen toolset is more flexible.