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.

I'm trying to automatically provision VMs with docker pre-installed.

My default init.pp looks like:

class { 'apt':
 always_apt_update    => true,

package { [
  ensure  => 'installed',

apt::ppa { 'ppa:dotcloud/lxc-docker':}

# refresh apt source
exec { "apt-update":
  command => "/usr/bin/apt-get update && apt-get install lxc-docker --force-yes",
  returns => 100

The last exec command returns (return 100 is default for a successful apt-get update I think):

info: /Stage[main]//Apt::Ppa[ppa:dotcloud/lxc-docker]/Exec[add-apt-repository-ppa:dotcloud/lxc-docker]: Scheduling refresh of Exec[apt_update] notice: /Stage[main]/Apt::Update/Exec[apt_update]/returns: executed successfully notice: /Stage[main]/Apt::Update/Exec[apt_update]: Triggered 'refresh' from 1 events

However when I ssh into the box docker is not installed and running apt-get install lxc-docker I can then install it. What am I doing wrong? I can't seem to get it working with a multitude of different configurations.

share|improve this question
add comment

1 Answer

up vote 7 down vote accepted

apt-get returns 0 on success and 100 on error, as you can easily see from the apt-get man page. So you've got that backwards. You are combining two commands using &&, which means the second command is only run when the first completes successfully (returning 0). So if apt-get update were to return "100", as you wrongly expect, the second command wouldn't even run.

And if you read the log message carefully you'll see that the Exec resource applied is named "apt_update" and not "apt-update". The former is defined in the apt class and run when the apt::ppa resource is applied. The latter is your own Exec resource, which would also appear in the log output, but as Exec[apt-update]. Look for that.

In any case, what you constructed here does not work because you are trying to use Puppet as a glorified Shell script and doing it wrong. Puppet ignores the order in which you specify resources in the manifest and instead applies them in the way it sees fit. So to make sure the lxc-docker package get installed from the specified PPA you need to make sure the PPA resource is applied before the package resource.

There are a few ways to do that, all of them involving that you specify relationships or dependencies. Here's one way, using chaining arrows:

class { 'apt':
 always_apt_update => true,

apt::ppa { 'ppa:dotcloud/lxc-docker':}

# Your regular packages don't know or care about the PPA
package { [
  ensure  => 'installed',

# We single lxc-docker out to be able to specify 
# the relationship to Apt::Ppa properly
package { 'lxc-docker':
  ensure => 'installed'

Apt::Ppa['ppa:dotcloud/lxc-docker'] ->

This means that the lxc-docker package resource will be applied after the apt::ppa resource for the PPA "ppa:dotcloud/lxc-docker" has been applied. As explained the apt::ppa resource already takes care of updating the APT cache after adding a PPA, so there is no need for explicitly calling apt-get update anywhere.

share|improve this answer
add comment

Your Answer


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.