puppet agent, centos 7 and raspberry pi

There’s no armv7l packages of the puppet agent, so I need to run it from source.

The docs for doing this date back to 3.8. Also helped by this post by Brandon Martin.

I’ll be looking to run the following client version to match my PE install.

# puppet --version


Applicable requirements come from 4.10.

  • Ruby: We currently only test and package with 2.1.x versions of Ruby.
  • Facter 3.1 or later
  • Hiera 2.0.0 or later
  • The json gem (any modern version)
  • The rgen gem version 0.6.6 or later is now required because Puppet parser = future is enabled by default
  • Optional libraries: The msgpack gem is required if you are using msgpack serialization.

Centos 7 has Ruby 2.0.0 as the primary package;  might be other versions hidden under other names or in software collections, but for the moment, I can live with:

Warning: Support for ruby version 2.0.0 is deprecated and will be removed in a future release.

Some packages are needed.

  • Bundler pulls in Ruby.
  • git is needed to pull down the repo, this also installs perl and rsync.
  • ruby-devel is also needed for compiling gems
  • .. as are gcc and make.
yum install rubygem-bundler git ruby-devel gcc make

This fixes:

Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

/usr/bin/ruby extconf.rb 
mkmf.rb can't find header files for ruby at /usr/share/include/ruby.h

Gem files will remain installed in /home/puppeteer/puppetsrc/.bundle/gems/ruby/gems/hpricot-0.8.6 for inspection.
Results logged to /home/puppeteer/puppetsrc/.bundle/gems/ruby/gems/hpricot-0.8.6/ext/fast_xs/gem_make.out
An error occurred while installing hpricot (0.8.6), and Bundler cannot continue.


Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

/usr/bin/ruby extconf.rb 
checking for stdio.h... *** extconf.rb failed ***

Pull down the release

I initially pulled down a tar ball, but then switched to git;  it’ll be easier for changing client versions as needed.

There’s loads of tags for different releases, but to avoid detached HEAD, I’ll start with an existing branch.

Created an account so all this stuff happens under a non-root account.

useradd --create-home --shell /sbin/nologin --uid 1042 --user-group puppeteer
sudo -u puppeteer bash
cd ~/
mkdir puppetsrc
git clone git://github.com/puppetlabs/puppet puppetsrc

There’s some branches .. so we could run with the latest 4.10.x ..

$ git branch --remote
  origin/HEAD -> origin/master
$ git checkout 4.10.x

.. which is a good starting point.

Or, if you want to go direct to a specific version, check out a tag.

$ git checkout 4.10.12

To avoid ‘detached HEAD’, create a local branch based on the tag.

$ git checkout -b 4.10.12 4.10.12


Most/all commands from this point run with a working directory of ~puppeteer/puppetsrc – whether

  • run by root (eg: bundle exec puppet agent) or
  • puppeteer – bundle install etc.


The instructions refer to a .bundle directory within the source tree as, I imagined, a target for stuff to be downloaded. If so that would suggest ..

$ cd puppetsrc
$ grep .bundle .gitignore

bundle install

Final clean run (4.10.x) looked like this.

