Skip to content

Latest commit

 

History

History
212 lines (153 loc) · 8.19 KB

DEVELOPERS.md

File metadata and controls

212 lines (153 loc) · 8.19 KB

Development on puppet-agent module

Welcome to the puppet-agent module! This is a document which will help guide you to getting started on development. The key sections here are:

  1. Iterative code changes
  2. Important files to understand repo
  3. Other tools for development
  4. Testing

Iterative code changes

Docker workflow

Iterative development is the practice of reducing the amount of time between making a code change and seeing the result of that change. Below are a few methods to do this style of development.

For iterative development using Docker, see:

  • docker/bin/upgrade.sh
  • docker/bin/versions.sh Ubuntu
  • docker/ubuntu/Dockerfile CentOS
  • docker/centos/Dockerfile

Note: This will not start systemd services due to a limitation in Docker. It will upgrade packages properly, and should be useful for the majority of development on the module.

VMPooler workflow

  1. Forward your ssh key to do github operations.
  2. Ensure editor supports editing remote files.
  3. Checkout a vmpooler machine.
  4. Clone the module.
  5. Run puppet apply to test it as you work.

Development for Puppet Enterprise exclusive platforms

Manual testing workflow

  1. Install an "old" PE on a master (typically RHEL).
  2. Declare the pe_repo classes for each agent you're testing upgrades for (e.g. like Windows, Fedora, etc.) using the PE Console.
  3. Install a "new" PE on the same master.
  4. Run puppet agent so that the pe_repo platforms have the new agent package.
  5. Copy local puppetlabs-puppet_agent module over to the /etc/puppetlabs/code/environment/production/modules directory.
  6. Install any module dependencies on the master via puppet module install (which you can get from the metadata.json file).
  7. Grab a VM to use as the agent, either in a local hypervisor or in VCloud.
  8. Test an upgrade scenario by installing the "old" agent by curling the old PE's install.bash script onto the agent VM and running puppet agent -t to link up with the master. Make sure to sign the agent’s CSR on the master.
  9. Declare the puppet_agent class in the site manifest (site.pp) declaring the master's agent as the puppet agent version for the agent node. Use the version returned by the master’s aio_agent_version fact.
  10. On the agent node, run puppet agent -t.
  11. To check that the upgrade was performed successfully, check the aio_agent_version fact on the agent to see if it matches what's reported on the master.

Important files to understand repo

These are a few key files to look at to understand the basic flow of how the repository works:

  • manifests/init.pp -- This is the entrypoint for the module. This file describes the module's parameters, includes other classes(e.g. prepare and install), and adds some exception cases for a variety of platforms.
  • templates/do_install.sh.erb -- This calls the other scripts in the same directory.

Other tools for development

This ad-hoc job can be used to run CI against a branch here.

This link/job may be updated with a new workflow in the near future.

Testing

Prior to committing any changes, ensure the tests pass locally.

Getting Started

Our Puppet modules provide Gemfiles, which can tell a Ruby package manager such as bundler what Ruby packages, or Gems, are required to build, develop, and test this software.

Please make sure you have bundler installed on your system, and then use it to install all dependencies needed for this project in the project root by running

% bundle install --path .bundle/gems
Fetching gem metadata from https://rubygems.org/........
Fetching gem metadata from https://rubygems.org/..
Using rake (10.1.0)
Using builder (3.2.2)
-- 8><-- many more --><8 --
Using rspec-system-puppet (2.2.0)
Using serverspec (0.6.3)
Using rspec-system-serverspec (1.0.0)
Using bundler (1.3.5)
Your bundle is complete!
Use `bundle show [gemname]` to see where a bundled gem is installed.

NOTE: some systems may require you to run this command with sudo.

If you already have those gems installed, make sure they are up-to-date:

% bundle update

Running Tests

With all dependencies in place and up-to-date, run the tests:

Unit Tests

% bundle exec rake spec

This executes all the rspec tests in the directories defined here and so on. rspec tests may have the same kind of dependencies as the module they are testing. Although the module defines these dependencies in its metadata.json, rspec tests define them in .fixtures.yml.

Acceptance Tests

Some Puppet modules also come with acceptance tests, which use beaker. These tests spin up a virtual machine under VirtualBox, controlled with Vagrant, to simulate scripted test scenarios. In order to run these, you need both Virtualbox and Vagrant installed on your system.

Run the tests by issuing the following command

% bundle exec rake spec_clean
% bundle exec rspec spec/acceptance

This will now download a pre-fabricated image configured in the default node-set, install Puppet, copy this module, and install its dependencies per spec/spec_helper_acceptance.rb and then run all the tests under spec/acceptance.

Writing Tests

Unit Tests

When writing unit tests for Puppet, rspec-puppet is your best friend. It provides tons of helper methods for testing your manifests against a catalog (e.g. contain_file, contain_package, with_params, etc). It would be ridiculous to try and top rspec-puppet's documentation but here's a tiny sample:

Sample manifest:

file { "a test file":
  ensure => present,
  path   => "/etc/sample",
}

Sample test:

it 'does a thing' do
  expect(subject).to contain_file("a test file").with({:path => "/etc/sample"})
end

Acceptance Tests

Writing acceptance tests for Puppet involves beaker and its cousin beaker-rspec. A common pattern for acceptance tests is to create a test manifest, apply it twice to check for idempotency or errors, then run expectations.

More information about beaker and beaker-puppet is [here][https://github.com/puppetlabs/puppetlabs-puppet_agent/tree/master/acceptance].

it 'does an end-to-end thing' do
  pp = <<-EOF
    file { 'a test file':
      ensure  => present,
      path    => "/etc/sample",
      content => "test string",
    }

  apply_manifest(pp, :catch_failures => true)
  apply_manifest(pp, :catch_changes => true)

end

describe file("/etc/sample") do
  it { is_expected.to contain "test string" }
end

If you have commit access to the repository

Even if you have commit access to the repository, you still need to go through the process above, and have someone else review and merge in your changes. The rule is that all changes must be reviewed by a project developer that did not write the code to ensure that all changes go through a code review process.

The record of someone performing the merge is the record that they performed the code review. Again, this should be someone other than the author of the topic branch.

Get Help

On the web

On chat

  • Slack (slack.puppet.com) #forge-modules, #puppet-dev, #windows, #voxpupuli