r10k 3.1.1 → 3.2.0
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/CHANGELOG.mkd +7 -0
- data/azure-pipelines.yml +10 -4
- data/doc/dynamic-environments/configuration.mkd +20 -0
- data/docker/.rspec +1 -0
- data/docker/Makefile +20 -7
- data/docker/README.md +28 -0
- data/docker/ci/build.ps1 +3 -1
- data/docker/r10k/Dockerfile +4 -18
- data/docker/r10k/docker-entrypoint.d/10-analytics.sh +6 -4
- data/docker/r10k/docker-entrypoint.sh +2 -2
- data/docker/r10k/spec/dockerfile_spec.rb +14 -15
- data/docker/r10k/spec/spec_helper.rb +22 -0
- data/lib/r10k/action/deploy/environment.rb +16 -1
- data/lib/r10k/action/deploy/module.rb +5 -1
- data/lib/r10k/action/runner.rb +6 -2
- data/lib/r10k/cli/deploy.rb +8 -0
- data/lib/r10k/environment/base.rb +14 -0
- data/lib/r10k/initializers.rb +8 -0
- data/lib/r10k/module/base.rb +4 -0
- data/lib/r10k/settings.rb +23 -0
- data/lib/r10k/version.rb +1 -1
- data/spec/fixtures/unit/action/r10k.yaml +5 -0
- data/spec/fixtures/unit/action/r10k_cachedir.yaml +2 -0
- data/spec/fixtures/unit/action/r10k_generate_types.yaml +3 -0
- data/spec/fixtures/unit/action/r10k_puppet_path.yaml +3 -0
- data/spec/unit/action/deploy/environment_spec.rb +120 -0
- data/spec/unit/action/deploy/module_spec.rb +96 -0
- data/spec/unit/action/runner_spec.rb +95 -0
- data/spec/unit/settings_spec.rb +12 -0
- metadata +8 -3
- data/test +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4e4eadf9d07ce0163d2ec4a20c748956fda46c7c
|
4
|
+
data.tar.gz: c89ec234651cb578c26df88d02ee0196406abf0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5be4326a9c9fddc77c1c84daa5deb557059b2f876beb278c97d7f8c36e3c742ec39aeeed6231b3087490b696b7655de39569524b18acf0103c29f3ab41ba17a1
|
7
|
+
data.tar.gz: 7ee4a185142460a472ceb7f7b09c66bf3bbe03abf5de5a99e66a6cf62476b18ffc870e4fafb020c8146a8f854330979baee3b9b4e1da56237e028cd995a6bfef
|
data/CHANGELOG.mkd
CHANGED
data/azure-pipelines.yml
CHANGED
@@ -20,10 +20,15 @@ steps:
|
|
20
20
|
#
|
21
21
|
# Azure
|
22
22
|
#
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
23
|
+
$assetTag = Get-WmiObject -class Win32_SystemEnclosure -namespace root\CIMV2 |
|
24
|
+
Select -ExpandProperty SMBIOSAssetTag
|
25
|
+
if ($assetTag -eq '7783-7084-3265-9085-8269-3286-77')
|
26
|
+
{
|
27
|
+
Write-Host "`n`n$line`nAzure`n$line`n"
|
28
|
+
Invoke-RestMethod -Headers @{'Metadata'='true'} -URI http://169.254.169.254/metadata/instance?api-version=2017-12-01 -Method Get |
|
29
|
+
ConvertTo-Json -Depth 10 |
|
30
|
+
Write-Host
|
31
|
+
}
|
27
32
|
#
|
28
33
|
# Docker
|
29
34
|
#
|
@@ -38,6 +43,7 @@ steps:
|
|
38
43
|
Write-Host "`n`n$line`nRuby`n$line`n"
|
39
44
|
ruby --version
|
40
45
|
gem --version
|
46
|
+
gem env
|
41
47
|
bundle --version
|
42
48
|
#
|
43
49
|
# Environment
|
@@ -300,6 +300,26 @@ deploy:
|
|
300
300
|
write_lock: "Deploying code is disallowed until the next maintenance window (2038-01-19)"
|
301
301
|
```
|
302
302
|
|
303
|
+
#### generate\_types
|
304
|
+
|
305
|
+
The `generate_types` setting controls whether r10k should update generated types
|
306
|
+
after a successful environment update. See [Environment isolation](https://puppet.com/docs/puppet/latest/environment\_isolation.html)
|
307
|
+
for more information on generated types. Defaults to false.
|
308
|
+
|
309
|
+
```yaml
|
310
|
+
deploy:
|
311
|
+
generate_types: true
|
312
|
+
```
|
313
|
+
|
314
|
+
#### puppet\_path
|
315
|
+
|
316
|
+
The path to the puppet executable used for generating types. Defaults to `/opt/puppetlabs/bin/puppet`.
|
317
|
+
|
318
|
+
```yaml
|
319
|
+
deploy:
|
320
|
+
puppet_path: '/usr/local/bin/puppet'
|
321
|
+
```
|
322
|
+
|
303
323
|
Source options
|
304
324
|
--------------
|
305
325
|
|
data/docker/.rspec
CHANGED
data/docker/Makefile
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
PUPPERWARE_ANALYTICS_STREAM ?= dev
|
2
|
+
NAMESPACE ?= puppet
|
2
3
|
git_describe = $(shell git describe)
|
3
4
|
vcs_ref := $(shell git rev-parse HEAD)
|
4
5
|
build_date := $(shell date -u +%FT%T)
|
@@ -37,20 +38,32 @@ build: prep
|
|
37
38
|
--build-arg version=$(version) \
|
38
39
|
--build-arg pupperware_analytics_stream=$(PUPPERWARE_ANALYTICS_STREAM) \
|
39
40
|
--file r10k/$(dockerfile) \
|
40
|
-
--tag
|
41
|
+
--tag $(NAMESPACE)/r10k:$(version) \
|
41
42
|
r10k
|
42
43
|
ifeq ($(IS_LATEST),true)
|
43
|
-
@docker tag
|
44
|
+
@docker tag $(NAMESPACE)/r10k:$(version) puppet/r10k:latest
|
44
45
|
endif
|
45
46
|
|
46
47
|
test: prep
|
47
48
|
@bundle install --path .bundle/gems
|
48
|
-
@PUPPET_TEST_DOCKER_IMAGE
|
49
|
+
@PUPPET_TEST_DOCKER_IMAGE=$(NAMESPACE)/r10k:$(version) bundle exec rspec r10k/spec
|
49
50
|
|
50
|
-
|
51
|
-
@docker push
|
51
|
+
push-image: prep
|
52
|
+
@docker push $(NAMESPACE)/r10k:$(version)
|
52
53
|
ifeq ($(IS_LATEST),true)
|
53
|
-
@docker push
|
54
|
+
@docker push $(NAMESPACE)/r10k:latest
|
54
55
|
endif
|
55
56
|
|
56
|
-
|
57
|
+
push-readme:
|
58
|
+
@docker pull sheogorath/readme-to-dockerhub
|
59
|
+
@docker run --rm \
|
60
|
+
-v $(PWD)/README.md:/data/README.md \
|
61
|
+
-e DOCKERHUB_USERNAME="$(DISTELLI_DOCKER_USERNAME)" \
|
62
|
+
-e DOCKERHUB_PASSWORD="$(DISTELLI_DOCKER_PW)" \
|
63
|
+
-e DOCKERHUB_REPO_PREFIX=puppet \
|
64
|
+
-e DOCKERHUB_REPO_NAME=r10k \
|
65
|
+
sheogorath/readme-to-dockerhub
|
66
|
+
|
67
|
+
publish: push-image push-readme
|
68
|
+
|
69
|
+
.PHONY: prep lint build test publish push-image push-readme
|
data/docker/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# [puppetlabs/r10k](https://github.com/puppetlabs/r10k)
|
2
|
+
|
3
|
+
r10k on a Docker image. Based on Alpine 3.8.
|
4
|
+
|
5
|
+
## Configuration
|
6
|
+
|
7
|
+
The following environment variables are supported:
|
8
|
+
|
9
|
+
- `PUPPERWARE_ANALYTICS_ENABLED`
|
10
|
+
|
11
|
+
Set to 'true' to enable Google Analytics metrics. Defaults to 'false'.
|
12
|
+
|
13
|
+
## Analytics Data Collection
|
14
|
+
|
15
|
+
The r10k container collects usage data. This is disabled by default. You can enable it by passing `--env PUPPERWARE_ANALYTICS_ENABLED=true`
|
16
|
+
to your `docker run` command.
|
17
|
+
|
18
|
+
### What data is collected?
|
19
|
+
* Version of the r10k container.
|
20
|
+
* Anonymized IP address is used by Google Analytics for Geolocation data, but the IP address is not collected.
|
21
|
+
|
22
|
+
### Why does the r10k container collect data?
|
23
|
+
|
24
|
+
We collect data to help us understand how the containers are used and make decisions about upcoming changes.
|
25
|
+
|
26
|
+
### How can I opt out of r10k container data collection?
|
27
|
+
|
28
|
+
This is disabled by default.
|
data/docker/ci/build.ps1
CHANGED
@@ -54,6 +54,8 @@ function Invoke-ContainerTest(
|
|
54
54
|
|
55
55
|
bundle install --path .bundle/gems
|
56
56
|
$ENV:PUPPET_TEST_DOCKER_IMAGE = "$Namespace/r10k:$Version"
|
57
|
+
Write-Host "Testing against image: ${ENV:PUPPET_TEST_DOCKER_IMAGE}"
|
58
|
+
bundle exec rspec --version
|
57
59
|
bundle exec rspec r10k/spec
|
58
60
|
|
59
61
|
Pop-Location
|
@@ -72,7 +74,7 @@ function Clear-ContainerBuilds(
|
|
72
74
|
|
73
75
|
# this provides example data which ConvertFrom-String infers parsing structure with
|
74
76
|
$template = @'
|
75
|
-
{Version*:
|
77
|
+
{Version*:10.2.3*} {ID:5b84704c1d01} {[DateTime]Created:2019-02-07 18:24:51} +0000 GMT
|
76
78
|
{Version*:latest} {ID:0123456789ab} {[DateTime]Created:2019-01-29 00:05:33} +0000 GMT
|
77
79
|
'@
|
78
80
|
$output = docker images --filter=reference="$Namespace/${Name}" --format "{{.Tag}} {{.ID}} {{.CreatedAt}}"
|
data/docker/r10k/Dockerfile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
FROM
|
1
|
+
FROM alpine:3.8
|
2
2
|
|
3
3
|
ARG vcs_ref
|
4
4
|
ARG build_date
|
@@ -9,7 +9,6 @@ ARG pupperware_analytics_stream="dev"
|
|
9
9
|
ENV PUPPERWARE_ANALYTICS_STREAM="$pupperware_analytics_stream"
|
10
10
|
|
11
11
|
ENV R10K_VERSION="$version"
|
12
|
-
ENV UBUNTU_CODENAME="xenial"
|
13
12
|
|
14
13
|
LABEL org.label-schema.maintainer="Puppet Release Team <release@puppet.com>" \
|
15
14
|
org.label-schema.vendor="Puppet" \
|
@@ -23,27 +22,14 @@ LABEL org.label-schema.maintainer="Puppet Release Team <release@puppet.com>" \
|
|
23
22
|
org.label-schema.schema-version="1.0" \
|
24
23
|
org.label-schema.dockerfile="/Dockerfile"
|
25
24
|
|
26
|
-
RUN
|
27
|
-
|
28
|
-
|
29
|
-
dpkg -i puppet5-release-"$UBUNTU_CODENAME".deb && \
|
30
|
-
rm puppet5-release-"$UBUNTU_CODENAME".deb && \
|
31
|
-
apt-get update && \
|
32
|
-
apt-get install --no-install-recommends -y puppet-agent && \
|
33
|
-
apt-get install --no-install-recommends -y git openssh-client && \
|
34
|
-
apt-get remove --purge -y wget && \
|
35
|
-
apt-get autoremove -y && \
|
36
|
-
apt-get clean && \
|
37
|
-
rm -rf /var/lib/apt/lists/*
|
38
|
-
|
39
|
-
RUN /opt/puppetlabs/puppet/bin/gem install r10k:"$R10K_VERSION"
|
25
|
+
RUN apk add --no-cache ruby openssh-client git ruby-rugged curl ruby-dev make gcc musl-dev
|
26
|
+
|
27
|
+
RUN gem install --no-doc r10k:"$R10K_VERSION" json etc
|
40
28
|
|
41
29
|
COPY docker-entrypoint.sh /
|
42
30
|
RUN chmod +x /docker-entrypoint.sh
|
43
31
|
COPY docker-entrypoint.d /docker-entrypoint.d
|
44
32
|
|
45
|
-
ENV PATH=/opt/puppetlabs/server/bin:/opt/puppetlabs/puppet/bin:/opt/puppetlabs/bin:$PATH
|
46
|
-
|
47
33
|
ENTRYPOINT ["/docker-entrypoint.sh"]
|
48
34
|
CMD ["help"]
|
49
35
|
|
@@ -1,7 +1,7 @@
|
|
1
1
|
#!/bin/sh
|
2
2
|
|
3
|
-
if [ "${
|
4
|
-
|
3
|
+
if [ "${PUPPERWARE_ANALYTICS_ENABLED}" != "true" ]; then
|
4
|
+
# Don't print out any messages here since this is a CLI container
|
5
5
|
exit 0
|
6
6
|
fi
|
7
7
|
|
@@ -19,10 +19,12 @@ cid=$(cat $_file 2>/dev/null || (cat /proc/sys/kernel/random/uuid | tee $_file))
|
|
19
19
|
ec=${PUPPERWARE_ANALYTICS_STREAM:-dev}
|
20
20
|
# Event Action
|
21
21
|
ea=start
|
22
|
+
# Anonymize ip
|
23
|
+
aip=1
|
22
24
|
|
23
|
-
_params="v=1&t=event&tid=${tid}&an=${an}&av=${av}&cid=${cid}&ec=${ec}&ea=${ea}"
|
25
|
+
_params="v=1&t=event&tid=${tid}&an=${an}&av=${av}&cid=${cid}&ec=${ec}&ea=${ea}&aip=${aip}"
|
24
26
|
_url="http://www.google-analytics.com/collect?${_params}"
|
25
27
|
|
26
|
-
|
28
|
+
# Don't print out any messages here since this is a CLI container
|
27
29
|
curl --fail --silent --show-error --output /dev/null \
|
28
30
|
-X POST -H "Content-Length: 0" $_url
|
@@ -1,9 +1,19 @@
|
|
1
1
|
require 'rspec/core'
|
2
2
|
require 'fileutils'
|
3
|
+
require 'open3'
|
3
4
|
|
4
5
|
SPEC_DIRECTORY = File.dirname(__FILE__)
|
5
6
|
|
6
7
|
describe 'r10k container' do
|
8
|
+
include Helpers
|
9
|
+
|
10
|
+
def run_r10k(command)
|
11
|
+
run_command("docker run --rm \
|
12
|
+
--volume #{File.join(SPEC_DIRECTORY, 'fixtures')}:/test \
|
13
|
+
#{@image} #{command} \
|
14
|
+
--puppetfile /test/Puppetfile")
|
15
|
+
end
|
16
|
+
|
7
17
|
before(:all) do
|
8
18
|
@image = ENV['PUPPET_TEST_DOCKER_IMAGE']
|
9
19
|
if @image.nil?
|
@@ -15,31 +25,20 @@ describe 'r10k container' do
|
|
15
25
|
MSG
|
16
26
|
fail error_message
|
17
27
|
end
|
18
|
-
@container = %x(docker run --rm --detach \
|
19
|
-
--env PUPPERWARE_DISABLE_ANALYTICS=true \
|
20
|
-
--entrypoint /bin/bash \
|
21
|
-
--interactive \
|
22
|
-
--volume #{File.join(SPEC_DIRECTORY, 'fixtures')}:/test \
|
23
|
-
#{@image}).chomp
|
24
|
-
|
25
|
-
%x(docker exec #{@container} cp test/Puppetfile /)
|
26
28
|
end
|
27
29
|
|
28
30
|
after(:all) do
|
29
|
-
%x(docker container kill #{@container})
|
30
31
|
FileUtils.rm_rf(File.join(SPEC_DIRECTORY, 'fixtures', 'modules'))
|
31
32
|
end
|
32
33
|
|
33
34
|
it 'should validate the Puppetfile' do
|
34
|
-
|
35
|
-
status
|
36
|
-
expect(status).to eq(0)
|
35
|
+
result = run_r10k('puppetfile check')
|
36
|
+
expect(result[:status].exitstatus).to eq(0)
|
37
37
|
end
|
38
38
|
|
39
39
|
it 'should install the Puppetfile' do
|
40
|
-
|
41
|
-
status
|
42
|
-
expect(status).to eq(0)
|
40
|
+
result = run_r10k('puppetfile install')
|
41
|
+
expect(result[:status].exitstatus).to eq(0)
|
43
42
|
expect(Dir.exist?(File.join(SPEC_DIRECTORY, 'fixtures', 'modules', 'ntp'))).to eq(true)
|
44
43
|
end
|
45
44
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'open3'
|
2
|
+
|
3
|
+
module Helpers
|
4
|
+
def run_command(command)
|
5
|
+
stdout_string = ''
|
6
|
+
status = nil
|
7
|
+
|
8
|
+
Open3.popen3(command) do |stdin, stdout, stderr, wait_thread|
|
9
|
+
Thread.new do
|
10
|
+
stdout.each { |l| stdout_string << l; STDOUT.puts l }
|
11
|
+
end
|
12
|
+
Thread.new do
|
13
|
+
stderr.each { |l| STDOUT.puts l }
|
14
|
+
end
|
15
|
+
|
16
|
+
stdin.close
|
17
|
+
status = wait_thread.value
|
18
|
+
end
|
19
|
+
|
20
|
+
{ status: status, stdout: stdout_string }
|
21
|
+
end
|
22
|
+
end
|
@@ -19,6 +19,7 @@ module R10K
|
|
19
19
|
settings ||= {}
|
20
20
|
@purge_levels = settings.fetch(:deploy, {}).fetch(:purge_levels, [])
|
21
21
|
@user_purge_whitelist = settings.fetch(:deploy, {}).fetch(:purge_whitelist, [])
|
22
|
+
@generate_types = settings.fetch(:deploy, {}).fetch(:generate_types, false)
|
22
23
|
|
23
24
|
super
|
24
25
|
|
@@ -86,6 +87,7 @@ module R10K
|
|
86
87
|
end
|
87
88
|
|
88
89
|
started_at = Time.new
|
90
|
+
@environment_ok = true
|
89
91
|
|
90
92
|
status = environment.status
|
91
93
|
logger.info _("Deploying environment %{env_path}") % {env_path: environment.path}
|
@@ -98,7 +100,11 @@ module R10K
|
|
98
100
|
logger.debug(_("Environment %{env_dir} is new, updating all modules") % {env_dir: environment.dirname})
|
99
101
|
end
|
100
102
|
|
103
|
+
previous_ok = @visit_ok
|
104
|
+
@visit_ok = true
|
101
105
|
yield
|
106
|
+
@environment_ok = @visit_ok
|
107
|
+
@visit_ok &&= previous_ok
|
102
108
|
end
|
103
109
|
|
104
110
|
if @purge_levels.include?(:environment)
|
@@ -110,6 +116,15 @@ module R10K
|
|
110
116
|
end
|
111
117
|
end
|
112
118
|
|
119
|
+
if @generate_types
|
120
|
+
if @environment_ok
|
121
|
+
logger.debug("Generating puppet types for environment '#{environment.dirname}'...")
|
122
|
+
environment.generate_types!
|
123
|
+
else
|
124
|
+
logger.debug("Not generating puppet types for environment '#{environment.dirname}' due to puppetfile failures.")
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
113
128
|
write_environment_info!(environment, started_at, @visit_ok)
|
114
129
|
end
|
115
130
|
|
@@ -151,7 +166,7 @@ module R10K
|
|
151
166
|
end
|
152
167
|
|
153
168
|
def allowed_initialize_opts
|
154
|
-
super.merge(puppetfile: :self, cachedir: :self,
|
169
|
+
super.merge(puppetfile: :self, cachedir: :self, 'no-force': :self, 'generate-types': :self, 'puppet-path': :self)
|
155
170
|
end
|
156
171
|
end
|
157
172
|
end
|
@@ -62,13 +62,17 @@ module R10K
|
|
62
62
|
if @argv.include?(mod.name)
|
63
63
|
logger.info _("Deploying module %{mod_path}") % {mod_path: mod.path}
|
64
64
|
mod.sync(force: @force)
|
65
|
+
if mod.environment && @generate_types
|
66
|
+
logger.debug("Generating puppet types for environment '#{mod.environment.dirname}'...")
|
67
|
+
mod.environment.generate_types!
|
68
|
+
end
|
65
69
|
else
|
66
70
|
logger.debug1(_("Only updating modules %{modules}, skipping module %{mod_name}") % {modules: @argv.inspect, mod_name: mod.name})
|
67
71
|
end
|
68
72
|
end
|
69
73
|
|
70
74
|
def allowed_initialize_opts
|
71
|
-
super.merge(environment: true,
|
75
|
+
super.merge(environment: true, 'no-force': :self, 'generate-types': :self, 'puppet-path': :self)
|
72
76
|
end
|
73
77
|
end
|
74
78
|
end
|
data/lib/r10k/action/runner.rb
CHANGED
@@ -42,10 +42,14 @@ module R10K
|
|
42
42
|
def setup_settings
|
43
43
|
config_settings = settings_from_config(@opts[:config])
|
44
44
|
|
45
|
-
overrides = {
|
46
|
-
overrides
|
45
|
+
overrides = {}
|
46
|
+
overrides[:cachedir] = @opts[:cachedir] unless @opts[:cachedir].nil?
|
47
|
+
overrides[:deploy] = {} if @opts[:'puppet-path'] || @opts[:'generate-types']
|
48
|
+
overrides[:deploy][:puppet_path] = @opts[:'puppet-path'] unless @opts[:'puppet-path'].nil?
|
49
|
+
overrides[:deploy][:generate_types] = @opts[:'generate-types'] unless @opts[:'generate-types'].nil?
|
47
50
|
|
48
51
|
with_overrides = config_settings.merge(overrides) do |key, oldval, newval|
|
52
|
+
newval = oldval.merge(newval) if oldval.is_a? Hash
|
49
53
|
logger.debug2 _("Overriding config file setting '%{key}': '%{old_val}' -> '%{new_val}'") % {key: key, old_val: oldval, new_val: newval}
|
50
54
|
newval
|
51
55
|
end
|
data/lib/r10k/cli/deploy.rb
CHANGED
@@ -23,6 +23,14 @@ module R10K::CLI
|
|
23
23
|
|
24
24
|
required nil, :cachedir, 'Specify a cachedir, overriding the value in config'
|
25
25
|
flag nil, :'no-force', 'Prevent the overwriting of local module modifications'
|
26
|
+
flag nil, :'generate-types', 'Run `puppet generate types` after updating an environment'
|
27
|
+
option nil, :'puppet-path', 'Path to puppet executable', argument: :required do |value, cmd|
|
28
|
+
unless File.executable? value
|
29
|
+
$stderr.puts "The specified puppet executable #{value} is not executable."
|
30
|
+
puts cmd.help
|
31
|
+
exit 1
|
32
|
+
end
|
33
|
+
end
|
26
34
|
|
27
35
|
run do |opts, args, cmd|
|
28
36
|
puts cmd.help(:verbose => opts[:verbose])
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'r10k/util/subprocess'
|
2
|
+
|
1
3
|
# This class defines a common interface for environment implementations.
|
2
4
|
#
|
3
5
|
# @since 1.3.0
|
@@ -133,4 +135,16 @@ class R10K::Environment::Base
|
|
133
135
|
|
134
136
|
list.to_a
|
135
137
|
end
|
138
|
+
|
139
|
+
def generate_types!
|
140
|
+
argv = [R10K::Settings.puppet_path, 'generate', 'types', '--environment', dirname, '--environmentpath', basedir]
|
141
|
+
subproc = R10K::Util::Subprocess.new(argv)
|
142
|
+
subproc.raise_on_fail = true
|
143
|
+
subproc.logger = logger
|
144
|
+
result = subproc.execute
|
145
|
+
unless result.stderr.empty?
|
146
|
+
logger.warn "There were problems generating types for environment #{dirname}:"
|
147
|
+
result.stderr.split(%r{\n}).map { |msg| logger.warn msg }
|
148
|
+
end
|
149
|
+
end
|
136
150
|
end
|
data/lib/r10k/initializers.rb
CHANGED
@@ -30,6 +30,8 @@ module R10K
|
|
30
30
|
logger.warn(_("the purgedirs key in r10k.yaml is deprecated. it is currently ignored."))
|
31
31
|
end
|
32
32
|
|
33
|
+
with_setting(:deploy) { |value| DeployInitializer.new(value).call }
|
34
|
+
|
33
35
|
with_setting(:cachedir) { |value| R10K::Git::Cache.settings[:cache_root] = value }
|
34
36
|
with_setting(:cachedir) { |value| R10K::Forge::ModuleRelease.settings[:cache_root] = value }
|
35
37
|
|
@@ -38,6 +40,12 @@ module R10K
|
|
38
40
|
end
|
39
41
|
end
|
40
42
|
|
43
|
+
class DeployInitializer < BaseInitializer
|
44
|
+
def call
|
45
|
+
with_setting(:puppet_path) { |value| R10K::Settings.puppet_path = value }
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
41
49
|
class GitInitializer < BaseInitializer
|
42
50
|
def call
|
43
51
|
with_setting(:provider) { |value| R10K::Git.provider = value }
|
data/lib/r10k/module/base.rb
CHANGED
@@ -27,6 +27,10 @@ class R10K::Module::Base
|
|
27
27
|
# @return [Pathname] The full path of the module
|
28
28
|
attr_reader :path
|
29
29
|
|
30
|
+
# @!attribute [r] environment
|
31
|
+
# @return [R10K::Environment, nil] The parent environment of the module
|
32
|
+
attr_reader :environment
|
33
|
+
|
30
34
|
# There's been some churn over `author` vs `owner` and `full_name` over
|
31
35
|
# `title`, so in the short run it's easier to support both and deprecate one
|
32
36
|
# later.
|
data/lib/r10k/settings.rb
CHANGED
@@ -9,6 +9,11 @@ module R10K
|
|
9
9
|
require 'r10k/settings/definition'
|
10
10
|
require 'r10k/settings/list'
|
11
11
|
|
12
|
+
class << self
|
13
|
+
# Path to puppet executable
|
14
|
+
attr_accessor :puppet_path
|
15
|
+
end
|
16
|
+
|
12
17
|
def self.git_settings
|
13
18
|
R10K::Settings::Collection.new(:git, [
|
14
19
|
|
@@ -108,6 +113,24 @@ module R10K
|
|
108
113
|
:desc => "A list of filename patterns to be excluded from any purge operations. Patterns are matched relative to the root of each deployed environment, if you want a pattern to match recursively you need to use the '**' glob in your pattern. Basic shell style globs are supported.",
|
109
114
|
:default => [],
|
110
115
|
}),
|
116
|
+
|
117
|
+
Definition.new(:generate_types, {
|
118
|
+
:desc => "Controls whether to generate puppet types after deploying an environment. Defaults to false.",
|
119
|
+
:default => false,
|
120
|
+
:normalize => lambda do |input|
|
121
|
+
input.to_s == 'true'
|
122
|
+
end,
|
123
|
+
}),
|
124
|
+
|
125
|
+
Definition.new(:puppet_path, {
|
126
|
+
:desc => "Path to puppet executable. Defaults to /opt/puppetlabs/bin/puppet.",
|
127
|
+
:default => '/opt/puppetlabs/bin/puppet',
|
128
|
+
:validate => lambda do |value|
|
129
|
+
unless File.executable? value
|
130
|
+
raise ArgumentError, "The specified puppet executable #{value} is not executable"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
}),
|
111
134
|
])
|
112
135
|
end
|
113
136
|
|
data/lib/r10k/version.rb
CHANGED
@@ -24,6 +24,14 @@ describe R10K::Action::Deploy::Environment do
|
|
24
24
|
end
|
25
25
|
|
26
26
|
it "normalizes environment names in the arg vector"
|
27
|
+
|
28
|
+
it 'can accept a generate-types option' do
|
29
|
+
described_class.new({ 'generate-types': true }, [])
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'can accept a puppet-path option' do
|
33
|
+
described_class.new({ 'puppet-path': '/nonexistent' }, [])
|
34
|
+
end
|
27
35
|
end
|
28
36
|
|
29
37
|
describe "when called" do
|
@@ -207,5 +215,117 @@ describe R10K::Action::Deploy::Environment do
|
|
207
215
|
end
|
208
216
|
end
|
209
217
|
end
|
218
|
+
describe "generate-types" do
|
219
|
+
let(:deployment) do
|
220
|
+
R10K::Deployment.new(
|
221
|
+
R10K::Deployment::MockConfig.new(
|
222
|
+
sources: {
|
223
|
+
control: {
|
224
|
+
type: :mock,
|
225
|
+
basedir: '/some/nonexistent/path/control',
|
226
|
+
environments: %w[first second]
|
227
|
+
}
|
228
|
+
}
|
229
|
+
)
|
230
|
+
)
|
231
|
+
end
|
232
|
+
|
233
|
+
before do
|
234
|
+
allow(R10K::Deployment).to receive(:new).and_return(deployment)
|
235
|
+
end
|
236
|
+
|
237
|
+
before(:each) do
|
238
|
+
allow(subject).to receive(:write_environment_info!)
|
239
|
+
expect(subject.logger).not_to receive(:error)
|
240
|
+
end
|
241
|
+
|
242
|
+
context 'with generate-types enabled' do
|
243
|
+
subject do
|
244
|
+
described_class.new(
|
245
|
+
{
|
246
|
+
config: '/some/nonexistent/path',
|
247
|
+
puppetfile: true,
|
248
|
+
'generate-types': true
|
249
|
+
},
|
250
|
+
%w[first second]
|
251
|
+
)
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'generate_types is true' do
|
255
|
+
expect(subject.instance_variable_get(:@generate_types)).to eq(true)
|
256
|
+
end
|
257
|
+
|
258
|
+
it 'only calls puppet generate types on specified environment' do
|
259
|
+
subject.instance_variable_set(:@argv, %w[first])
|
260
|
+
expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
|
261
|
+
if environment.dirname == 'first'
|
262
|
+
expect(environment).to receive(:generate_types!)
|
263
|
+
else
|
264
|
+
expect(environment).not_to receive(:generate_types!)
|
265
|
+
end
|
266
|
+
original.call(environment, &block)
|
267
|
+
end.twice
|
268
|
+
subject.call
|
269
|
+
end
|
270
|
+
|
271
|
+
it 'does not call puppet generate types on puppetfile failure' do
|
272
|
+
allow(subject).to receive(:visit_puppetfile) { subject.instance_variable_set(:@visit_ok, false) }
|
273
|
+
expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
|
274
|
+
expect(environment).not_to receive(:generate_types!)
|
275
|
+
original.call(environment, &block)
|
276
|
+
end.twice
|
277
|
+
subject.call
|
278
|
+
end
|
279
|
+
|
280
|
+
it 'calls puppet generate types on previous puppetfile failure' do
|
281
|
+
allow(subject).to receive(:visit_puppetfile) do |puppetfile|
|
282
|
+
subject.instance_variable_set(:@visit_ok, false) if puppetfile.environment.dirname == 'first'
|
283
|
+
end
|
284
|
+
expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
|
285
|
+
if environment.dirname == 'second'
|
286
|
+
expect(environment).to receive(:generate_types!)
|
287
|
+
else
|
288
|
+
expect(environment).not_to receive(:generate_types!)
|
289
|
+
end
|
290
|
+
original.call(environment, &block)
|
291
|
+
end.twice
|
292
|
+
subject.call
|
293
|
+
end
|
294
|
+
end
|
295
|
+
|
296
|
+
context 'with generate-types disabled' do
|
297
|
+
subject do
|
298
|
+
described_class.new(
|
299
|
+
{
|
300
|
+
config: '/some/nonexistent/path',
|
301
|
+
puppetfile: true,
|
302
|
+
'generate-types': false
|
303
|
+
},
|
304
|
+
%w[first]
|
305
|
+
)
|
306
|
+
end
|
307
|
+
|
308
|
+
it 'generate_types is false' do
|
309
|
+
expect(subject.instance_variable_get(:@generate_types)).to eq(false)
|
310
|
+
end
|
311
|
+
|
312
|
+
it 'does not call puppet generate types' do
|
313
|
+
expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
|
314
|
+
expect(environment).not_to receive(:generate_types!)
|
315
|
+
original.call(environment, &block)
|
316
|
+
end.twice
|
317
|
+
subject.call
|
318
|
+
end
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
describe 'with puppet-path' do
|
323
|
+
|
324
|
+
subject { described_class.new({ config: '/some/nonexistent/path', 'puppet-path': '/nonexistent' }, []) }
|
325
|
+
|
326
|
+
it 'sets puppet_path' do
|
327
|
+
expect(subject.instance_variable_get(:@puppet_path)).to eq('/nonexistent')
|
328
|
+
end
|
329
|
+
end
|
210
330
|
end
|
211
331
|
end
|
@@ -17,6 +17,14 @@ describe R10K::Action::Deploy::Module do
|
|
17
17
|
it "can accept a no-force option" do
|
18
18
|
described_class.new({:'no-force' => true}, [])
|
19
19
|
end
|
20
|
+
|
21
|
+
it 'can accept a generate-types option' do
|
22
|
+
described_class.new({ 'generate-types': true }, [])
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'can accept a puppet-path option' do
|
26
|
+
described_class.new({ 'puppet-path': '/nonexistent' }, [])
|
27
|
+
end
|
20
28
|
end
|
21
29
|
|
22
30
|
describe "with no-force" do
|
@@ -27,4 +35,92 @@ describe R10K::Action::Deploy::Module do
|
|
27
35
|
expect(subject.force).to equal(false)
|
28
36
|
end
|
29
37
|
end
|
38
|
+
|
39
|
+
describe 'generate-types' do
|
40
|
+
let(:deployment) do
|
41
|
+
R10K::Deployment.new(
|
42
|
+
sources: {
|
43
|
+
control: {
|
44
|
+
type: :mock,
|
45
|
+
basedir: '/some/nonexistent/path/control',
|
46
|
+
environments: %w[first second]
|
47
|
+
}
|
48
|
+
}
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
before do
|
53
|
+
allow(R10K::Deployment).to receive(:new).and_return(deployment)
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'with generate-types enabled' do
|
57
|
+
subject do
|
58
|
+
described_class.new(
|
59
|
+
{
|
60
|
+
config: '/some/nonexistent/path',
|
61
|
+
'generate-types': true
|
62
|
+
},
|
63
|
+
%w[first]
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
before do
|
68
|
+
allow(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
|
69
|
+
expect(environment.puppetfile).to receive(:modules).and_return(
|
70
|
+
[R10K::Module::Local.new(environment.name, '/fakedir', [], environment)]
|
71
|
+
)
|
72
|
+
original.call(environment, &block)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'generate_types is true' do
|
77
|
+
expect(subject.instance_variable_get(:@generate_types)).to eq(true)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'only calls puppet generate types on environments with specified module' do
|
81
|
+
expect(subject).to receive(:visit_module).and_wrap_original do |original, mod, &block|
|
82
|
+
if mod.name == 'first'
|
83
|
+
expect(mod.environment).to receive(:generate_types!)
|
84
|
+
else
|
85
|
+
expect(mod.environment).not_to receive(:generate_types!)
|
86
|
+
end
|
87
|
+
original.call(mod, &block)
|
88
|
+
end.twice
|
89
|
+
subject.call
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
context 'with generate-types disabled' do
|
94
|
+
subject do
|
95
|
+
described_class.new(
|
96
|
+
{
|
97
|
+
config: '/some/nonexistent/path',
|
98
|
+
'generate-types': false
|
99
|
+
},
|
100
|
+
%w[first]
|
101
|
+
)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'generate_types is false' do
|
105
|
+
expect(subject.instance_variable_get(:@generate_types)).to eq(false)
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'does not call puppet generate types' do |it|
|
109
|
+
expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
|
110
|
+
expect(environment).not_to receive(:generate_types!)
|
111
|
+
original.call(environment, &block)
|
112
|
+
end.twice
|
113
|
+
subject.call
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe 'with puppet-path' do
|
119
|
+
|
120
|
+
subject { described_class.new({ config: '/some/nonexistent/path', 'puppet-path': '/nonexistent' }, []) }
|
121
|
+
|
122
|
+
it 'sets puppet_path' do
|
123
|
+
expect(subject.instance_variable_get(:@puppet_path)).to eq('/nonexistent')
|
124
|
+
end
|
125
|
+
end
|
30
126
|
end
|
@@ -25,6 +25,10 @@ describe R10K::Action::Runner do
|
|
25
25
|
|
26
26
|
subject(:runner) { described_class.new({:opts => :yep}, %w[args yes], action_class) }
|
27
27
|
|
28
|
+
before(:each) do
|
29
|
+
expect(runner.logger).not_to receive(:error)
|
30
|
+
end
|
31
|
+
|
28
32
|
describe "instantiating the wrapped class" do
|
29
33
|
it "creates an instance of the class" do
|
30
34
|
expect(runner.instance).to be_a_kind_of action_class
|
@@ -62,6 +66,97 @@ describe R10K::Action::Runner do
|
|
62
66
|
end
|
63
67
|
end
|
64
68
|
|
69
|
+
describe "configuring settings" do
|
70
|
+
subject(:runner) { described_class.new(options, %w[args yes], action_class) }
|
71
|
+
|
72
|
+
let(:global_settings) { R10K::Settings.global_settings }
|
73
|
+
|
74
|
+
before(:each) do
|
75
|
+
expect(R10K::Settings).to receive(:global_settings).and_return(global_settings)
|
76
|
+
allow(File).to receive(:executable?).and_return(true)
|
77
|
+
end
|
78
|
+
|
79
|
+
opts = {
|
80
|
+
cachedir: nil,
|
81
|
+
puppet_path: :deploy,
|
82
|
+
generate_types: :deploy,
|
83
|
+
}
|
84
|
+
|
85
|
+
opts.each do |opt, conf_path|
|
86
|
+
context "with #{opt} config setting" do
|
87
|
+
let(:options) { { config: "spec/fixtures/unit/action/r10k_#{opt}.yaml" } }
|
88
|
+
|
89
|
+
context "when not overridden" do
|
90
|
+
it "uses the config value" do
|
91
|
+
override = { "#{opt}": "/config_#{opt}" }
|
92
|
+
overrides = if conf_path.nil?
|
93
|
+
override
|
94
|
+
else
|
95
|
+
{ "#{conf_path}": override }
|
96
|
+
end
|
97
|
+
expect(global_settings).to receive(:evaluate).with(overrides).and_call_original
|
98
|
+
runner.call
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
context "when overridden" do
|
103
|
+
let(:options) { super().merge("#{opt.to_s.sub('_','-')}": "/overridden_#{opt}") }
|
104
|
+
|
105
|
+
it "uses the overridden value" do
|
106
|
+
override = { "#{opt}": "/overridden_#{opt}" }
|
107
|
+
overrides = if conf_path.nil?
|
108
|
+
override
|
109
|
+
else
|
110
|
+
{ "#{conf_path}": override }
|
111
|
+
end
|
112
|
+
expect(global_settings).to receive(:evaluate).with(overrides).and_call_original
|
113
|
+
runner.call
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
context "with complete config" do
|
119
|
+
let(:options) { { config: "spec/fixtures/unit/action/r10k.yaml" } }
|
120
|
+
let(:config) do
|
121
|
+
config = {}
|
122
|
+
opts.each do |o, path|
|
123
|
+
if path.nil?
|
124
|
+
config[o] = "/config_#{o}"
|
125
|
+
else
|
126
|
+
config[path] ||= {}
|
127
|
+
config[path][o] = "/config_#{o}"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
config
|
131
|
+
end
|
132
|
+
|
133
|
+
context "when not overridden" do
|
134
|
+
it "uses the config value" do
|
135
|
+
expect(global_settings).to receive(:evaluate).with(config).and_call_original
|
136
|
+
runner.call
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
context "when overridden" do
|
141
|
+
let(:options) {
|
142
|
+
super().merge("#{opt.to_s.sub('_','-')}": "/overridden_#{opt}")
|
143
|
+
}
|
144
|
+
|
145
|
+
it "uses the overridden value" do
|
146
|
+
with_overrides = config
|
147
|
+
if conf_path.nil?
|
148
|
+
with_overrides[opt] = "/overridden_#{opt}"
|
149
|
+
else
|
150
|
+
with_overrides[conf_path][opt] = "/overridden_#{opt}"
|
151
|
+
end
|
152
|
+
expect(global_settings).to receive(:evaluate).with(with_overrides).and_call_original
|
153
|
+
runner.call
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
65
160
|
describe "configuring logging" do
|
66
161
|
it "sets the log level if :loglevel is provided" do
|
67
162
|
runner = described_class.new({:opts => :yep, :loglevel => 'FATAL'}, %w[args yes], action_class)
|
data/spec/unit/settings_spec.rb
CHANGED
@@ -117,6 +117,18 @@ describe R10K::Settings do
|
|
117
117
|
end
|
118
118
|
end
|
119
119
|
end
|
120
|
+
|
121
|
+
describe 'puppet_path' do
|
122
|
+
it 'when executable raises no error' do
|
123
|
+
expect(File).to receive(:executable?).with('/nonexistent').and_return(true)
|
124
|
+
expect { subject.evaluate('puppet_path' => '/nonexistent') }.not_to raise_error
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'when not executable raises error' do
|
128
|
+
expect(File).to receive(:executable?).with('/nonexistent')
|
129
|
+
expect { subject.evaluate('puppet_path' => '/nonexistent') }.to raise_error(R10K::Settings::Collection::ValidationError)
|
130
|
+
end
|
131
|
+
end
|
120
132
|
end
|
121
133
|
|
122
134
|
describe "global settings" do
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: r10k
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.
|
4
|
+
version: 3.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adrien Thebo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: colored
|
@@ -191,6 +191,7 @@ files:
|
|
191
191
|
- docker/.rspec
|
192
192
|
- docker/Gemfile
|
193
193
|
- docker/Makefile
|
194
|
+
- docker/README.md
|
194
195
|
- docker/ci/build.ps1
|
195
196
|
- docker/distelli-manifest.yml
|
196
197
|
- docker/r10k/Dockerfile
|
@@ -198,6 +199,7 @@ files:
|
|
198
199
|
- docker/r10k/docker-entrypoint.sh
|
199
200
|
- docker/r10k/spec/dockerfile_spec.rb
|
200
201
|
- docker/r10k/spec/fixtures/Puppetfile
|
202
|
+
- docker/r10k/spec/spec_helper.rb
|
201
203
|
- integration/Gemfile
|
202
204
|
- integration/README.mkd
|
203
205
|
- integration/Rakefile
|
@@ -405,6 +407,10 @@ files:
|
|
405
407
|
- spec/fixtures/module/forge/bad_module/metadata.json
|
406
408
|
- spec/fixtures/module/forge/eight_hundred/Modulefile
|
407
409
|
- spec/fixtures/module/forge/eight_hundred/metadata.json
|
410
|
+
- spec/fixtures/unit/action/r10k.yaml
|
411
|
+
- spec/fixtures/unit/action/r10k_cachedir.yaml
|
412
|
+
- spec/fixtures/unit/action/r10k_generate_types.yaml
|
413
|
+
- spec/fixtures/unit/action/r10k_puppet_path.yaml
|
408
414
|
- spec/fixtures/unit/puppetfile/argument-error/Puppetfile
|
409
415
|
- spec/fixtures/unit/puppetfile/duplicate-module-error/Puppetfile
|
410
416
|
- spec/fixtures/unit/puppetfile/invalid-syntax/Puppetfile
|
@@ -509,7 +515,6 @@ files:
|
|
509
515
|
- spec/unit/util/subprocess/subprocess_error_spec.rb
|
510
516
|
- spec/unit/util/subprocess_spec.rb
|
511
517
|
- spec/unit/util/symbolize_keys_spec.rb
|
512
|
-
- test
|
513
518
|
homepage: https://github.com/puppetlabs/r10k
|
514
519
|
licenses:
|
515
520
|
- Apache-2.0
|