Skip to content

Commit e6687f8

Browse files
committed
WIP/RFC: Add run_agent task
1 parent 10f437e commit e6687f8

File tree

9 files changed

+400
-8
lines changed

9 files changed

+400
-8
lines changed

.fixtures.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ fixtures:
1212
git: 'https://github.com/theforeman/puppet-git.git'
1313
inifile: 'https://github.com/puppetlabs/puppetlabs-inifile.git'
1414
puppetdb: 'https://github.com/puppetlabs/puppetlabs-puppetdb.git'
15+
ruby_task_helper: 'https://github.com/puppetlabs/puppetlabs-ruby_task_helper.git'
1516
stdlib: 'https://github.com/puppetlabs/puppetlabs-stdlib.git'
1617
systemd: 'https://github.com/camptocamp/puppet-systemd.git'
1718
yumrepo_core:

.sync.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,16 @@
1313
Rakefile:
1414
param_docs_pattern:
1515
- manifests/init.pp
16+
Gemfile:
17+
extra:
18+
- gem: bolt
19+
version: '~> 1.15'
20+
# TODO: Add something to foreman-installer-modulesync to support `unless ENV['PUPPET_VERSION'] =~ /^5/`
21+
options:
22+
groups:
23+
- 'system_tests'
24+
- gem: beaker-task_helper
25+
version: '~> 1.7'
26+
options:
27+
groups:
28+
- 'system_tests'

.travis.yml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ matrix:
1616
env:
1717
- BEAKER_PUPPET_COLLECTION=puppet5
1818
- BEAKER_setfile=centos7-64{hostname=centos7-64.example.com}
19-
script: bundle exec rake beaker
19+
script: bundle exec rake spec_prep beaker
2020
services: docker
2121
bundler_args: --without development
2222
before_install:
@@ -27,7 +27,7 @@ matrix:
2727
env:
2828
- BEAKER_PUPPET_COLLECTION=puppet6
2929
- BEAKER_setfile=centos7-64{hostname=centos7-64.example.com}
30-
script: bundle exec rake beaker
30+
script: bundle exec rake spec_prep beaker
3131
services: docker
3232
bundler_args: --without development
3333
before_install:
@@ -38,7 +38,7 @@ matrix:
3838
env:
3939
- BEAKER_PUPPET_COLLECTION=puppet5
4040
- BEAKER_setfile=centos6-64{hostname=centos6-64.example.com}
41-
script: bundle exec rake beaker
41+
script: bundle exec rake spec_prep beaker
4242
services: docker
4343
bundler_args: --without development
4444
before_install:
@@ -49,7 +49,7 @@ matrix:
4949
env:
5050
- BEAKER_PUPPET_COLLECTION=puppet6
5151
- BEAKER_setfile=centos6-64{hostname=centos6-64.example.com}
52-
script: bundle exec rake beaker
52+
script: bundle exec rake spec_prep beaker
5353
services: docker
5454
bundler_args: --without development
5555
before_install:
@@ -60,7 +60,7 @@ matrix:
6060
env:
6161
- BEAKER_PUPPET_COLLECTION=puppet5
6262
- BEAKER_setfile=debian9-64{hostname=debian9-64.example.com}
63-
script: bundle exec rake beaker
63+
script: bundle exec rake spec_prep beaker
6464
services: docker
6565
bundler_args: --without development
6666
before_install:
@@ -71,7 +71,7 @@ matrix:
7171
env:
7272
- BEAKER_PUPPET_COLLECTION=puppet6
7373
- BEAKER_setfile=debian9-64{hostname=debian9-64.example.com}
74-
script: bundle exec rake beaker
74+
script: bundle exec rake spec_prep beaker
7575
services: docker
7676
bundler_args: --without development
7777
before_install:

Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,5 +37,7 @@ gem 'beaker-puppet_install_helper', {"groups"=>["system_tests"]}
3737
gem 'metadata-json-lint'
3838
gem 'kafo_module_lint'
3939
gem 'parallel_tests'
40+
gem 'bolt', '~> 1.15', {"groups"=>["system_tests"]} unless ENV['PUPPET_VERSION'] =~ /^5/
41+
gem 'beaker-task_helper', '~> 1.7', {"groups"=>["system_tests"]}
4042

4143
# vim:ft=ruby

spec/acceptance/puppetserver_latest_spec.rb

