Ask Your Question

How do I modify a user, who has a service running?

asked 2015-11-12 06:40:43 -0600

martin.gerdes gravatar image

updated 2015-11-23 09:00:21 -0600

I am just starting out with puppet. I took the Package, since it was suggested in the tutorial. After reading about how you should organize your code, I decided I liked the profile/role model:

So I defined a common profile, and added the ntp module to it. Works, great. But I noticed that the home dir of ntp was not how I have configured our servers until now: Its set to /home/ntp, which does not exist, which tiger complains about. Well, I am just learning, so I think this is a good opportunity to try out the advantages of the profile/role model, leave the ntp module as is, and correct the users home dir afterwards.

However, a simple

user { 'ntp'
  ensure => 'present',
  home => '/var/lib/ntp'

results in the error:

change from /home/ntp to /var/cache/ntp failed: Could not set home on user[ntp]: Execution of '/usr/sbin/usermod -d /var/cache/ntp ntp' returned 8: usermod: user ntp is currently used by process 5584
So this does not work because the ntp service is running. A bit of googling found me this bug: Yeah, an "obstruction" parameter would be awesome...

So I now ended up doing this:

class profile::common (
) {
    if $ntp_client {
        class { '::ntp':
            server_options=>" burst"
        #stop ntp and set its homedir if set to something else ->puppet will restart ntp
        exec { '/etc/init.d/ntp stop && usermod -d /var/lib/ntp ntp':
            unless => '/usr/bin/test "`egrep "^ntp:" /etc/passwd | cut -f 6 -d:`" = /var/lib/ntp'

This actually works perfectly well!

However, I am just starting out with puppet, as I said. Is this really the best way to solve this? It does not seem very puppet like to me, I am hard coding the commands and recreating puppets test logic. But I have found no way to trigger a command to be executed before (not after ->notify) a change is made...

So, what is the best practice for something like this?


As suggested, I tried to do it using require (I actually had tried something similar before, relying on ordering):

#the ntp class sets the ntp home dir wrong - fix it (puppet will restart ntp)
user { 'ntp':
    ensure => 'present',
    home => '/var/lib/ntp',
    require => Exec['stop ntp if wrong home dir'],
exec { 'stop ntp if wrong home dir':
    command => '/etc/init.d/ntp stop',
    unless => '/usr/bin/test ~ntp = /var/lib/ntp',

Starting ntp via exec is both wrong (the suggested condition would not match anymore - the home dir has changed), and unnecessary: puppet notices that ntp has been stopped, and starts it again by itself.

However, this is also the problem preventing me from using this solution.

Executing 'puppet agent -t' on the client gives me:

Info: Retrieving pluginfacts
Info: Retrieving plugin
Info: Caching catalog for admintestvm.local
Info: Applying configuration version '1448289413'
Notice ...
edit retag flag offensive close merge delete

2 Answers

Sort by ยป oldest newest most voted

answered 2015-11-12 11:14:05 -0600

could you try forcelocal => true under the home entry?

edit flag offensive delete link more



user { 'ntp':
    ensure => 'present',
    home => '/var/lib/ntp',
    forcelocal => true
I get
Error: Could not set home on user[ntp]: Execution of '/usr/sbin/usermod -d /var/lib/ntp ntp' returned 8: usermod: user ntp is currently used by process 23653

martin.gerdes gravatar imagemartin.gerdes ( 2015-11-13 02:25:48 -0600 )edit

So no change at all. Which is what I would expect: forcelocal forces puppet to manage the user account - which puppet is already doing, it's just failing at it.

martin.gerdes gravatar imagemartin.gerdes ( 2015-11-13 02:35:34 -0600 )edit

answered 2015-11-13 09:05:22 -0600

scoffland gravatar image

updated 2015-11-13 09:09:23 -0600

The least convoluted way I can think of to do this would be with execs, and that is not really the puppet way.

user { 'ntp':
  ensure => 'present',
  home => '/var/lib/ntp',
  require => Exec['/etc/init.d/ntp stop'],
  before => Exec['/etc/init.d/ntp start'],

exec { '/etc/init.d/ntp stop':
  unless => '/usr/bin/test "`egrep "^ntp:" /etc/passwd | cut -f 6 -d:`" = /var/lib/ntp',
exec { '/etc/init.d/ntp start':
  unless => '/usr/bin/test "`egrep "^ntp:" /etc/passwd | cut -f 6 -d:`" = /var/lib/ntp',

Notify the service is the puppet way to do things but this would not stop the service until a task was completed and then restart it after.

edit flag offensive delete link more


I had already tried this. Tried it again using code close to yours. Works, but I don't think it works safely, but only because of a race condition. I have edited my question to include that possible (but in my opinion unreliable) solution. Still, thanks a lot for your answer!

martin.gerdes gravatar imagemartin.gerdes ( 2015-11-23 08:58:31 -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

1 follower


Asked: 2015-11-12 05:24:13 -0600

Seen: 761 times

Last updated: Nov 23 '15