r10k 3.1.1 → 3.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|