Lines changed: 92 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
require 'spec_helper_acceptance'
2+
require 'beaker-task_helper/inventory'
3+
require 'bolt_spec/run'
24

35
describe 'Scenario: install puppetserver (latest):' do
46
before(:context) do
@@ -22,11 +24,99 @@ class { '::puppet':
2224
server_external_nodes => '',
2325
# only for install test - don't think to use this in production!
2426
# https://docs.puppet.com/puppetserver/latest/tuning_guide.html
25-
server_jvm_max_heap_size => '256m',
26-
server_jvm_min_heap_size => '256m',
27+
server_jvm_max_heap_size => '256m',
28+
server_jvm_min_heap_size => '256m',
29+
server_max_active_instances => 1,
2730
}
2831
EOS
2932
end
3033

3134
it_behaves_like 'a idempotent resource'
35+
36+
describe 'run_agent task' do
37+
include Beaker::TaskHelper::Inventory
38+
include BoltSpec::Run
39+
40+
def bolt_config
41+
{ 'modulepath' => File.join(File.dirname(File.expand_path(__FILE__)), '../', 'fixtures', 'modules') }
42+
end
43+
44+
def bolt_inventory
45+
hosts_to_inventory
46+
end
47+
48+
context 'with empty catalog' do
49+
before do
50+
sleep 10
51+
end
52+
it 'applies and changes nothing' do
53+
results = run_task('puppet::run_agent', 'agent', {})
54+
expect(results.first).to include('status' => 'success')
55+
expect(results.first['result']['detailed_exitcode']).to eq 0
56+
expect(results.first['result']['last_run_summary']['changes']['total']).to eq 0
57+
end
58+
end
59+
60+
context 'with basic site.pp' do
61+
before do
62+
on default, 'mkdir -p /etc/puppetlabs/code/environments/production/manifests'
63+
on default, 'echo "node default { notify {\'test\':}}" > /etc/puppetlabs/code/environments/production/manifests/site.pp'
64+
end
65+
describe 'running task with --noop' do
66+
it 'changes nothing and reports noop events' do
67+
results = run_task('puppet::run_agent', 'agent', '_noop' => true)
68+
expect(results.first).to include('status' => 'success')
69+
expect(results.first['result']['detailed_exitcode']).to eq 0
70+
expect(results.first['result']['last_run_summary']['changes']['total']).to eq 0
71+
expect(results.first['result']['last_run_summary']['events']['noop']).to eq 1
72+
end
73+
end
74+
describe 'running task without --noop' do
75+
it 'applies changes' do
76+
results = run_task('puppet::run_agent', 'agent', {})
77+
expect(results.first).to include('status' => 'success')
78+
expect(results.first['result']['detailed_exitcode']).to eq 2
79+
expect(results.first['result']['last_run_summary']['changes']['total']).to eq 1
80+
expect(results.first['result']['last_run_summary']['events']['success']).to eq 1
81+
end
82+
end
83+
end
84+
context 'with invalid puppet_settings' do
85+
it 'returns failure' do
86+
results = run_task('puppet::run_agent', 'agent', 'puppet_settings' => { 'foo' => 'bar' })
87+
expect(results.first).to include('status' => 'failure')
88+
end
89+
end
90+
context 'with invalid manifest' do
91+
before do
92+
on default, 'echo "NOT A MANIFEST" > /etc/puppetlabs/code/environments/production/manifests/site.pp'
93+
end
94+
it 'returns failure' do
95+
results = run_task('puppet::run_agent', 'agent', {})
96+
expect(results.first).to include('status' => 'failure')
97+
expect(results.first['result']['_error']['details']['detailed_exitcode']).to eq 1
98+
end
99+
end
100+
context 'overriding environment' do
101+
before do
102+
on default, 'mkdir -p /etc/puppetlabs/code/environments/test/manifests'
103+
on default, 'echo "node default { file {\'/tmp/overriding_environment_test\': ensure => \'file\'}}" > /etc/puppetlabs/code/environments/test/manifests/site.pp'
104+
end
105+
it 'applies changes' do
106+
results = run_task('puppet::run_agent', 'agent', 'puppet_settings' => { 'environment' => 'test' })
107+
expect(results.first).to include('status' => 'success')
108+
expect(results.first['result']['detailed_exitcode']).to eq 2
109+
expect(results.first['result']['last_run_summary']['changes']['total']).to eq 1
110+
expect(results.first['result']['last_run_summary']['events']['success']).to eq 1
111+
end
112+
it 'is idempotent' do
113+
results = run_task('puppet::run_agent', 'agent', 'puppet_settings' => { 'environment' => 'test' })
114+
expect(results.first).to include('status' => 'success')
115+
expect(results.first['result']['detailed_exitcode']).to eq 0
116+
end
117+
describe file('/tmp/overriding_environment_test') do
118+
it { should exist }
119+
end
120+
end
121+
end
32122
end

