Ask Your Question

Writing modules: detecting package manager and init system

asked 2015-10-17 20:05:33 -0600

Rikken gravatar image

Say, I want to write a module which installs a package, and runs a service. I want to include most OS-es (well, Linuxes at least). For this, I need to know:

  • the package manager in use (am I going to add a yum or an apt repo?)
  • the init system in use (am I going to add config for SysV, upstart, systemd?)

... now, Puppets documentation for packages and for services just claim 'Puppet will usually find this out on its own', however, as I need to code adding that repo, or figure out which init config file to put where, does it actually expose this kind of information anywhere? Looking through facts & code, I don't see it anywhere, and looking at some mature modules they all seem to re-invent the wheel in checking operating systems & going for what should be default there. So, in short, my question is:

  • Does Puppet itself expose this kind of information anywhere in a module?
  • And if not, is there a module specifically to do this, which I can use?

... because basically, having just an if $::packagemanager == 'yum' or if $::initsystem == 'upstart' does seem a whole lot cleaner than an entire tree of $::osfamily stuff, with all the possible version comparisons as well.

edit retag flag offensive close merge delete

4 Answers

Sort by ยป oldest newest most voted

answered 2015-10-20 16:41:27 -0600

rnelson0 gravatar image

Package managers allow you to include more than just your software but a ton of metadata and scripts and service config. Look at fpm and bundle everything into one package, then install that with a simple:

package {'whatever':
  ensure => present,

You can host the packages in a repo and ensure the repo is present, also through puppet, or allow users to state repo locations. Or use the rpm/dpkg providers and use the source parameter, but then you don't get dependency installation.

Trying to auto-detect all of this via Puppet is the first step on the road to insanity. Puppet models state that you declare, it's not great at determining what state to model. Build packages for your supported OSes and include some instructions if someone wants to build for another OS (even if private, future-you will appreciate that), distribute as needed. If you need some tips for how to set up build targets and such, there's the fpm wiki and I wrote up a few tips at my blog.

edit flag offensive delete link more


I know about package repos, and already have yum & deb repos running, I just need to know whether there is a more generic way of detecting them than a full OS-decision tree/switch. Same for init system (even harder as the default for an OS-version combo might not be what is actually in use).

Rikken gravatar imageRikken ( 2015-10-20 17:32:52 -0600 )edit

Let's say, in short: is there a generic way to decide between calling apt::source or yumrepo without having to reinvent the wheel yet again with the decision tree present in oh so many modules. There's enough inspection going on in Puppet, both internally, and with facts, why would it be insanity?

Rikken gravatar imageRikken ( 2015-10-20 17:37:18 -0600 )edit

Just drop your repo in /etc/apt/sources.list.d if there's a /usr/bin/apt-get present? Do the same for systemctl. For many other decisions, finer grained control is needed. You may need to provide different pkg's for different OS-releases, for instance. Design for your expected future.

hvm gravatar imagehvm ( 2015-10-23 04:56:56 -0600 )edit

Existence of a systemctl binary doesn't inidicate which init system is running. Nor does the existence of yum & apt-get indicate which of the 2 is in use (although it's very rare to have them both of course). But, what you're saying is: yes Rikken, you will need to write your own tests yet again.

Rikken gravatar imageRikken ( 2015-10-30 10:11:28 -0600 )edit

Check using "systemctl is-system-running", or check for existing packages using "dpkg -l" to be sure. There could still be differences between distro's using RPM or between, say, Debian and Ubuntu that are relevant to you. Are you sure your package will run on *any* version, even in the future?

hvm gravatar imagehvm ( 2015-12-01 08:17:17 -0600 )edit

answered 2016-04-26 16:09:54 -0600

Emerson Prado gravatar image

I have the same problem: I need to know the init system to choose the correct action.
I can think about some different paths:
1. Create a custom fact
2. Find a module which does it
3. Ask Puppet of Facter developers to add a standard fact exposing the init system
For the first way, I should learn Ruby first. I can try, but who knows when I can get something done...
I found a module which claim just that - - But, in fact, it assumes the init system based on OS version, so we're back to the start problem. Maybe we could start a feature request. I have just entered Puppet community, so I'm grasping its ways still.
Hope this gives some starter.
Best regards,

edit flag offensive delete link more

answered 2015-10-19 08:46:26 -0600

It shouldn't be needed. Have a Google on types and providers. If you're writing for a rare or new os then maybe consider it..Else puppet will figure it for you.

edit flag offensive delete link more


Of course I need it: in my package I only have the binary, and I need to know whether to write stuff to /etc/init.d/my-service or something to /etc/systemd/system/my-service.service for instance. And to get the binary even there: do I need to add an apt or yum repo?

Rikken gravatar imageRikken ( 2015-10-19 09:10:20 -0600 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools



Asked: 2015-10-17 20:05:33 -0600

Seen: 518 times

Last updated: Oct 22 '15