Take the 2-minute tour ×
Server Fault is a question and answer site for professional system and network administrators. It's 100% free, no registration required.

Puppet 0.25.4 on ubuntu point blank refuses to execute the following command:

exec {"initiate replica set":
    command => "echo 'rs.initiate()' | mongo",
    path => ["/usr/bin","/usr/sbin","/bin"],
    user => "root",
    require => Class["mongodb"]
}

I can execute the command as root myself, so I'm guessing perhaps it's an issue with the shell. Unfortunately upgrading puppet isn't an option (and causes other issues anyway).

I've tried specifying explicit paths to the binaries instead of relying on the path parameter, and also changing the command to:

"bash -c \"echo 'rs.initiate()' | mongo\""

Still doesn't work.

Any ideas?

I get an error message saying something like "failed to change from notrun to 0"

share|improve this question

3 Answers 3

See what the command actually returns when run as shell from root by running echo $? after running the actual command, probably it returns not 0. If so you need to change the statement to:

exec {"initiate replica set":
    command => "echo 'rs.initiate()' | mongo",
    path => ["/usr/bin","/usr/sbin","/bin"],
    user => "root",
    require => Class["mongodb"],
    returns => $ActualReturnCode
}

Where $ActualReturnCode is the code that you get from echo $? after running the command as root.

There is one more thing about mongodb I forgot to mention - when you install the package it will take some time for the main mongodb database to init, until then you won't be able to access it. Thus the workaround here would be to also add sleep and a number of retries making the code look like:

exec {"initiate replica set":
    command => "echo 'rs.initiate()' | mongo",
    path => ["/usr/bin","/usr/sbin","/bin"],
    user => "root",
    require => Class["mongodb"],
    retries => 5,
    sleep   => 60,
}
share|improve this answer
    
the problem is that it returns 1. i can't work out what shell puppet is using. –  tom Sep 13 '12 at 14:56
    
will if it returns one then you need to replace $ActualReturnCode with 1 making it thus: returns => 1 this should help –  Logic Wreck Sep 13 '12 at 14:59
    
but the command fails. puppet seems to execute the command in a way that means it never runs successfully. –  tom Sep 13 '12 at 15:51
    
Check my last edit - just remembered one thing about mongodb and its puppetization process. –  Logic Wreck Sep 13 '12 at 16:00

One way do it is is:

exec {"initiate replica set":
      command => mongo admin /path/to/init.js",
      path => ["/usr/bin","/usr/sbin","/bin"],
      user => "root",
      require => Class["mongodb"],
      sleep => 60,
      retries => 5,
}

Where the init.js is:

res = rs.initiate()
printjson(res)

This will return 0 if the command was executed without error. Use printjson(res) just for dev/debug mode. Later on you can get rid of it.

Also as Logic Wreck said make sure to use sleep, because initiate can take few seconds to finish.

share|improve this answer

puppet 3 has new syntax for the exec resource type:

http://docs.puppetlabs.com/references/latest/type.html#exec

as such, the code from LogicWreck and Golja is a bit out of date. The parameter retries is now tries and the sleep parameter is now try_sleep.

  exec { 'rs.initiate()':
     command     => 'echo "rs.initiate()" | mongo',
     path        => ['/usr/bin', '/usr/sbin', '/bin'],
     user        => root,
     require     => Service[mongodb],
     tries       => 5,
     try_sleep   => 60,
     unless      => 'echo "rs.status()" | mongo | grep "members"'
  }

You might consider using an 'unless' or 'onlyif' parameter in there so that your resource is only evaluated when first setting up the replica set.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.