spec/spec_helper_acceptance.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
ENV['BEAKER_setfile'] ||= 'centos7-64{hostname=centos7-64.example.com}'
66
ENV['BEAKER_HYPERVISOR'] ||= 'docker'
77

8+
require 'bolt/pal'
9+
Bolt::PAL.load_puppet
10+
811
require 'beaker-puppet'
912
require 'beaker-rspec'
1013
require 'beaker/puppet_install_helper'

spec/tasks/run_agent_spec.rb

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
require 'spec_helper'
2+
require_relative '../../tasks/run_agent.rb'
3+
4+
describe 'RunAgentTask' do
5+
let(:task) { RunAgentTask.new }
6+
let(:mock_sucess_result) do
7+
{
8+
result: 'The run succeeded with no changes or failures; the system was already in the desired state (or --noop was used).',
9+
stdout: 'STDOUT',
10+
stderr: 'STDERR',
11+
detailed_exitcode: 0,
12+
last_run_summary: {}
13+
}
14+
end
15+
let(:default_puppet_opts) do
16+
{
17+
onetime: true,
18+
verbose: true,
19+
daemonize: false,
20+
usecacheonfailure: false,
21+
'detailed-exitcodes': true,
22+
splay: false,
23+
show_diff: true,
24+
noop: false
25+
}
26+
end
27+
28+
context 'default options' do
29+
it 'runs the puppet agent' do
30+
expect(task).to receive(:validate_puppet_settings).with({})
31+
expect(task).to receive(:check_running_as_root)
32+
expect(task).to receive(:check_agent_not_disabled)
33+
expect(task).to receive(:wait_for_puppet_lockfile)
34+
expect(task).to receive(:run_puppet).with(default_puppet_opts).and_return(mock_sucess_result)
35+
expect(task.task).to eq(mock_sucess_result)
36+
end
37+
end
38+
context 'with usecacheonfailure puppet_setting' do
39+
let(:params) { { puppet_settings: { usecacheonfailure: true } } }
40+
let(:expected_puppet_opts) do
41+
{
42+
onetime: true,
43+
verbose: true,
44+
daemonize: false,
45+
usecacheonfailure: true,
46+
'detailed-exitcodes': true,
47+
splay: false,
48+
show_diff: true,
49+
noop: false
50+
}
51+
end
52+
it 'runs the puppet agent' do
53+
expect(task).to receive(:validate_puppet_settings).with(usecacheonfailure: true)
54+
expect(task).to receive(:check_running_as_root)
55+
expect(task).to receive(:check_agent_not_disabled)
56+
expect(task).to receive(:wait_for_puppet_lockfile)
57+
expect(task).to receive(:run_puppet).with(expected_puppet_opts).and_return(mock_sucess_result)
58+
expect(task.task(params)).to eq(mock_sucess_result)
59+
end
60+
end
61+
end

tasks/run_agent.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"description": "Runs the puppet agent",
3+
"supports_noop": true,
4+
"files": ["ruby_task_helper/files/task_helper.rb"],
5+
"input_method": "stdin",
6+
"parameters": {
7+
"puppet_bin": {
8+
"description": "The full path to the puppet binary. Defaults to `'/opt/puppetlabs/bin/puppet'`.",
9+
"type": "Optional[Stdlib::Absolutepath]"
10+
},
11+
"wait_time": {
12+
"description": "How many seconds should the task wait for an existing puppet run to finish. Defaults to `300` (5 minutes).",
13+
"type": "Optional[Integer[0]]"
14+
},
15+
"puppet_settings": {
16+
"description": "An optional hash of puppet configuration settings. These can be used to override puppet's defaults, settings in puppet.conf and default settings included with `--test`.",
17+
"type": "Optional[Hash]"
18+
}
19+
}
20+
}

0 commit comments

Comments
 (0)