From da976905e08f6718bfcca72e76563a5953d42e29 Mon Sep 17 00:00:00 2001 From: Ben Roberts Date: Mon, 20 Sep 2021 22:33:50 +0100 Subject: [PATCH] Support multiple envs_dir directories This module adds support for the puppet environmentpath setting to be configured using multiple directories. An example use-case is where r10k is in use to deploy some but not all environments, to avoid unmanaged environments being purged by r10k. Directories (whether one, or multiple) are passed as an Array of Stdlib::Absolutepath values. This is a breaking change, as a single string will no longer be accepted. - Each listed environmentpath directory will be created and managed by puppet - The default post-receive hook script uses the first listed directory in `envs_dir` to create initial environments to maintain backward compatibility. Tests are included to ensure that all listed directories are created and managed. Fixes #708 --- manifests/init.pp | 4 ++-- manifests/params.pp | 4 ++-- manifests/server.pp | 7 +++++-- manifests/server/config.pp | 5 +++-- spec/classes/puppet_server_spec.rb | 17 +++++++++++++++++ templates/server/post-receive.erb | 2 +- 6 files changed, 30 insertions(+), 9 deletions(-) diff --git a/manifests/init.pp b/manifests/init.pp index fd3466da7..3b242580a 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -288,7 +288,7 @@ # # $server_environment_timeout:: Timeout for cached compiled catalogs (10s, 5m, ...) # -# $server_envs_dir:: Directory that holds puppet environments +# $server_envs_dir:: List of directories which hold puppet environments # # $server_envs_target:: Indicates that $envs_dir should be # a symbolic link to this target @@ -656,7 +656,7 @@ String $server_environments_owner = $puppet::params::server_environments_owner, Optional[String] $server_environments_group = $puppet::params::server_environments_group, Pattern[/^[0-9]{3,4}$/] $server_environments_mode = $puppet::params::server_environments_mode, - Stdlib::Absolutepath $server_envs_dir = $puppet::params::server_envs_dir, + Array[Stdlib::Absolutepath, 1] $server_envs_dir = $puppet::params::server_envs_dir, Optional[Stdlib::Absolutepath] $server_envs_target = $puppet::params::server_envs_target, Variant[Undef, String[0], Array[Stdlib::Absolutepath]] $server_common_modules_path = $puppet::params::server_common_modules_path, Pattern[/^[0-9]{3,4}$/] $server_git_repo_mode = $puppet::params::server_git_repo_mode, diff --git a/manifests/params.pp b/manifests/params.pp index ec00747d9..4eab6d509 100644 --- a/manifests/params.pp +++ b/manifests/params.pp @@ -241,10 +241,10 @@ $server_environments_group = $root_group $server_environments_mode = '0755' # Where we store our puppet environments - $server_envs_dir = "${codedir}/environments" + $server_envs_dir = ["${codedir}/environments"] $server_envs_target = undef # Modules in this directory would be shared across all environments - $server_common_modules_path = unique(["${server_envs_dir}/common", "${codedir}/modules", "${sharedir}/modules", '/usr/share/puppet/modules']) + $server_common_modules_path = unique(["${server_envs_dir[0]}/common", "${codedir}/modules", "${sharedir}/modules", '/usr/share/puppet/modules']) # Dynamic environments config, ignore if the git_repo is 'false' # Path to the repository diff --git a/manifests/server.pp b/manifests/server.pp index 763423d10..d80ad45eb 100644 --- a/manifests/server.pp +++ b/manifests/server.pp @@ -70,7 +70,10 @@ # # $environments_mode:: Environments directory mode. # -# $envs_dir:: Directory that holds puppet environments +# $envs_dir:: List of directories that hold puppet environments +# All listed directories will be created and attributes managed, +# but only the first listed path will be used to populate +# environments from git repo branches. # # $envs_target:: Indicates that $envs_dir should be # a symbolic link to this target @@ -371,7 +374,7 @@ String $environments_owner = $puppet::server_environments_owner, Optional[String] $environments_group = $puppet::server_environments_group, Pattern[/^[0-9]{3,4}$/] $environments_mode = $puppet::server_environments_mode, - Stdlib::Absolutepath $envs_dir = $puppet::server_envs_dir, + Array[Stdlib::Absolutepath, 1] $envs_dir = $puppet::server_envs_dir, Optional[Stdlib::Absolutepath] $envs_target = $puppet::server_envs_target, Variant[Undef, String[0], Array[Stdlib::Absolutepath]] $common_modules_path = $puppet::server_common_modules_path, Pattern[/^[0-9]{3,4}$/] $git_repo_mode = $puppet::server_git_repo_mode, diff --git a/manifests/server/config.pp b/manifests/server/config.pp index 199f82903..26f4640c5 100644 --- a/manifests/server/config.pp +++ b/manifests/server/config.pp @@ -36,6 +36,7 @@ $server_external_nodes = $puppet::server::external_nodes $server_environment_timeout = $puppet::server::environment_timeout $trusted_external_command = $puppet::server::trusted_external_command + $primary_envs_dir = $puppet::server::envs_dir[0] if $server_external_nodes and $server_external_nodes != '' { class{ 'puppet::server::enc': @@ -56,7 +57,7 @@ puppet::config::main { 'reports': value => $puppet::server::reports; - 'environmentpath': value => $puppet::server::envs_dir; + 'environmentpath': value => $puppet::server::envs_dir.join(':'); } if $puppet::server::hiera_config and !empty($puppet::server::hiera_config){ puppet::config::main { @@ -258,7 +259,7 @@ mode => $puppet::server::git_repo_mode, user => $puppet::server::git_repo_user, group => $puppet::server::git_repo_group, - require => File[$puppet::vardir, $puppet::server::envs_dir], + require => File[$puppet::vardir, $primary_envs_dir], } $git_branch_map = $puppet::server::git_branch_map diff --git a/spec/classes/puppet_server_spec.rb b/spec/classes/puppet_server_spec.rb index 23414a5da..77dcbac0b 100644 --- a/spec/classes/puppet_server_spec.rb +++ b/spec/classes/puppet_server_spec.rb @@ -674,6 +674,23 @@ it { should contain_puppet__config__master('trusted_external_command').with_value('/usr/local/sbin/trusted_external_command') } end end + + describe 'with multiple environment paths' do + let(:params) do + super().merge( + server_envs_dir: ['/etc/puppetlabs/code/environments/', '/etc/puppetlabs/code/unmanaged-environments/'], + server_git_repo_path: '/test/puppet', + server_post_hook_name: 'post-receive', + server_git_repo: true, + ) + end + + it { should contain_puppet__config__main('environmentpath').with_value('/etc/puppetlabs/code/environments/:/etc/puppetlabs/code/unmanaged-environments/') } + it { should contain_file('/etc/puppetlabs/code/environments/') } + it { should contain_file('/etc/puppetlabs/code/unmanaged-environments/') } + it { should contain_git__repo('puppet_repo').that_requires('File[/etc/puppetlabs/code/environments/]') } + it { should contain_file('/test/puppet/hooks/post-receive').with_content(/ENVIRONMENT_BASEDIR\s=\s"\/etc\/puppetlabs\/code\/environments\/"/) } + end end end end diff --git a/templates/server/post-receive.erb b/templates/server/post-receive.erb index 37173b0a5..1a2a9e1ac 100644 --- a/templates/server/post-receive.erb +++ b/templates/server/post-receive.erb @@ -10,7 +10,7 @@ $stdout.sync = true $stderr.sync = true # Set this to where you want to keep your environments -ENVIRONMENT_BASEDIR = "<%= scope.lookupvar("puppet::server::envs_dir") %>" +ENVIRONMENT_BASEDIR = "<%= scope.lookupvar("puppet::server::config::primary_envs_dir") %>" # post-receive hooks set GIT_DIR to the current repository. If you want to # clone from a non-local repository, set this to the URL of the repository,