How to fetch a remote file (e.g. from Github) in a Puppet file resource?

Profpatsch picture Profpatsch · Sep 17, 2013 · Viewed 37.8k times · Source
file { 'leiningen': 
    path => '/home/vagrant/bin/lein',
    ensure => 'file',
    mode => 'a+x',
    source => 'https://raw.github.com/technomancy/leiningen/stable/bin/lein',
}

was my idea, but Puppet doesn’t know http://. Is there something about puppet:// I have missed?

Or if not, is there a way to declaratively fetch the file first and then use it as a local source?

Answer

rdoyle picture rdoyle · Sep 17, 2013

Before Puppet 4.4, as per http://docs.puppetlabs.com/references/latest/type.html#file, the file source only accepts puppet:// or file:// URIs.

As of Puppet 4.4+, your original code would be possible.

If you're using an older version, one way to achieve what you want to do without pulling down the entire Git repository would be to use the exec resource to fetch the file.

exec{'retrieve_leiningen':
  command => "/usr/bin/wget -q https://raw.github.com/technomancy/leiningen/stable/bin/lein -O /home/vagrant/bin/lein",
  creates => "/home/vagrant/bin/lein",
}

file{'/home/vagrant/bin/lein':
  mode => 0755,
  require => Exec["retrieve_leiningen"],
}

Although the use of exec is somewhat frowned upon, it can be used effectively to create your own types. For example, you could take the snippet above and create your own resource type.

define remote_file($remote_location=undef, $mode='0644'){
  exec{"retrieve_${title}":
    command => "/usr/bin/wget -q ${remote_location} -O ${title}",
    creates => $title,
  }

  file{$title:
    mode    => $mode,
    require => Exec["retrieve_${title}"],
  }
}

remote_file{'/home/vagrant/bin/lein':
  remote_location => 'https://raw.github.com/technomancy/leiningen/stable/bin/lein',
  mode            => '0755',
}