r10k 3.7.0 → 3.9.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/pull_request_template.md +1 -1
- data/.github/workflows/docker.yml +4 -1
- data/.github/workflows/release.yml +3 -2
- data/.github/workflows/rspec_tests.yml +1 -1
- data/.github/workflows/stale.yml +19 -0
- data/.travis.yml +8 -1
- data/CHANGELOG.mkd +32 -0
- data/CODEOWNERS +2 -2
- data/doc/common-patterns.mkd +1 -0
- data/doc/dynamic-environments/configuration.mkd +114 -42
- data/doc/dynamic-environments/usage.mkd +12 -11
- data/doc/puppetfile.mkd +23 -3
- data/docker/Gemfile +1 -1
- data/docker/Makefile +4 -3
- data/docker/docker-compose.yml +18 -0
- data/docker/r10k/Dockerfile +1 -1
- data/docker/r10k/docker-entrypoint.sh +0 -1
- data/docker/r10k/release.Dockerfile +1 -1
- data/docker/spec/dockerfile_spec.rb +26 -32
- data/integration/tests/git_source/git_source_repeated_remote.rb +2 -2
- data/integration/tests/user_scenario/basic_workflow/multi_env_custom_forge_git_module.rb +2 -1
- data/integration/tests/user_scenario/basic_workflow/multi_env_custom_forge_git_module_static.rb +2 -1
- data/integration/tests/user_scenario/basic_workflow/multi_source_custom_forge_git_module.rb +1 -1
- data/integration/tests/user_scenario/basic_workflow/single_env_custom_forge_git_module.rb +2 -1
- data/lib/r10k/action/base.rb +10 -0
- data/lib/r10k/action/deploy/display.rb +49 -10
- data/lib/r10k/action/deploy/environment.rb +101 -51
- data/lib/r10k/action/deploy/module.rb +54 -30
- data/lib/r10k/action/puppetfile/check.rb +3 -1
- data/lib/r10k/action/puppetfile/install.rb +20 -23
- data/lib/r10k/action/puppetfile/purge.rb +8 -2
- data/lib/r10k/action/runner.rb +33 -0
- data/lib/r10k/cli/deploy.rb +13 -7
- data/lib/r10k/cli/puppetfile.rb +5 -5
- data/lib/r10k/content_synchronizer.rb +83 -0
- data/lib/r10k/deployment.rb +1 -1
- data/lib/r10k/environment/base.rb +29 -2
- data/lib/r10k/environment/git.rb +17 -5
- data/lib/r10k/environment/name.rb +22 -4
- data/lib/r10k/environment/svn.rb +11 -4
- data/lib/r10k/environment/with_modules.rb +46 -30
- data/lib/r10k/git.rb +1 -0
- data/lib/r10k/git/rugged/credentials.rb +39 -2
- data/lib/r10k/initializers.rb +1 -0
- data/lib/r10k/module.rb +1 -1
- data/lib/r10k/module/base.rb +17 -1
- data/lib/r10k/module/forge.rb +29 -11
- data/lib/r10k/module/git.rb +50 -27
- data/lib/r10k/module/local.rb +2 -1
- data/lib/r10k/module/svn.rb +24 -18
- data/lib/r10k/puppetfile.rb +66 -83
- data/lib/r10k/settings.rb +18 -2
- data/lib/r10k/source/base.rb +9 -0
- data/lib/r10k/source/git.rb +18 -7
- data/lib/r10k/source/hash.rb +5 -5
- data/lib/r10k/source/svn.rb +5 -3
- data/lib/r10k/util/cleaner.rb +21 -0
- data/lib/r10k/util/setopts.rb +33 -12
- data/lib/r10k/version.rb +1 -1
- data/locales/r10k.pot +98 -82
- data/r10k.gemspec +1 -1
- data/spec/fixtures/unit/action/r10k_creds.yaml +9 -0
- data/spec/r10k-mocks/mock_source.rb +1 -1
- data/spec/shared-examples/puppetfile-action.rb +7 -7
- data/spec/unit/action/deploy/display_spec.rb +35 -5
- data/spec/unit/action/deploy/environment_spec.rb +199 -38
- data/spec/unit/action/deploy/module_spec.rb +162 -28
- data/spec/unit/action/puppetfile/check_spec.rb +2 -2
- data/spec/unit/action/puppetfile/install_spec.rb +31 -10
- data/spec/unit/action/puppetfile/purge_spec.rb +25 -5
- data/spec/unit/action/runner_spec.rb +48 -1
- data/spec/unit/environment/git_spec.rb +19 -2
- data/spec/unit/environment/name_spec.rb +28 -0
- data/spec/unit/environment/svn_spec.rb +12 -0
- data/spec/unit/environment/with_modules_spec.rb +74 -0
- data/spec/unit/git/rugged/credentials_spec.rb +78 -1
- data/spec/unit/module/forge_spec.rb +21 -13
- data/spec/unit/module/git_spec.rb +63 -8
- data/spec/unit/module_spec.rb +77 -10
- data/spec/unit/puppetfile_spec.rb +63 -60
- data/spec/unit/util/purgeable_spec.rb +2 -8
- data/spec/unit/util/setopts_spec.rb +25 -1
- metadata +11 -12
- data/azure-pipelines.yml +0 -87
data/doc/puppetfile.mkd
CHANGED
@@ -109,11 +109,19 @@ latest version available.
|
|
109
109
|
|
110
110
|
mod 'puppetlabs/apache', :latest
|
111
111
|
|
112
|
+
An explicit type and/or version can be specified using the standard interface,
|
113
|
+
`:type` and `:version`. The `:source` parameter is not supported for individual
|
114
|
+
forge modules and will be ignored.
|
115
|
+
|
116
|
+
mod 'puppetlabs/apache',
|
117
|
+
type: 'forge',
|
118
|
+
version: '6.0.0'
|
119
|
+
|
112
120
|
### Git
|
113
121
|
|
114
122
|
Git repositories that contain a Puppet module can be cloned and used as modules.
|
115
123
|
When Git is used, the module version can be specified by using `:ref`, `:tag`,
|
116
|
-
`:commit`,
|
124
|
+
`:commit`, `:branch`, or the standard interface parameter `:version`.
|
117
125
|
|
118
126
|
When a module is installed using `:ref`, r10k uses some simple heuristics to
|
119
127
|
determine the type of Git object that should be checked out. This can be used
|
@@ -153,6 +161,13 @@ mod 'apache',
|
|
153
161
|
mod 'apache',
|
154
162
|
:git => 'https://github.com/puppetlabs/puppetlabs-apache',
|
155
163
|
:branch => 'docs_experiment'
|
164
|
+
|
165
|
+
# Install puppetlabs/apache and use standard interface parameters pinned to the
|
166
|
+
# '2098a17' commit.
|
167
|
+
mod 'puppetlabs-apache',
|
168
|
+
type: 'git',
|
169
|
+
source: 'https://github.com/puppetlabs/puppetlabs-apache',
|
170
|
+
version: '2098a17'
|
156
171
|
```
|
157
172
|
|
158
173
|
#### Control Repo Branch Tracking
|
@@ -195,8 +210,8 @@ the latest version available in the main SVN repository.
|
|
195
210
|
mod 'apache',
|
196
211
|
:svn => 'https://github.com/puppetlabs/puppetlabs-apache/trunk'
|
197
212
|
|
198
|
-
If an SVN revision number is specified with `:rev
|
199
|
-
SVN revision will be kept checked out.
|
213
|
+
If an SVN revision number is specified with `:rev`, `:revision`, or `:version`,
|
214
|
+
that SVN revision will be kept checked out.
|
200
215
|
|
201
216
|
mod 'apache',
|
202
217
|
:svn => 'https://github.com/puppetlabs/puppetlabs-apache/trunk',
|
@@ -206,6 +221,11 @@ SVN revision will be kept checked out.
|
|
206
221
|
:svn => 'https://github.com/puppetlabs/puppetlabs-apache/trunk',
|
207
222
|
:revision => '154'
|
208
223
|
|
224
|
+
mod 'apache',
|
225
|
+
type: 'svn',
|
226
|
+
source: 'https://github.com/puppetlabs/puppetlabs-apache/trunk',
|
227
|
+
version: '154'
|
228
|
+
|
209
229
|
If the SVN repository requires credentials, you can supply the `:username` and
|
210
230
|
`:password` options.
|
211
231
|
|
data/docker/Gemfile
CHANGED
data/docker/Makefile
CHANGED
@@ -5,12 +5,12 @@ vcs_ref := $(shell git rev-parse HEAD)
|
|
5
5
|
build_date := $(shell date -u +%FT%T)
|
6
6
|
hadolint_available := $(shell hadolint --help > /dev/null 2>&1; echo $$?)
|
7
7
|
hadolint_command := hadolint
|
8
|
-
hadolint_container := hadolint/hadolint:latest
|
8
|
+
hadolint_container := ghcr.io/hadolint/hadolint:latest
|
9
9
|
alpine_version := 3.9
|
10
10
|
export BUNDLE_PATH = $(PWD)/.bundle/gems
|
11
11
|
export BUNDLE_BIN = $(PWD)/.bundle/bin
|
12
12
|
export GEMFILE = $(PWD)/Gemfile
|
13
|
-
export DOCKER_BUILDKIT
|
13
|
+
export DOCKER_BUILDKIT ?= 1
|
14
14
|
|
15
15
|
ifeq ($(IS_RELEASE),true)
|
16
16
|
VERSION ?= $(shell echo $(git_describe) | sed 's/-.*//')
|
@@ -50,8 +50,9 @@ endif
|
|
50
50
|
|
51
51
|
build: prep
|
52
52
|
docker pull alpine:$(alpine_version)
|
53
|
-
docker build \
|
53
|
+
docker buildx build \
|
54
54
|
${DOCKER_BUILD_FLAGS} \
|
55
|
+
--load \
|
55
56
|
--build-arg alpine_version=$(alpine_version) \
|
56
57
|
--build-arg vcs_ref=$(vcs_ref) \
|
57
58
|
--build-arg build_date=$(build_date) \
|
@@ -0,0 +1,18 @@
|
|
1
|
+
version: '3.7'
|
2
|
+
|
3
|
+
services:
|
4
|
+
r10k_check:
|
5
|
+
image: ${R10K_IMAGE:-puppet/r10k}
|
6
|
+
environment:
|
7
|
+
- PUPPERWARE_ANALYTICS_ENABLED=${PUPPERWARE_ANALYTICS_ENABLED:-false}
|
8
|
+
command: 'puppetfile check --verbose --trace --puppetfile test/Puppetfile'
|
9
|
+
volumes:
|
10
|
+
- ${SPEC_DIRECTORY}/fixtures:/home/puppet/test
|
11
|
+
|
12
|
+
r10k_install:
|
13
|
+
image: ${R10K_IMAGE:-puppet/r10k}
|
14
|
+
environment:
|
15
|
+
- PUPPERWARE_ANALYTICS_ENABLED=${PUPPERWARE_ANALYTICS_ENABLED:-false}
|
16
|
+
command: 'puppetfile install --verbose --trace --puppetfile test/Puppetfile'
|
17
|
+
volumes:
|
18
|
+
- ${SPEC_DIRECTORY}/fixtures:/home/puppet/test
|
data/docker/r10k/Dockerfile
CHANGED
@@ -49,7 +49,7 @@ COPY --from=build /workspace/r10k.gem /
|
|
49
49
|
SHELL ["/bin/ash", "-eo", "pipefail", "-c"]
|
50
50
|
# ignore apk and gem pinning
|
51
51
|
# hadolint ignore=DL3018,DL3028
|
52
|
-
RUN chmod a+x /adduser.sh /docker-entrypoint.sh && \
|
52
|
+
RUN chmod a+x /adduser.sh /docker-entrypoint.sh /docker-entrypoint.d/*.sh && \
|
53
53
|
# Add a puppet user to run r10k as for consistency with puppetserver
|
54
54
|
/adduser.sh && \
|
55
55
|
chown -R puppet: /docker-entrypoint.d /docker-entrypoint.sh && \
|
@@ -38,7 +38,7 @@ LABEL org.label-schema.version="$version" \
|
|
38
38
|
SHELL ["/bin/ash", "-eo", "pipefail", "-c"]
|
39
39
|
# ignore apk and gem pinning
|
40
40
|
# hadolint ignore=DL3018,DL3028
|
41
|
-
RUN chmod a+x /adduser.sh /docker-entrypoint.sh && \
|
41
|
+
RUN chmod a+x /adduser.sh /docker-entrypoint.sh /docker-entrypoint.d/*.sh && \
|
42
42
|
/adduser.sh && \
|
43
43
|
chown -R puppet: /docker-entrypoint.d /docker-entrypoint.sh && \
|
44
44
|
apk add --no-cache ruby openssh-client git ruby-rugged curl ruby-dev make gcc musl-dev && \
|
@@ -1,43 +1,37 @@
|
|
1
1
|
require 'rspec/core'
|
2
2
|
require 'fileutils'
|
3
3
|
require 'open3'
|
4
|
+
include Pupperware::SpecHelpers
|
4
5
|
|
5
|
-
SPEC_DIRECTORY = File.dirname(__FILE__)
|
6
|
+
ENV['SPEC_DIRECTORY'] = File.dirname(__FILE__)
|
7
|
+
# unifies volume naming
|
8
|
+
ENV['COMPOSE_PROJECT_NAME'] ||= 'r10k'
|
6
9
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
--trace \
|
15
|
-
--puppetfile test/Puppetfile")
|
16
|
-
end
|
17
|
-
|
18
|
-
before(:all) do
|
19
|
-
@image = require_test_image
|
10
|
+
RSpec.configure do |c|
|
11
|
+
c.before(:suite) do
|
12
|
+
ENV['R10K_IMAGE'] = require_test_image
|
13
|
+
pull_images(['r10k_check','r10k_install'])
|
14
|
+
teardown_cluster()
|
15
|
+
# no certs to preload, but if the suite adds puppetserver, be explicit
|
16
|
+
docker_compose_up(preload_certs: true)
|
20
17
|
end
|
21
18
|
|
22
|
-
after(:
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
it 'should validate the Puppetfile' do
|
27
|
-
result = run_r10k('puppetfile check')
|
28
|
-
container = result[:stdout].chomp
|
29
|
-
wait_on_container_exit(container)
|
30
|
-
expect(get_container_exit_code(container)).to eq(0)
|
31
|
-
emit_log(container)
|
32
|
-
teardown_container(container)
|
19
|
+
c.after(:suite) do
|
20
|
+
teardown_cluster()
|
21
|
+
FileUtils.rm_rf(File.join(ENV['SPEC_DIRECTORY'], 'fixtures', 'modules'))
|
33
22
|
end
|
23
|
+
end
|
34
24
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
25
|
+
describe 'r10k container' do
|
26
|
+
{
|
27
|
+
'r10k_check': 'validate',
|
28
|
+
'r10k_install': 'install',
|
29
|
+
}.each do |container, op|
|
30
|
+
it "should #{op} the Puppetfile" do
|
31
|
+
container = get_service_container(container)
|
32
|
+
wait_on_container_exit(container)
|
33
|
+
expect(get_container_exit_code(container)).to eq(0)
|
34
|
+
emit_log(container)
|
35
|
+
end
|
42
36
|
end
|
43
37
|
end
|
@@ -30,11 +30,11 @@ CONF
|
|
30
30
|
puppetfile = <<-EOS
|
31
31
|
mod 'prod_apache',
|
32
32
|
:git => 'git://github.com/puppetlabs/puppetlabs-apache.git',
|
33
|
-
:
|
33
|
+
:tag => 'v6.0.0'
|
34
34
|
|
35
35
|
mod 'test_apache',
|
36
36
|
:git => 'git://github.com/puppetlabs/puppetlabs-apache.git',
|
37
|
-
:
|
37
|
+
:tag => 'v6.0.0'
|
38
38
|
EOS
|
39
39
|
|
40
40
|
teardown do
|
@@ -27,7 +27,8 @@ stdlib_notify_message_regex = /The test message is:.*one.*=>.*1.*two.*=>.*bats.*
|
|
27
27
|
puppet_file = <<-PUPPETFILE
|
28
28
|
mod "puppetlabs/motd"
|
29
29
|
mod 'puppetlabs/stdlib',
|
30
|
-
:git => 'git://github.com/puppetlabs/puppetlabs-stdlib.git'
|
30
|
+
:git => 'git://github.com/puppetlabs/puppetlabs-stdlib.git',
|
31
|
+
:tag => 'v7.0.1'
|
31
32
|
PUPPETFILE
|
32
33
|
|
33
34
|
puppet_file_path = File.join(git_environments_path, 'Puppetfile')
|
data/integration/tests/user_scenario/basic_workflow/multi_env_custom_forge_git_module_static.rb
CHANGED
@@ -31,7 +31,8 @@ puppet_file = <<-PUPPETFILE
|
|
31
31
|
moduledir '#{@module_path}'
|
32
32
|
mod "puppetlabs/motd"
|
33
33
|
mod 'puppetlabs/stdlib',
|
34
|
-
:git => 'git://github.com/puppetlabs/puppetlabs-stdlib.git'
|
34
|
+
:git => 'git://github.com/puppetlabs/puppetlabs-stdlib.git',
|
35
|
+
:tag => 'v7.0.1'
|
35
36
|
PUPPETFILE
|
36
37
|
|
37
38
|
puppet_file_path = File.join(git_environments_path, 'Puppetfile')
|
@@ -65,7 +65,7 @@ env_structs = {:production => GitEnv.new('/git_repos',
|
|
65
65
|
'/git_repos_alt/environments_alt.git',
|
66
66
|
'/root/environments_alt',
|
67
67
|
'/root/environments_alt/Puppetfile',
|
68
|
-
'mod "puppetlabs/stdlib", :git => "git://github.com/puppetlabs/puppetlabs-stdlib.git"',
|
68
|
+
'mod "puppetlabs/stdlib", :git => "git://github.com/puppetlabs/puppetlabs-stdlib.git", :tag => "v7.0.1"',
|
69
69
|
'/root/environments_alt/manifests/site.pp',
|
70
70
|
create_site_pp(master_certname, stage_env_manifest)
|
71
71
|
),
|
@@ -28,7 +28,8 @@ notify_message_regex = /I am in the production environment/
|
|
28
28
|
puppet_file = <<-PUPPETFILE
|
29
29
|
mod "puppetlabs/motd"
|
30
30
|
mod 'puppetlabs/inifile',
|
31
|
-
:git => 'git://github.com/puppetlabs/puppetlabs-inifile'
|
31
|
+
:git => 'git://github.com/puppetlabs/puppetlabs-inifile',
|
32
|
+
:tag => 'v5.0.1'
|
32
33
|
PUPPETFILE
|
33
34
|
|
34
35
|
puppet_file_path = File.join(git_environments_path, 'Puppetfile')
|
data/lib/r10k/action/base.rb
CHANGED
@@ -10,6 +10,16 @@ module R10K
|
|
10
10
|
|
11
11
|
attr_accessor :settings
|
12
12
|
|
13
|
+
# @param opts [Hash] A hash of options defined in #allowed_initialized_opts
|
14
|
+
# and managed by the SetOps mixin within the Action::Base class.
|
15
|
+
# Corresponds to the CLI flags and options.
|
16
|
+
# @param argv [Enumerable] Typically CRI::ArgumentList or Array. A list-like
|
17
|
+
# collection of the remaining arguments to the CLI invocation (after
|
18
|
+
# removing flags and options).
|
19
|
+
# @param settings [Hash] A hash of configuration loaded from the relevant
|
20
|
+
# config (r10k.yaml).
|
21
|
+
#
|
22
|
+
# @note All arguments will be required in the next major version
|
13
23
|
def initialize(opts, argv, settings = {})
|
14
24
|
@opts = opts
|
15
25
|
@argv = argv
|
@@ -9,17 +9,48 @@ module R10K
|
|
9
9
|
|
10
10
|
include R10K::Action::Deploy::DeployHelpers
|
11
11
|
|
12
|
+
# @param opts [Hash] A hash of options defined in #allowed_initialized_opts
|
13
|
+
# and managed by the SetOps mixin within the Action::Base class.
|
14
|
+
# Corresponds to the CLI flags and options.
|
15
|
+
# @param argv [Enumerable] Typically CRI::ArgumentList or Array. A list-like
|
16
|
+
# collection of the remaining arguments to the CLI invocation (after
|
17
|
+
# removing flags and options).
|
18
|
+
# @param settings [Hash] A hash of configuration loaded from the relevant
|
19
|
+
# config (r10k.yaml).
|
20
|
+
#
|
21
|
+
# @note All arguments will be required in the next major version
|
22
|
+
def initialize(opts, argv, settings = {})
|
23
|
+
super
|
24
|
+
|
25
|
+
@settings = @settings.merge({
|
26
|
+
overrides: {
|
27
|
+
environments: {
|
28
|
+
preload_environments: @fetch,
|
29
|
+
requested_environments: @argv.map { |arg| arg.gsub(/\W/, '_') }
|
30
|
+
},
|
31
|
+
modules: {},
|
32
|
+
output: {
|
33
|
+
format: @format,
|
34
|
+
trace: @trace,
|
35
|
+
detail: @detail
|
36
|
+
},
|
37
|
+
purging: {}
|
38
|
+
}
|
39
|
+
})
|
40
|
+
end
|
41
|
+
|
12
42
|
def call
|
13
43
|
expect_config!
|
14
44
|
deployment = R10K::Deployment.new(@settings)
|
15
45
|
|
16
|
-
if @
|
46
|
+
if @settings.dig(:overrides, :environments, :preload_environments)
|
17
47
|
deployment.preload!
|
48
|
+
deployment.validate!
|
18
49
|
end
|
19
50
|
|
20
|
-
output = { :sources => deployment.sources.map { |source| source_info(source, @
|
51
|
+
output = { :sources => deployment.sources.map { |source| source_info(source, @settings.dig(:overrides, :environments, :requested_environments)) } }
|
21
52
|
|
22
|
-
case @format
|
53
|
+
case @settings.dig(:overrides, :output, :format)
|
23
54
|
when 'json' then json_format(output)
|
24
55
|
else yaml_format(output)
|
25
56
|
end
|
@@ -27,7 +58,7 @@ module R10K
|
|
27
58
|
# exit 0
|
28
59
|
true
|
29
60
|
rescue => e
|
30
|
-
logger.error R10K::Errors::Formatting.format_exception(e, @trace)
|
61
|
+
logger.error R10K::Errors::Formatting.format_exception(e, @settings.dig(:overrides, :output, :trace))
|
31
62
|
false
|
32
63
|
end
|
33
64
|
|
@@ -43,7 +74,7 @@ module R10K
|
|
43
74
|
puts output.to_yaml
|
44
75
|
end
|
45
76
|
|
46
|
-
def source_info(source,
|
77
|
+
def source_info(source, requested_environments = [])
|
47
78
|
source_info = {
|
48
79
|
:name => source.name,
|
49
80
|
:basedir => source.basedir,
|
@@ -52,28 +83,30 @@ module R10K
|
|
52
83
|
source_info[:prefix] = source.prefix if source.prefix
|
53
84
|
source_info[:remote] = source.remote if source.respond_to?(:remote)
|
54
85
|
|
55
|
-
|
86
|
+
select_all_envs = requested_environments.empty?
|
87
|
+
env_list = source.environments.select { |env| select_all_envs || requested_environments.include?(env.name) }
|
56
88
|
source_info[:environments] = env_list.map { |env| environment_info(env) }
|
57
89
|
|
58
90
|
source_info
|
59
91
|
end
|
60
92
|
|
61
93
|
def environment_info(env)
|
62
|
-
|
94
|
+
modules = @settings.dig(:overrides, :environments, :deploy_modules)
|
95
|
+
if !modules && !@settings.dig(:overrides, :output, :detail)
|
63
96
|
env.dirname
|
64
97
|
else
|
65
98
|
env_info = env.info.merge({
|
66
99
|
:status => (env.status rescue nil),
|
67
100
|
})
|
68
101
|
|
69
|
-
env_info[:modules] = env.modules.map { |mod| module_info(mod) } if
|
102
|
+
env_info[:modules] = env.modules.map { |mod| module_info(mod) } if modules
|
70
103
|
|
71
104
|
env_info
|
72
105
|
end
|
73
106
|
end
|
74
107
|
|
75
108
|
def module_info(mod)
|
76
|
-
if @detail
|
109
|
+
if @settings.dig(:overrides, :output, :detail)
|
77
110
|
{ :name => mod.title, :properties => mod.properties }
|
78
111
|
else
|
79
112
|
mod.title
|
@@ -81,7 +114,13 @@ module R10K
|
|
81
114
|
end
|
82
115
|
|
83
116
|
def allowed_initialize_opts
|
84
|
-
super.merge(
|
117
|
+
super.merge({
|
118
|
+
puppetfile: :modules,
|
119
|
+
modules: :self,
|
120
|
+
detail: :self,
|
121
|
+
format: :self,
|
122
|
+
fetch: :self
|
123
|
+
})
|
85
124
|
end
|
86
125
|
end
|
87
126
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'r10k/util/setopts'
|
2
|
+
require 'r10k/util/cleaner'
|
2
3
|
require 'r10k/deployment'
|
3
4
|
require 'r10k/logging'
|
4
5
|
require 'r10k/action/visitor'
|
@@ -13,29 +14,64 @@ module R10K
|
|
13
14
|
|
14
15
|
include R10K::Action::Deploy::DeployHelpers
|
15
16
|
|
17
|
+
# Deprecated
|
16
18
|
attr_reader :force
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
20
|
+
attr_reader :settings
|
21
|
+
|
22
|
+
# @param opts [Hash] A hash of options defined in #allowed_initialized_opts
|
23
|
+
# and managed by the SetOps mixin within the Action::Base class.
|
24
|
+
# Corresponds to the CLI flags and options.
|
25
|
+
# @param argv [Enumerable] Typically CRI::ArgumentList or Array. A list-like
|
26
|
+
# collection of the remaining arguments to the CLI invocation (after
|
27
|
+
# removing flags and options).
|
28
|
+
# @param settings [Hash] A hash of configuration loaded from the relevant
|
29
|
+
# config (r10k.yaml).
|
30
|
+
#
|
31
|
+
# @note All arguments will be required in the next major version
|
32
|
+
def initialize(opts, argv, settings = {})
|
24
33
|
super
|
25
34
|
|
26
|
-
#
|
27
|
-
|
28
|
-
|
35
|
+
# instance variables below are set by the super class based on the
|
36
|
+
# spec of #allowed_initialize_opts and any command line flags. This
|
37
|
+
# gives a preference order of cli flags > config files > defaults.
|
38
|
+
@settings = @settings.merge({
|
39
|
+
overrides: {
|
40
|
+
environments: {
|
41
|
+
requested_environments: @argv.map { |arg| arg.gsub(/\W/,'_') },
|
42
|
+
default_branch_override: @default_branch_override,
|
43
|
+
generate_types: @generate_types || settings.dig(:deploy, :generate_types) || false,
|
44
|
+
preload_environments: true
|
45
|
+
},
|
46
|
+
modules: {
|
47
|
+
requested_modules: [],
|
48
|
+
deploy_modules: @modules,
|
49
|
+
force: !@no_force, # force here is used to make it easier to reason about
|
50
|
+
},
|
51
|
+
purging: {
|
52
|
+
purge_levels: settings.dig(:deploy, :purge_levels) || [],
|
53
|
+
purge_allowlist: read_purge_allowlist(settings.dig(:deploy, :purge_whitelist) || [],
|
54
|
+
settings.dig(:deploy, :purge_allowlist) || [])
|
55
|
+
},
|
56
|
+
output: {}
|
57
|
+
}
|
58
|
+
})
|
29
59
|
end
|
30
60
|
|
31
61
|
def call
|
32
62
|
@visit_ok = true
|
33
63
|
|
34
|
-
|
35
|
-
|
36
|
-
|
64
|
+
begin
|
65
|
+
expect_config!
|
66
|
+
deployment = R10K::Deployment.new(@settings)
|
67
|
+
check_write_lock!(@settings)
|
68
|
+
|
69
|
+
deployment.accept(self)
|
70
|
+
rescue => e
|
71
|
+
@visit_ok = false
|
72
|
+
logger.error R10K::Errors::Formatting.format_exception(e, @trace)
|
73
|
+
end
|
37
74
|
|
38
|
-
deployment.accept(self)
|
39
75
|
@visit_ok
|
40
76
|
end
|
41
77
|
|
@@ -43,15 +79,34 @@ module R10K
|
|
43
79
|
|
44
80
|
private
|
45
81
|
|
82
|
+
def read_purge_allowlist (whitelist, allowlist)
|
83
|
+
whitelist_has_content = !whitelist.empty?
|
84
|
+
allowlist_has_content = !allowlist.empty?
|
85
|
+
case
|
86
|
+
when whitelist_has_content == false && allowlist_has_content == false
|
87
|
+
[]
|
88
|
+
when whitelist_has_content && allowlist_has_content
|
89
|
+
raise R10K::Error.new "Values found for both purge_whitelist and purge_allowlist. Setting " <<
|
90
|
+
"purge_whitelist is deprecated, please only use purge_allowlist."
|
91
|
+
when allowlist_has_content
|
92
|
+
allowlist
|
93
|
+
else
|
94
|
+
logger.warn "Setting purge_whitelist is deprecated; please use purge_allowlist instead."
|
95
|
+
whitelist
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
46
99
|
def visit_deployment(deployment)
|
47
100
|
# Ensure that everything can be preloaded. If we cannot preload all
|
48
101
|
# sources then we can't fully enumerate all environments which
|
49
102
|
# could be dangerous. If this fails then an exception will be raised
|
50
103
|
# and execution will be halted.
|
51
|
-
|
52
|
-
|
104
|
+
if @settings.dig(:overrides, :environments, :preload_environments)
|
105
|
+
deployment.preload!
|
106
|
+
deployment.validate!
|
107
|
+
end
|
53
108
|
|
54
|
-
undeployable = undeployable_environment_names(deployment.environments, @
|
109
|
+
undeployable = undeployable_environment_names(deployment.environments, @settings.dig(:overrides, :environments, :requested_environments))
|
55
110
|
if !undeployable.empty?
|
56
111
|
@visit_ok = false
|
57
112
|
logger.error _("Environment(s) \'%{environments}\' cannot be found in any source and will not be deployed.") % {environments: undeployable.join(", ")}
|
@@ -59,7 +114,7 @@ module R10K
|
|
59
114
|
|
60
115
|
yield
|
61
116
|
|
62
|
-
if @purge_levels.include?(:deployment)
|
117
|
+
if @settings.dig(:overrides, :purging, :purge_levels).include?(:deployment)
|
63
118
|
logger.debug("Purging unmanaged environments for deployment...")
|
64
119
|
deployment.purge!
|
65
120
|
end
|
@@ -67,7 +122,8 @@ module R10K
|
|
67
122
|
if (postcmd = @settings[:postrun])
|
68
123
|
if postcmd.grep('$modifiedenvs').any?
|
69
124
|
envs = deployment.environments.map { |e| e.dirname }
|
70
|
-
|
125
|
+
requested_envs = @settings.dig(:overrides, :environments, :requested_environments)
|
126
|
+
envs.reject! { |e| !requested_envs.include?(e) } if requested_envs.any?
|
71
127
|
postcmd = postcmd.map { |e| e.gsub('$modifiedenvs', envs.join(' ')) }
|
72
128
|
end
|
73
129
|
subproc = R10K::Util::Subprocess.new(postcmd)
|
@@ -81,7 +137,8 @@ module R10K
|
|
81
137
|
end
|
82
138
|
|
83
139
|
def visit_environment(environment)
|
84
|
-
|
140
|
+
requested_envs = @settings.dig(:overrides, :environments, :requested_environments)
|
141
|
+
if !(requested_envs.empty? || requested_envs.any? { |name| environment.dirname == name })
|
85
142
|
logger.debug1(_("Environment %{env_dir} does not match environment name filter, skipping") % {env_dir: environment.dirname})
|
86
143
|
return
|
87
144
|
end
|
@@ -95,28 +152,31 @@ module R10K
|
|
95
152
|
environment.sync
|
96
153
|
logger.info _("Environment %{env_dir} is now at %{env_signature}") % {env_dir: environment.dirname, env_signature: environment.signature}
|
97
154
|
|
98
|
-
if status == :absent || @
|
155
|
+
if status == :absent || @settings.dig(:overrides, :modules, :deploy_modules)
|
99
156
|
if status == :absent
|
100
157
|
logger.debug(_("Environment %{env_dir} is new, updating all modules") % {env_dir: environment.dirname})
|
101
158
|
end
|
102
159
|
|
103
160
|
previous_ok = @visit_ok
|
104
161
|
@visit_ok = true
|
105
|
-
|
162
|
+
|
163
|
+
environment.deploy
|
164
|
+
|
106
165
|
@environment_ok = @visit_ok
|
107
166
|
@visit_ok &&= previous_ok
|
108
167
|
end
|
109
168
|
|
110
|
-
|
169
|
+
|
170
|
+
if @settings.dig(:overrides, :purging, :purge_levels).include?(:environment)
|
111
171
|
if @visit_ok
|
112
172
|
logger.debug("Purging unmanaged content for environment '#{environment.dirname}'...")
|
113
|
-
environment.purge!(:recurse => true, :whitelist => environment.whitelist(@
|
173
|
+
environment.purge!(:recurse => true, :whitelist => environment.whitelist(@settings.dig(:overrides, :purging, :purge_allowlist)))
|
114
174
|
else
|
115
175
|
logger.debug("Not purging unmanaged content for environment '#{environment.dirname}' due to prior deploy failures.")
|
116
176
|
end
|
117
177
|
end
|
118
178
|
|
119
|
-
if @generate_types
|
179
|
+
if @settings.dig(:overrides, :environments, :generate_types)
|
120
180
|
if @environment_ok
|
121
181
|
logger.debug("Generating puppet types for environment '#{environment.dirname}'...")
|
122
182
|
environment.generate_types!
|
@@ -128,34 +188,21 @@ module R10K
|
|
128
188
|
write_environment_info!(environment, started_at, @visit_ok)
|
129
189
|
end
|
130
190
|
|
131
|
-
def visit_puppetfile(puppetfile)
|
132
|
-
puppetfile.load(@opts[:'default-branch-override'])
|
133
|
-
|
134
|
-
yield
|
135
|
-
|
136
|
-
if @purge_levels.include?(:puppetfile)
|
137
|
-
logger.debug("Purging unmanaged Puppetfile content for environment '#{puppetfile.environment.dirname}'...")
|
138
|
-
puppetfile.purge!
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
def visit_module(mod)
|
143
|
-
logger.info _("Deploying %{origin} content %{path}") % {origin: mod.origin, path: mod.path}
|
144
|
-
mod.sync(force: @force)
|
145
|
-
end
|
146
|
-
|
147
191
|
def write_environment_info!(environment, started_at, success)
|
148
|
-
module_deploys =
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
192
|
+
module_deploys =
|
193
|
+
begin
|
194
|
+
environment.modules.map do |mod|
|
195
|
+
props = mod.properties
|
196
|
+
{
|
197
|
+
name: mod.name,
|
198
|
+
version: props[:expected],
|
199
|
+
sha: props[:type] == :git ? props[:actual] : nil
|
200
|
+
}
|
201
|
+
end
|
202
|
+
rescue
|
203
|
+
logger.debug("Unable to get environment module deploy data for .r10k-deploy.json at #{environment.path}")
|
204
|
+
[]
|
155
205
|
end
|
156
|
-
rescue
|
157
|
-
logger.debug("Unable to get environment module deploy data for .r10k-deploy.json at #{environment.path}")
|
158
|
-
end
|
159
206
|
|
160
207
|
# make this file write as atomic as possible in pure ruby
|
161
208
|
final = "#{environment.path}/.r10k-deploy.json"
|
@@ -183,12 +230,15 @@ module R10K
|
|
183
230
|
end
|
184
231
|
|
185
232
|
def allowed_initialize_opts
|
186
|
-
super.merge(puppetfile: :
|
233
|
+
super.merge(puppetfile: :modules,
|
234
|
+
modules: :self,
|
187
235
|
cachedir: :self,
|
188
236
|
'no-force': :self,
|
189
237
|
'generate-types': :self,
|
190
238
|
'puppet-path': :self,
|
191
239
|
'puppet-conf': :self,
|
240
|
+
'private-key': :self,
|
241
|
+
'oauth-token': :self,
|
192
242
|
'default-branch-override': :self)
|
193
243
|
end
|
194
244
|
end
|