$ bundle install --path .bundle/gems/
Using rake 12.3.2
Using CFPropertyList 2.2.8
Using addressable 2.4.0
Using artifactory 2.8.2
Using ast 2.4.0
Using builder 3.2.3
Using coderay 1.1.2
Using safe_yaml 1.0.4
Using crack 0.4.3
Using diff-lcs 1.3
Using facter 2.5.1
Using fast_gettext 1.1.2
Using locale 2.1.2
Using text 1.3.1
Using gettext 3.2.9
Using gettext-setup 0.30
Using hashdiff 0.3.7
Using hiera 3.5.0
Using highline 1.6.21
Using trollop 2.9.9
Using hiera-eyaml 2.1.0
Using hocon 1.2.5
Installing hpricot 0.8.6
Installing json-schema 2.1.1
Installing json_pure 1.8.6
Installing metaclass 0.0.4
Installing method_source 0.9.2
Installing mocha 0.10.5
Installing msgpack 1.2.4
Installing multi_json 1.7.7
Installing mustache 1.1.0
Installing net-ssh 4.2.0
Installing packaging 0.99.20
Installing parser
Installing powerpack 0.1.2
Installing pry 0.12.2
Using puppet 4.10.14 from source at .
Installing puppet-lint 2.3.6
Installing puppet-syntax 2.4.1
Installing rspec-support 3.8.0
Installing rspec-core 3.8.0
Installing rspec-expectations 3.8.2
Installing rspec-mocks 3.8.0
Installing rspec 3.8.0
Installing rspec-puppet 2.7.2
Installing puppetlabs_spec_helper 1.1.1
Installing racc 1.4.9
Installing rack 1.6.11
Installing rainbow 2.2.2
Installing rdiscount
Installing rdoc 4.3.0
Installing redcarpet 2.3.0
Installing ronn 0.7.3
Installing rspec-collection_matchers 1.1.3
Installing rspec-its 1.2.0
Installing rspec-legacy_formatters 1.0.1
Installing ruby-progressbar 1.10.0
Installing unicode-display_width 1.4.1
Installing rubocop 0.39.0
Installing ruby-prof 0.17.0
Installing vcr 2.9.3
Installing webmock 1.24.6
Installing yard 0.9.16
Installing yarjuf 2.0.0
Using bundler 1.7.8
Your bundle is complete!
It was installed into ./.bundle/gems
Post-install message from yard:
As of YARD v0.9.2:

RubyGems "--document=yri,yard" hooks are now supported. You can auto-configure
YARD to automatically build the yri index for installed gems by typing:

    $ yard config --gem-install-yri

See `yard config --help` for more information on RubyGems install hooks.

You can also add the following to your .gemspec to have YARD document your gem
on install:

    spec.metadata["yard.run"] = "yri" # use "yard" to build full HTML docs.

$ bundle exec puppet --version

Switch versions

The following checks out a tag as a branch, and then the gems are rebuilt as needed.

git checkout -b 4.10.12 4.10.12
bundle update

Deltas rolling back 4.10.x to 4.10.12 were:

Installing rake 10.1.1 (was 12.3.2)
Using puppet 4.10.12 (was 4.10.14) from source at .

Getting us where we wanted to be.

$ bundle exec puppet --version

Agent first-run

Set up certificate signing, and fire up the client.

# as root
/bin/mkdir -p /etc/puppetlabs/puppet && \
cat >> /etc/puppetlabs/puppet/csr_attributes.yaml <<EOF
  pp_environment: DEV
  pp_role: role::pitest

bundle exec puppet agent --test --waitforcert 20 --certname=$(hostname -f) \
--server=puppet.$(hostname -d) --environment=development

Which worked.  It waited for my puppet master to start up, then for me to sign the cert.  The role wasn’t defined, so my manifests/site.pp abended the catalog run, but otherwise working as designed.

It’ll save a little typing later if I also provide:

# as root
cat >> /etc/puppetlabs/puppet/puppet.conf <<EOF
certname = $(hostname -f)
server = puppet.$(hostname -d)
environment = development

Once the catalog is working, the relevant profile will manage that config anyway.

next steps

  • Testing my existing profiles on this installation
  • Adding profiles to handle this minimal build and pi nuances
  • Do some actual stuff with the machine

Running the client regularly: I’ll do it out of cron to save memory. ‘bundle exec’ is clearly not how it is normally run, so my beginners ruby will need to do some heavy lifting and find a nicer way.

In the first instance, though, I want to get some things running on my new Pis, so running puppet manually to get the build in place isn’t a big deal.

More will be posted with the tags pi and puppet.

bootnote: rspec tests

I tried running the test suite.

bundle exec rspec spec
Finished in 18 minutes 38 seconds (files took 4 minutes 11.9 seconds to load)
1103 examples, 0 failures, 5 pending

I had to terminate it early as it kicks off a bunch of parallel processes and then causes the machine to swap like crazy.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s