Comments (22)
I think it is better to suggest such a change to fabric instead of cuisine. See fabric#538 and fabric#98 for more discussion.
from cuisine.
Thinking about it, it absolutely makes sense to implement this kind of feature in fabric. But following above mentioned issues, it is not clear to me, when and if this will come.
But in the meantime, we still have to live with what we have: and this is a working, but slightly confusing/inconsistent solution - that I wanted to streamline with my proposal.
These are our options:
a) we fix it in cuisine, till it is eventually ressolved in fabric.
b) leave cuisine unchanged, till is eventually ressolved in fabric.
And anyway, if we want to approach the fabric guys, it might be helpful to come with a proper proposal. And at the moment, we just have a brainstorming with myself.
from cuisine.
This is in an interesting discussion, however, the main reason why I introduced this notion of "modes" is the to avoid having to re-write functions that use a specific mode.
In particular, most basic functions should only be implemented using run
(ie. file ops, dir ops, command ops), but some others need to be implemented using sudo
(packages, users, groups) as they are typical admin tasks.
However, you don't want to have file_write
and file_write_sudo
, which is why I introduced mode_sudo
to override the status of run
.
Sames goes for mode_local
, as it allows to using any cuisine function on the local machine.
So in essence:
run()
is necessary, and should be what is used in most core cuisine functionssudo()
is optional (if you have mode_sudo()), but core cuisine functions that are typically restricted to admins should then wrap the runs inmode_sudo()
mode_local()
andmode_sudo()
are also necessary to allow to use existing cuisine core functions on the local system and using sudo priviledges without rewriting them
I agree with @schacki's proposals:
mode_local
should support enter/exit such asmode_sudo
MODE_SUDO
andMODE_LOCAL
should be False by default- The
MODE_*
should be set infabric.api.env
, not in the globals.
The reason why I think we should keep sudo()
is because I often sprinkle a couple of admin commands within my cuisine scripts. And I would hate to have to do:
with mode_sudo(): run("some admin-related command")
instead of
sudo("some admin-related command")
but I would agree with using mode_sudo()
instead of run in cuisine's core functions.
Thoughts?
from cuisine.
on the one hand, you prefer "sudo("some admin-related command")" over "with mode_sudo(): run("some admin-related command")", but at the same time you prefere "mode_sudo() instead of run in cuisine's core functions". I do not bring that together in my mind, please help :-).
i do not fully agree with: "but some others need to be implemented using sudo (packages, users, groups) as they are typical admin tasks". actually, this complete idea was triggered by an issue I had on webfaction: i do not have sudo rights there, but I do have read access to /etc/passwd and /etc/shadow. when i try to run check_user, i get an error, since you are using sudo:
d = sudo("cat /etc/passwd | egrep '^%s:' ; true" % (name))
s = sudo("cat /etc/shadow | egrep '^%s:' | awk -F':' '{print $2}'" % (name))
so i had to write my own check_user function without sudo to get it working.
from cuisine.
In that case reading the password should not use sudo, as it's not necessary. I didn't say I would like to use run() only in function core, only that I was not opposed to using with mode_sudo and run() instead ;)
from cuisine.
great discussion so far, so what is the bottom line? and i am not sarcarstic but really not sure :-)
i think we agree on the issue, but not sure on the solution.
first of all: do we want to align/push the fabric team, as madkinder proposed, or do we just want to move forward and adapt later on, once the fabric team has come up with a better solution?
if we want to move forward, what kind of API do we want to use for what I called the execution function(s)? please find my ideas here:
a) run (cuisine)
the core cuisine execution function, which respects all our "mode" definitions. should we keep the name "run" or should we make the different functionality more prominent by giving it a different name like "do"?
b) run (fabric)
will be used where appropriate as part of the run(cusinse) function. otherwise not recommended to be used since it will never respect the mode definitions
c) run_local(cuisine) and local (fabric)
why do we need run_local? from my understanding it is the same as local(fabric). if it has any additional/different feature, let's keep it, otherwise bin it. whatever of the 2 we go for: it should then be used where appropriate as part of the run(cusinse) function. and it will be the recommended way for users, if they want to enforce the local execution (and only recommended for that).
d) sudo (cuisine) and sudo (fabric)
same as c): why do we need both? should we keep the cuisine version or bin it? whatever of the 2 we go for: it should then be used where appropriate as part of the run(cusinse) function. and it will be the recommended way for users, if they want to enforce the sudo execution (and only recommended for that).
from cuisine.
I have had a talk on #fabric and figured out that the devs aren't happy about the idea of having any kind of local_sudo implementation in the core. So I guess the best way to persuade them (if it is possible at all) is to implement it in cuisine, then show them some use cases that demonstrate reusability of the code and how awesome it is. To cut the long story short: I guess we should go cuisine-only way. At least for now.
Here are some other random ideas.
-
group_*
anduser_*
functions shouldn't access /etc/{passwd,group} directly, instead they should usegetent
,groups
, etc tools.This way we will honor /etc/nsswitch.conf picking users/groups from ldap and/or other backends configured there without even knowing about it.
-
it would be nice to have an optional
user
argument tomode_sudo()
defaulting to 'root'with mode_sudo(user='postgres'): run('createuser ...') run('createdb ...')
-
I guess it is better to store a stack of modes rather then storing it in
_old_mode
. And yes, storing it infabric.api.env
is definitely the way to go. -
I haven't checked myself but they say fabric has some issues with quoting inconsistency with local/remote invocation. So
run('echo "Hello, world!"')
may behave differently in different local/remote/sudo modes.
I totally agree with sebastien that all the cuisine core functions are supposed to use the generic run()
(the one that honors mode_*()
). On the other hand I also agree with schacki that core functions should not impose sudo-ing in any way. Personally I prefer to declare the permissions explicitly:
with mode_sudo(user='superpower'):
package_ensure('python-django')
package_ensure('postgresql-9.1')
from cuisine.
- getent, groups ==> maybe please put that into a separate thread
- optional user argument to mode_sudo() defaulting to 'root' ==> great idea, and the same for mode_user() :-)
- fabric has some issues with quoting inconsistency ==> i think we just have to live with it for the moment :-(
from cuisine.
@schacki
I don't think mode_user() can accept a user argument by design. sudo is supposed to change the user running the command, how do you imagine non-sudo mode to do that?
What do you think about having a stack of modes rather then storing them in _old_mode
?
See #48 for getent stuff.
from cuisine.
following this: http://docs.fabfile.org/en/1.3.4/usage/env.html#user, we could utilize for user argument of mode_user()
could you explain the stack of modes in more detail please, and what would be the advantage?
from cuisine.
to be consistent with fabric approach, should the mode_xxx() not wrap the fabric settings decorator. from my understanding, this is EXACTLY what we want.
from cuisine.
@schacki yes indeed, and I think @madkinder made a pretty good summary of what we should do next. I've released an update today, but would love to have some contributions for you guys, esp. for the proper user_* and group_* implementation. I will take care of the mode_* rewrite using fabric's env.
So who is taking what?
from cuisine.
regarding " proper user* and group* implementation", I would not recommend myself, my command line knowledge is limited (thats why I loave cuisine :-) ).
I am happy to remove sudo from where it is not needed (being aware that this is not a huge contribution), if you need any other help that is not too close to command line, let me know.
from cuisine.
Alright, then, thanks!
from cuisine.
I think there are a lot of good ideas in this thread, and I've been looking into possible implementations. @sebastien, does the env-based implementation seem to make sense, and is it coming along?
I put together a proof-of-concept implementation today, but it involves monkey-patching fabric, which some people find unacceptable. It turns out that fabric's internal _run_command function controls almost everything you'd want to change in the modes, including specifying a user to sudo as. I've patched that function to override variables based on env settings and to run local execution through subprocess (similar to a pull request I made earlier, but cleaner, since fabric handles output, aborting during errors, etc.).
Before I start working on a clean pull request, does this sound like a workable approach? I like to avoid monkey-patching whenever possible, but in this case it just seems like a much cleaner way to solve the problem.
from cuisine.
@davehughes I was planning to rework the run
function in Cuisine to support sudo/user and local/remote all based on fabric.api.env
. Maybe it would be best to wait for me to do the update (which will be probably done today, actually), and then see if you find things to be improved -- if we can avoid monkey-patching, we should try first.
Feel free to share a gist though, I'm curious to see what it's like!
from cuisine.
Sounds good, I'll look forward to the update. In the meantime, my stab at the implementation is summarized in this gist.
from cuisine.
Ha, it's interesting, we took at similar approach for modes -- well done! Here's the update 96e7300 -- I've added some test cases for modes as well.
from cuisine.
The update looks good - in hindsight, I guess it isn't necessary to have a stack for modes, since each context manager just has to hold on to the oldMode to be able to roll back to the previous state.
There are a few possible improvements that I see, mostly having to do with the local mode. Right now, there are a few things that fabric's remote run methods do that run_local() doesn't:
- Prefixing commands based on env.command_prefixes, env.path, and env.sudo_prefix (a property that doesn't seem to be documented on the fabric site)
- Some general behavior, such as output and conditionally aborting on errors based on env.warn_only.
I think I'm going to try and rework run_local so it works more like the _run_command function I was trying to monkey-patch. It will involve a little bit of duplication, but I think it's worth it to have behavior that is more in line with fabric's handling.
from cuisine.
Yes, if cuisine.run_local
can behave as close as possible to fabric.run
it would be ideal -- but let's try to keep things simple as well and not mimic obscure/undocumented featured of Fabric.
from cuisine.
My bad, env.sudo_prefix did get documented recently; I was browsing some outdated doc.
http://docs.fabfile.org/en/1.4.3/usage/env.html#sudo-prefix
This seems like it could be a replacement for the SUDO_PASSWORD setting. The main question in my mind is whether cuisine.sudo_password() is intended to only set the sudo password for mode_local (this seems to be the case, but I can't tell for sure).
from cuisine.
I actually didn't add sudo_password
but saw it in the code today. I think it's safe to remove it, especially if it's an option already supported by fabric.
from cuisine.
Related Issues (20)
- group_user_ensure fails in suse 11 sp3 HOT 5
- `user_create` function appears in duplicate HOT 1
- cuisine.file_write fails with 7.6 and 7.7 HOT 2
- Why `apt_get` function executes a command twice?
- What is changed between version 0.7.6 and 0.7.7? HOT 6
- SyntaxError: 'invalid syntax' cuisine.py at 342 HOT 1
- how to set up attributes (chef like ) in cuisine HOT 1
- `dir_ensure` tries to create the directory even if it exists HOT 3
- Please rename "bsd" features "freebsd" HOT 2
- file_upload() behavior for lcd context incompatible with fabric put() HOT 4
- Using hashlib breaks compatibility with CentoOS 5 HOT 2
- package_ensure_apt(package_name, update=True) upgrade all package not only selected HOT 2
- Newline at end of updated text
- process_find can't find processes due to leading spaces. HOT 3
- trapping fabric.exceptions.NetworkError HOT 3
- NameError: name 'env' is not defined HOT 2
- README links
- Support for Fabric 2.x? HOT 1
- Fix simple typo: referes -> refers
- Python 3 support
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from cuisine.