From 9da1994f7da7e15cab5835ed7347a0476554576f Mon Sep 17 00:00:00 2001 From: Daniel Dreier Date: Fri, 20 Mar 2015 19:22:11 -0700 Subject: [PATCH 1/5] Add basic rspec-puppet tests for puppetserver --- spec/classes/server_spec.rb | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/spec/classes/server_spec.rb b/spec/classes/server_spec.rb index 4441e32..024262a 100644 --- a/spec/classes/server_spec.rb +++ b/spec/classes/server_spec.rb @@ -25,7 +25,7 @@ let(:facts) { facthash } context "running on #{name}" do - ['standalone','passenger','unicorn','thin'].each do |server_type| + ['standalone','passenger','unicorn','thin','puppetserver'].each do |server_type| context "servertype => #{server_type}" do let(:params) {{ :servertype => server_type, @@ -76,12 +76,20 @@ should contain_service('thin-puppetmaster').with({:ensure => "running"}) should contain_file('/etc/thin.d/puppetmaster.yml') } + when 'puppetserver' + it { + should contain_class('puppet::server::puppetserver') + should contain_service('puppetmaster').with({ :ensure => "stopped" }) + should contain_service('puppetserver').with({:ensure => "running"}) + should contain_package('puppetserver') + } end end end context "manage_package => false" do let(:params) {{ :manage_package => false }} + it { should_not contain_package('puppetserver') } case facthash['osfamily'] when 'RedHat' it { should_not contain_package('puppet-server') } From 9a648fe673f5ceaa8da1ec7a613332b4c7ea216a Mon Sep 17 00:00:00 2001 From: Daniel Dreier Date: Fri, 20 Mar 2015 19:35:39 -0700 Subject: [PATCH 2/5] Add beaker tests for puppetserver functionality Provide rudimentary tests for installing puppetserver. Not expected to pass yet. This is likely to run into memory size issues because beaker VMs are created with 512mb and I'm not aware of an obvious way to change that. --- spec/acceptance/puppetserver_server_spec.rb | 22 +++++++++++++++++++++ spec/spec_helper_acceptance.rb | 21 ++++++++++++++++++++ 2 files changed, 43 insertions(+) create mode 100644 spec/acceptance/puppetserver_server_spec.rb diff --git a/spec/acceptance/puppetserver_server_spec.rb b/spec/acceptance/puppetserver_server_spec.rb new file mode 100644 index 0000000..12f2c22 --- /dev/null +++ b/spec/acceptance/puppetserver_server_spec.rb @@ -0,0 +1,22 @@ +require 'spec_helper_acceptance' + +describe 'server', :unless => UNSUPPORTED_PLATFORMS.include?(fact('osfamily')) do + context 'running on puppetserver', :servertype => 'puppetserver', :webserver => 'puppetserver' do + it 'should run with no errors' do + pp = <<-EOS + class { 'puppet::server': + servertype => 'puppetserver', + ca => true, + } + EOS + + # Run it twice and test for idempotency + apply_manifest(pp, :catch_failures => true) + expect(apply_manifest(pp, :catch_failures => true).exit_code).to be_zero + end + + it_behaves_like "basic working puppetmaster" + it_behaves_like "puppetserver-based master" + + end +end diff --git a/spec/spec_helper_acceptance.rb b/spec/spec_helper_acceptance.rb index 2eeeb1a..6f7bf32 100644 --- a/spec/spec_helper_acceptance.rb +++ b/spec/spec_helper_acceptance.rb @@ -99,3 +99,24 @@ it { should_not be_running } end end + +shared_examples_for "puppetserver-based master" do + describe package('puppetserver') do + it { should be_installed } + end + + describe service('nginx') do + it { should_not be_enabled } + it { should_not be_running } + end + + describe service('puppetmaster') do + it { should_not be_enabled } + it { should_not be_running } + end + + describe service('puppetserver') do + it { should be_enabled } + it { should be_running } + end +end From b02a285ee8a228efe3574c745ceb2bbc7a1acd7f Mon Sep 17 00:00:00 2001 From: Daniel Dreier Date: Fri, 20 Mar 2015 20:07:20 -0700 Subject: [PATCH 3/5] add puppetserver-specific items to params.pp --- manifests/params.pp | 74 +++++++++++++++++++++++++-------------------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/manifests/params.pp b/manifests/params.pp index 69c1873..5af673f 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -85,42 +85,50 @@ } $default_value = { - agent_package => 'puppet', - agent_service => 'puppet', - agent_service_conf => '/etc/default/puppet', - default_method => 'cron', - master_package => 'puppetmaster', - master_service => 'puppetmaster', - puppet_cmd => '/usr/bin/puppet', - puppet_conf => '/etc/puppet/puppet.conf', - puppet_confdir => '/etc/puppet', - puppet_logdir => '/var/log/puppet', - puppet_rundir => '/var/run/puppet', - puppet_ssldir => '/var/lib/puppet/ssl', - puppet_user => 'puppet', - puppet_group => 'puppet', - puppet_vardir => '/var/lib/puppet', - report_dir => '/usr/lib/ruby/vendor_ruby/puppet/reports', + agent_package => 'puppet', + agent_service => 'puppet', + agent_service_conf => '/etc/default/puppet', + default_method => 'cron', + master_package => 'puppetmaster', + master_service => 'puppetmaster', + puppet_cmd => '/usr/bin/puppet', + puppet_conf => '/etc/puppet/puppet.conf', + puppet_confdir => '/etc/puppet', + puppet_group => 'puppet', + puppet_logdir => '/var/log/puppet', + puppet_rundir => '/var/run/puppet', + puppet_ssldir => '/var/lib/puppet/ssl', + puppet_user => 'puppet', + puppet_vardir => '/var/lib/puppet', + puppetserver_bootstrap_conf => '/etc/puppetserver/bootstrap.cfg', + report_dir => '/usr/lib/ruby/vendor_ruby/puppet/reports', + server_package => 'puppetserver', + server_service => 'puppetserver', + server_service_conf => '/etc/default/puppetserver', } $merged_values = merge($default_value, $os_specific) - $agent_package = $merged_values[agent_package] - $agent_service = $merged_values[agent_service] - $agent_service_conf = $merged_values[agent_service_conf] - $agent_use = $merged_values[agent_use] - $default_method = $merged_values[default_method] - $master_package = $merged_values[master_package] - $master_service = $merged_values[master_service] - $master_use = $merged_values[master_use] - $puppet_cmd = $merged_values[puppet_cmd] - $puppet_conf = $merged_values[puppet_conf] - $puppet_confdir = $merged_values[puppet_confdir] - $puppet_group = $merged_values[puppet_group] - $puppet_logdir = $merged_values[puppet_logdir] - $puppet_rundir = $merged_values[puppet_rundir] - $puppet_ssldir = $merged_values[puppet_ssldir] - $puppet_user = $merged_values[puppet_user] - $puppet_vardir = $merged_values[puppet_vardir] + $agent_package = $merged_values[agent_package] + $agent_service = $merged_values[agent_service] + $agent_service_conf = $merged_values[agent_service_conf] + $agent_use = $merged_values[agent_use] + $default_method = $merged_values[default_method] + $master_package = $merged_values[master_package] + $master_service = $merged_values[master_service] + $master_use = $merged_values[master_use] + $puppet_cmd = $merged_values[puppet_cmd] + $puppet_conf = $merged_values[puppet_conf] + $puppet_confdir = $merged_values[puppet_confdir] + $puppet_group = $merged_values[puppet_group] + $puppet_logdir = $merged_values[puppet_logdir] + $puppet_rundir = $merged_values[puppet_rundir] + $puppet_ssldir = $merged_values[puppet_ssldir] + $puppet_user = $merged_values[puppet_user] + $puppet_vardir = $merged_values[puppet_vardir] + $puppetserver_bootstrap_conf = $merged_values[puppetserver_bootstrap_conf] + $server_package = $merged_values[server_package] + $server_service = $merged_values[server_service] + $server_service_conf = $merged_values[server_service_conf] } From b37e82762f650b62c6df24a0422e05cad3993cd9 Mon Sep 17 00:00:00 2001 From: Daniel Dreier Date: Fri, 20 Mar 2015 22:57:31 -0700 Subject: [PATCH 4/5] Add basic puppetserver support Configure a basic puppetserver. This puts just enough configuration in place to get a basic running instance. Some of the configuration parameters are not implemented yet; they're placeholders to facilitate future development. --- manifests/params.pp | 10 ++ manifests/server.pp | 5 +- manifests/server/puppetserver.pp | 180 +++++++++++++++++++++++++++++++ tests/puppetserver.pp | 4 + 4 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 manifests/server/puppetserver.pp create mode 100644 tests/puppetserver.pp diff --git a/manifests/params.pp b/manifests/params.pp index 5af673f..ec7a0e4 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -101,6 +101,11 @@ puppet_user => 'puppet', puppet_vardir => '/var/lib/puppet', puppetserver_bootstrap_conf => '/etc/puppetserver/bootstrap.cfg', + puppetserver_config_dir => '/etc/puppetserver/conf.d', + puppetserver_install_dir => '/usr/share/puppetserver', + puppetserver_logback_conf => '/etc/puppetserver/logback.xml', + puppetserver_java => '/usr/bin/java', + puppetserver_gem_home => '/var/lib/puppet/jruby-gems', report_dir => '/usr/lib/ruby/vendor_ruby/puppet/reports', server_package => 'puppetserver', server_service => 'puppetserver', @@ -130,5 +135,10 @@ $server_package = $merged_values[server_package] $server_service = $merged_values[server_service] $server_service_conf = $merged_values[server_service_conf] + $puppetserver_install_dir = $merged_values[puppetserver_install_dir] + $puppetserver_config_dir = $merged_values[puppetserver_config_dir] + $puppetserver_java = $merged_values[puppetserver_java] + $puppetserver_logback_conf = $merged_values[puppetserver_logback_conf] + $puppetserver_gem_home = $merged_values[puppetserver_gem_home] } diff --git a/manifests/server.pp b/manifests/server.pp index 820833d..92b9433 100644 --- a/manifests/server.pp +++ b/manifests/server.pp @@ -103,8 +103,11 @@ 'standalone': { include puppet::server::standalone } + 'puppetserver': { + include puppet::server::puppetserver + } default: { - err('Only "passenger", "thin", "unicorn" and "standalone" are valid options for servertype') + err('Only "puppetserver", "passenger", "thin", "unicorn" and "standalone" are valid options for servertype') fail('Servertype "$servertype" not implemented') } } diff --git a/manifests/server/puppetserver.pp b/manifests/server/puppetserver.pp new file mode 100644 index 0000000..badc124 --- /dev/null +++ b/manifests/server/puppetserver.pp @@ -0,0 +1,180 @@ +# puppet::server::puppetserver configures the master using the new JVM puppet server +# Puppet Server is pre-release and not recommended for production use yet +# See https://github.com/puppetlabs/puppet-server/blob/master/documentation/install_from_packages.markdown for basic +# manual install documentation + +# This class should not normally be used directly. + +# TODO: Add support for external SSL termination +# https://github.com/puppetlabs/puppet-server/blob/master/documentation/external_ssl_termination.markdown + +# TODO: Add ability to configure stuff from: +# https://github.com/puppetlabs/puppet-server/blob/master/documentation/configuration.markdown +# - where JRuby will look for gems +# - path to puppet conf dir +# - path to puppet var dir +# - maximum number of JRuby instances to allow; defaults to +2 +# - enable/disable the CA service via trapperkeeper settings +# - configure logging via logback + +# Note that OpenBSD support is blocking on https://tickets.puppetlabs.com/browse/SERVER-14 + +# parameters +# descriptions largely copied from official docs at +# https://github.com/puppetlabs/puppet-server/blob/master/documentation/configuration.markdown +# [*memory*] - (optional) set JVM memory use; 2gb recommended by default +# format is "2gb", "512m", etc. +# [*max_active_instances*] - (optional) maximum number of JRuby instances to allow +# [*logging_config*] - (optional) Path to logback logging configuration file +# http://logback.qos.ch/manual/configuration.html +# [*gem_home*] - (optional) determines where JRuby will look for gems. Also +# used by the `puppetserver gem` command line tool. +# [*master_conf_dir*] - (optional) path to puppet conf dir +# [*master_var_dir*] - (optional) path to puppet var dir +# [*enable_profiler*] - (optional) enable or disable profiling for the Ruby code +# (true|false) +# [*allow_header_cert_info - (optional) Allows the "ssl_client_header" and +# (true|false) "ssl_client_verify_header" options set in +# puppet.conf to work. These headers will be +# ignored unless "allow-header-cert-info" is true + +# puppetserver.conf is in HOCON format, which is a superset of JSON: +# - https://github.com/puppetlabs/puppet-server/blob/master/documentation/configuration.markdown +# - https://github.com/typesafehub/config#using-hocon-the-json-superset +# puppet-puppet will use https://github.com/puppetlabs/puppetlabs-hocon to +# manage hocon settings because that appears to be the approach the puppetserver +# developers have chosen to support + +class puppet::server::puppetserver ( + # aside from memory (defaults to 2g), these are the puppetserver defaults + # Setting them here makes it easier to anticipate behavior + $enabled = true, + $memory_pct = 70, + $memory = undef, + $max_active_instances = $::processorcount + 2, + $logging_config = $puppet::params::puppetserver_logback_conf, + $gem_home = $puppet::params::puppetserver_gem_home, + $master_conf_dir = $puppet::params::puppet_confdir, + $master_var_dir = $puppet::params::puppet_vardir, + $enable_profiler = false, + $allow_header_cert_info = false, + $bootstrap_cfg = $puppet::params::puppetserver_bootstrap_conf, +) { + + include puppet + include puppet::server + + # Calculate JVM memory based on percentage if specified + # Should JVM settings be their own class? + if ($memory_pct != undef) and ($memory != undef) { + fail('memory and memory_pct cannot both be set at the same time') + } + if ($memory_pct != undef) and ($memory == undef) { + $rounded_mem = floor($::memorysize_mb * $memory_pct * 0.01) + $jvm_memory = "${rounded_mem}m" + } + if ($memory_pct == undef) and ($memory != undef) { + $jvm_memory = $memory + } + + $service_ensure = $enabled? { + true => 'running', + default => 'stopped', + } + + Ini_subsetting { + ensure => present, + section => '', + key_val_separator => '=', + quote_char => '"', + path => $puppet::params::server_service_conf, + setting => 'JAVA_ARGS', + notify => Service[$puppet::params::server_service], + } + + ini_subsetting {'puppetserver_xmx_memory': + subsetting => '-Xmx', + value => $jvm_memory, + } + ini_subsetting {'puppetserver_xms_memory': + subsetting => '-Xms', + value => $jvm_memory, + } + ini_subsetting {'puppetserver_maxpermsize': + subsetting => '-XX:MaxPermSize=', + value => '256m', + } + # JAVA_ARGS="-Xms2776m -Xmx2776m -XX:MaxPermSize=256m" + Ini_setting { + ensure => present, + path => $puppet::params::server_service_conf, + key_val_separator => '=', + section => '', + } + ini_setting { "JAVA_BIN": + setting => 'JAVA_BIN', + value => "\"${puppet::params::puppetserver_java}\"", + } + ini_setting { "USER": + setting => 'USER', + value => "\"${puppet::params::puppet_user}\"", + } + ini_setting { "INSTALL_DIR": + setting => 'INSTALL_DIR', + value => "\"${puppet::params::puppetserver_install_dir}\"", + } + ini_setting { "CONFIG": + setting => 'CONFIG', + value => "\"${puppet::params::puppetserver_config_dir}\"", + } + ini_setting { "BOOTSTRAP_CONFIG": + setting => 'BOOTSTRAP_CONFIG', + value => "\"${puppet::params::puppetserver_bootstrap_conf}\"", + } + ini_setting { "SERVICE_STOP_RETRIES": + setting => 'SERVICE_STOP_RETRIES', + value => '60', + } + + # disable the trapperkeeper-based CA service entirely if this isn't a CA node + $ca_disable_ensure = $puppet::params::ca? { + false => 'present', + default => 'absent', + } + $ca_enable_ensure = $puppet::params::ca? { + false => 'absent', + default => 'present', + } + file_line { 'disable_puppetserver_ca': + ensure => $ca_disable_ensure, + path => $puppet::params::puppetserver_bootstrap_conf, + line => 'puppetlabs.services.ca.certificate-authority-disabled-service/certificate-authority-disabled-service', + require => Package[$puppet::params::server_package], + } + file_line { 'enable_puppetserver_ca': + ensure => $ca_enable_ensure, + path => $puppet::params::puppetserver_bootstrap_conf, + line => 'puppetlabs.services.ca.certificate-authority-service/certificate-authority-service', + require => Package[$puppet::params::server_package], + } + + service { $puppet::params::server_service: + ensure => $service_ensure, + enable => $enabled, + hasstatus => false, + pattern => 'puppet-server-release.jar', # yeah, this is embarassing + require => [Class['puppet::server::config'], + Class['puppet::server::standalone'], + Package[$puppet::params::server_package]], + } + + # stop regular puppet master to avoid conflicting binds on port 8140 + if $enabled == true { + package { $puppet::params::server_package: + ensure => $puppet::server::ensure; + } + class { 'puppet::server::standalone': + enabled => false + } + } +} diff --git a/tests/puppetserver.pp b/tests/puppetserver.pp new file mode 100644 index 0000000..8fb74a0 --- /dev/null +++ b/tests/puppetserver.pp @@ -0,0 +1,4 @@ +class { 'puppet::server': + servertype => 'puppetserver', + ca => true, +} From 3ba358ca162a8f94aea5e6af121b47d8e2beb9e1 Mon Sep 17 00:00:00 2001 From: Daniel Dreier Date: Sat, 21 Mar 2015 16:05:44 -0700 Subject: [PATCH 5/5] Set puppetserver_maxpermsize conditionally Based on @igalic's suggestion, this sets the puppetserver_maxpermsize ini subsetting conditionally based on java version if the java_major_version fact from the puppetlabs-java module is available. --- manifests/server/puppetserver.pp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/manifests/server/puppetserver.pp b/manifests/server/puppetserver.pp index badc124..c42b7f2 100644 --- a/manifests/server/puppetserver.pp +++ b/manifests/server/puppetserver.pp @@ -100,8 +100,21 @@ subsetting => '-Xms', value => $jvm_memory, } + + # test for java_major_version fact, and assume we'll use defaults if it's not found + # this allows us to use puppetlabs-java's fact if available without adding a hard + # dependency on it + if $::java_major_version { + $perm = $::java_major_version ? { + 8 => '-XX:MaxMetaspaceSize=', + default => '-XX:MaxPermSize=', + } + } else { + $perm = '-XX:MaxPermSize=' + } + ini_subsetting {'puppetserver_maxpermsize': - subsetting => '-XX:MaxPermSize=', + subsetting => $perm, value => '256m', } # JAVA_ARGS="-Xms2776m -Xmx2776m -XX:MaxPermSize=256m"