I have been running simple pyinfra deploy scripts like this one
for doing my daily apt-get update/upgrade combo:
apt.py
from pyinfra.modules import apt
from pyinfra.modules import server
apt.update()
apt.upgrade()
server.shell(commands="apt-get -y autoremove")
initially I always ran it as the root user, like so
pyinfra -i somehost --user root -v apt.py
ie. using simply somehost's hostname, and taking advantage of the
fact, that I have an ssh-agent running, ie. I am not asked for a password or
key phrase (whether it's a good thing to allow ssh root access, is another question,
but it certainly makes my adminstrator's life easier).
Then I got bored of always having to type --user root, so instead I introduced
simple inventories (one for each host I use so far):
somehost.py
HOSTS = [
('somehost', {'ssh_user': "root"})
]
that way I can just call:
pyinfra -i somehost.py apt.py -v
I guess it makes sense to have ssh_user set as "root", because most of
the operations I do on a host require root permissions.
However not always: a similar emacs/cask update I typically do as user rx
(rather then root):
cd ~/.emacs.d && EMACS="emacs" ~/cfg/e/cask/bin/cask outdated
Now what I would like is: just call
pyinfra -i somehost.py -v cask.py
given that I have prepared a similar cask deploy script:
cask.py
from pyinfra.modules import server
server.shell(chdir="~/.emacs.d"
, commands='EMACS="emacs" ~/cfg/e/cask/bin/cask update'
, user="rx")
Ie. I want to just use the somehost.py inventory, and have my cask.py deploy script
figure out, that a certain task requires user "rx" only.
Note that this is my wishlist thinking: the server.shell command doesn't
currently have a user=... parameter
I do not want to have to think for every little task:
- oh, apt operations require root permissions, thus call them with an inventory
that has 'ssh_user': "root"
- cask operations I do as user "rx", thus call them with another inventory
that has 'ssh_user': "rx"
Rather I want the individual deploy scripts/operations therein be able
to take a user param.
currently what I am resorting to in the case of cask above:
def caskUpdate():
server.shell(commands='su - rx -c "cd ~/.emacs.d && EMACS=emacs ~/cfg/e/cask/bin/cask update"')
caskUpdate()
which is not really the style I want to write my operations.
Maybe this is possible with pyfinfra alreay, and I just haven't discovered it yet?
Also on my wishlist: maybe create a pyinfra mailing list, where I could ask these
kind of user questions ?
Not that in (haskell) propellor, which I am also using, this
is possible: the userScriptPropterty
there takes among other params a User param, cf eg.
http://hackage.haskell.org/package/propellor-3.0.5/docs/Propellor-Property-Cmd.html#v:userScriptProperty
ie. in propellor I just have
caskUpdate :: Property UnixLike
caskUpdate = propertyList "cask update" $ props
& userScriptProperty (User "rx")
[
"(cd ~/.emacs.d && EMACS=\"emacs\" ~/cfg/e/cask/bin/cask update)"
] `assume` MadeChange
Thanks for creating pyinfra in the first place, and keep up your good work.