-
-
Notifications
You must be signed in to change notification settings - Fork 14.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create service abstraction layer (proposal, prototype) #5246
Conversation
How are service dependencies specified in this new Service Abstraction Layer? Like systemd "wants" and "after". |
Currenlty they are not, i am not sure that's really a part of this layer. Different process managers have different ways for dependencies. In case of docker you would run multiple containers for each process, and sometimes you run service on many instances and do load balancing and other services depend on it. I think it's up to systemd, supervisord, docker to define dependencies in their own way. |
+1 |
Very nice. A selfish question: maybe there should be a separate mongodb.configs attribute set so we can easily get everything considered a config file? It is sometimes helpful for debugging, and specifyng it into a large service refactoring gives us a chance for a uniform interface. |
@7c6f434c yeah this is only one use case, this is not such an easy problem. I guess separate service definitions for user services could be a solution, but well then we are already talking about service abstraction layer. Honestly i'm quite limited with systemd, because i can't write services for other process managers and it hurts everytime i write service i could use elsewhere (user services, docker, osx,..). I'm still waiting for response @lethalman @wmertens @edolstra @rbvermaa @nbp @iElectric? I would like to solve this so i could continue develop nix user services and docker services. |
I wonder what will be the next thing to break — broken logging of
And then, sometimes the service needs just a start script and stop By the way, is preStop script implied to be capable to properly tell
Well, I am so not OK with SystemD that I will be willing to join you |
fi | ||
''; | ||
}; | ||
|
||
sal.services.mongodb.dataDir = "/var/lib/mongodb"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original dir was /var/db
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, i will that, it was mostly as example, i have to make this interface better anyway.
Also, I think this is the best time for thinking about multiple-instances of services? Instead of having |
@lethalman can you explain multiple-instances of services in more detail? |
postStart = config.service.postStart; | ||
preStop = config.service.preStop; | ||
postStop = config.service.postStop; | ||
reload = config.service.reload; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inherit (config.service) description environment;
and so on ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup, makes sense ;)
Having an abstraction layer for services is a good thing, as this brings more competition between multiple systems and reduce the cost for changing from one to the other without as much burden as other distributions (* -> systemd). The current prototype is not yet satisfying from my point of view. One of the issue I see is that the MongoDB module is no longer 1 module, but 2 modules. One defined as part of "sal", and the other defined as part of NixOS. The one defined in "sal" contains most of the logic for starting a service, but none of the logic for making it secure when we are capable of expressing the need of a new user associated with the service. The user name is not always something which appear last in a configuration, and as such I do not think it should be a second citizen option. The other part are the systemd option definitions, why do they have to be out-side the first MongoDB module? I guess I should put mock-up system as part of the module logic … and not as part of any mock-up module. |
My idea of multi instances is to have multiple instances of the service :P Instead of e.g. one nginx httpd, you can define multiple nginx httpd using different versions for example. E.g. pgsql 9.3 and pgsql 9.4. But forget that, it's not tied to this PR, I'm going to do that separately. Though I'd like these new services to be multiple-instances aware as possible. |
@nbp honestly, changing init system is not a burden even in the current stage. upstart -> systemd translation is straightforward. But I feel adding an abstract layer makes services more "standard". |
About systemd services, those should be more automatized starting from the sal services. Otherwise it becomes annoying to write services. Using an helper function like mkSystemdService = salService: otherOptions: ... |
I can agree here.
Ok we need some security definitions. But i have to think here, managing users will not be everywhere(os x, user services). @nbp @lethalman do you have any idea how we could do this without defining users in sal? |
I would like to work on that when we solve this is done in some way.
Yes, but user managment, this is not part of sal services. Sal has to provide required deffinitions for security, so systemd will be able to define users. And yes in that case i should also add service dependencies in sal, but that's not such a big problem i guess. |
It is a very nice feature, and this PR is just small enough to try to But I guess it is OK if it is clear how to add this when/if this is |
Well, a global transition with the minorities losing is one thing (and I looked at just extracting service definitions from our current NixOS |
About user name being second class citizen: in a sense, it is a second Maybe this could be handled less radically, but the distinction is
Well, there will always be modules that can be made to work only inside Either these have to be made pseudo-SAL-services with little plans for Or NixOS will have its own service list with some of the services being (I currently care only about SAL and don't care for NixOS-with-SystemD |
While we talk about annoyance... I guess we need to consider templatability of both SAL part and SystemD Writing services from scratch is already more annoying (relative to just |
Thanks for all the ideas so far, i'm working on something that would try to cover everything from security, dependencies and data(directories) in a as general way as possible while not trying to overcomplicate everything. |
I tried to abstract the SAL. I started by reasoning that systemd is probably the most complete process supervisor and as such all other supervisors will implement subsets of what systemd does. The systemd manual says:
Let's draw lines:
Abstraction:
These options could be abstracted as follows:
The SAL services should be functions that take a configuration and return an attrset with e.g.:
Note that So... Relative to the current mongod example, the Note that the Thoughts on this? |
Systemd assumes to much and at the same time limits portability on anything but systemd. Docker has to deal with data volumes(where services store their data) and ports exposion betwene services, so let's think out of the systemd box(because it's really just a very limited box).
I have sockets now, will still have to figure how to deal with dbus, still thanks for reminder.
That's not something sal will deal with, sal is only about definitions. I think it's not too hard to add multy service support.
true
It does not, but it knows what features are supported by process manager.
That's up to process manager implementation that will be using sal. In docker, clearly services will not be abstracted like this. Still thanks for idea for later implementation.
Sal services are schema definitions and not a function, how you implement them is up to process managers.
Thanks, i forgot for oneshot services, will add them.
I'm working on abstraction that will define for each phase what privileges are needed, so no direct definition of this (limited) systemd speciffic option. This was mostly for directory creation in systemd and i'm abstraction storage too. I have to add things i'm working on:
|
canFork = mkOption { | ||
default = false; | ||
type = types.bool; | ||
description = "Whether process mananager can fork."; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you mean "whether process manager can handle forking daemons."?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, i'm adding a quite more flags, for different features.
On Dec 16, 2014 5:42 PM, "wmertens" notifications@github.com wrote:
In services/services.nix
#5246 (diff):
+let
+in {
- options = {
- sal.services = mkOption {
default = {};
type = types.attrsOf types.optionSet;
options = [ serviceOptions ];
description = "Definition of systemd service units.";
- };
- sal.processManager = {
canFork = mkOption {
default = false;
type = types.bool;
description = "Whether process mananager can fork.";
Do you mean "whether process manager can handle forking daemons."?
—
Reply to this email directly or view it on GitHub
https://github.com/NixOS/nixpkgs/pull/5246/files#r21911916.
I was really just looking for a list of all things a supervisor could handle, looks like indeed systemd doesn't directly support those two use cases but neither does Docker really... either way glue code is needed no?
Hmmm... so you'd give the SAL functions a
I was afraid that would cause supervisor-specific code into the services. It would be nice to write a service definition and have it work on new supervisors without change. Unfounded fear?
Yeah I was focusing too much on an abstracted interface at the filesystem level, but indeed that's not necessary because we control the supervisor as well as the service. So all you need is the service information and then the supervisor can implement it somehow.
Please push changes 😁. So, how do you envision the workflow for a user that wants to run nginx as himself for development, or e.g. a CMS deployment via nixpkgs on an Ubuntu server? |
As I understood, there is a decision to make, whether SAL tries to express as little as definitely necessary or as much as can be specified in a portable way (so the service config generator can make its own decision about what information to use — without needing any more data in the simple cases). |
93846b4
to
b319132
Compare
Fixed bugs with supervisord and docker. Assertions are now handled properly(and better) and not dependant on nixos assertions. You can test now with going to
This will create configuration and supervisord wrapper scripts in bin directory:
You can do the same with docker+fig by going to
To run: |
Do you have some ideas how services with different process managers(nixos+systemd, supervisord, docker+fig...) could be tested on all of them(format of tests, debugging of tests,...) ? Testing is really critical feature that has to be in service abstraction layer. |
1cdfff6
to
0b3f89b
Compare
0b3f89b
to
539e58b
Compare
787a61a
to
af797a9
Compare
Hey @offlinehacker this is also something I'd really like to see. How can I help? |
Any progress on this? |
@offlinehacker is this something you're still working on, or this became stale? |
I'm closing this pull request, as after two years of dealing with docker, kubernetes and other containarized environments, i have much better idea how nix-services should be designed. Now all i need is a bit of time, which i would have to take, because it's something we need quite urgent on gatehub and proteuslabs. This work is from my perspecitve obsolete. |
@offlinehacker if it's obsolete, do you have something better? Curious where we should take this going forward |
@copumpkin yes we should, I have some cool ideas, especially related with docker/kubernetes and other cluster technologies. I have built nix-kubernetes, but this is just abstraction over kubernetes. I want to make nix-services environment independant and cluster aware. The only problem is limited amount of time I have, if you have some time we can discuss how to push this forward. |
Yeah, I'll check out your nix-kubernetes to see what you've done. It's mostly just been frustrating me to use |
I hope you all saw https://github.com/LnL7/nix-darwin |
@domenkozar nice General idea is abstraction for different runtime environments, we could reuse module systems as backends for these environments. |
Idea
Let's abstract services, so they can be used independently by different process manager like supervisord, docker,... and not only by systemd.
Preface
I really like nixos and module definition schema, and i really like to write nixos services. As a developer i want to make these services portable betwene systems independently of process managers if that is possible for speciffic service. Current systemd interface is not right approach and only results in hacks to support its interface(like https://github.com/kiberpipa/nix-rehash/tree/master/nix-services).
Problems with using systemd interface
Problem with using systemd interface as a base for service definitions for other process managers is that service definitions use all features of systemd, even that other process managers do not support them. There are not sufficient nixos options to support lack or presence of if:
Implementation
Prototype implementation present in this pull request wants to solve this by abstracting services out of nixos. The reason for abstracting out is that services will not be only used in nixos, but also in other scearios with other process manager and with abscence of nixos on different systems, distros, process virtualization solutions like docker.
Because of lack of better idea i defined
sal
(service abstraction layer) interface abstracted into newservice
directory tree. There, service options/configurations are defined and process manager options are present. Real implementation of this schema is present in nixos systemd, which usessal
as a base for services.I should mention that proposed solution is not usefull for all services and is not ment to replace systemd interface, which is by the way really nice and has a lot of features.
Alternative implemenations
More straightforward solution would be to make something like
users.services
interface, for defining services. This has a downside, and does not take in account which features different process managers support.I would really need this now
I want to ask you, whether you like the proposed implementation or if you have any better idea how to implement this. I would really like to solve the problem, because i need it to make user services and docker implementation using this or similar interface. Without this i can only make hacked implementations(that people use and depend on), like https://github.com/kiberpipa/nix-rehash/tree/master/nix-services, that i later don't want to support, because of hackiness involved.
So please review the prototype and please propose better implementations and let's make nix services as portable as possible :)
@edolstra @rbvermaa @nbp @iElectric @lethalman @wmertens