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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 84930e8294eba7ee0bb6891b043c7b5c50adc06b
4
- data.tar.gz: 941551e36b98e187c52afbbc1c20e98c4b869ae8
3
+ metadata.gz: 4e4eadf9d07ce0163d2ec4a20c748956fda46c7c
4
+ data.tar.gz: c89ec234651cb578c26df88d02ee0196406abf0a
5
5
  SHA512:
6
- metadata.gz: 9eef55519460f134d9e2a376e64cab9e04a63836c9a4aa7a46f3d220576b29beed54215fc9710057f6d932a9892b9abeb7e91cfe9f2caa29a2846fed951de662
7
- data.tar.gz: 53f5d878d87b1db35402539a0ca21d97ab22f230f84b583885dd67fa4c162a0c6ec1b05c71e535f116015583e49b76c87fd6642e8e7311d16c7a7addd08e1343
6
+ metadata.gz: 5be4326a9c9fddc77c1c84daa5deb557059b2f876beb278c97d7f8c36e3c742ec39aeeed6231b3087490b696b7655de39569524b18acf0103c29f3ab41ba17a1
7
+ data.tar.gz: 7ee4a185142460a472ceb7f7b09c66bf3bbe03abf5de5a99e66a6cf62476b18ffc870e4fafb020c8146a8f854330979baee3b9b4e1da56237e028cd995a6bfef
@@ -1,6 +1,13 @@
1
1
  CHANGELOG
2
2
  =========
3
3
 
4
+ 3.2.0
5
+ -----
6
+
7
+ ## New Feature
8
+
9
+ Add support for running `puppet generate types`
10
+
4
11
  3.1.1
5
12
  -----
6
13
 
@@ -20,10 +20,15 @@ steps:
20
20
  #
21
21
  # Azure
22
22
  #
23
- Write-Host "`n`n$line`nAzure`n$line`n"
24
- Invoke-RestMethod -Headers @{'Metadata'='true'} -URI http://169.254.169.254/metadata/instance?api-version=2017-12-01 -Method Get |
25
- ConvertTo-Json -Depth 10 |
26
- Write-Host
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
 
@@ -1,3 +1,4 @@
1
+ --require ./r10k/spec/spec_helper
1
2
  --format RspecJunitFormatter
2
3
  --out TEST-rspec.xml
3
4
  --format documentation
@@ -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 puppet/r10k:$(version) \
41
+ --tag $(NAMESPACE)/r10k:$(version) \
41
42
  r10k
42
43
  ifeq ($(IS_LATEST),true)
43
- @docker tag puppet/r10k:$(version) puppet/r10k:latest
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=puppet/r10k:$(version) bundle exec rspec r10k/spec
49
+ @PUPPET_TEST_DOCKER_IMAGE=$(NAMESPACE)/r10k:$(version) bundle exec rspec r10k/spec
49
50
 
50
- publish: prep
51
- @docker push puppet/r10k:$(version)
51
+ push-image: prep
52
+ @docker push $(NAMESPACE)/r10k:$(version)
52
53
  ifeq ($(IS_LATEST),true)
53
- @docker push puppet/r10k:latest
54
+ @docker push $(NAMESPACE)/r10k:latest
54
55
  endif
55
56
 
56
- .PHONY: lint build test publish
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
@@ -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.
@@ -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*:1.2.3} {ID:5b84704c1d01} {[DateTime]Created:2019-02-07 18:24:51} +0000 GMT
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}}"
@@ -1,4 +1,4 @@
1
- FROM ubuntu:16.04
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 apt-get update && \
27
- apt-get install --no-install-recommends -y wget ca-certificates lsb-release && \
28
- wget https://apt.puppetlabs.com/puppet5-release-"$UBUNTU_CODENAME".deb && \
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 [ "${PUPPERWARE_DISABLE_ANALYTICS}" = "true" ]; then
4
- echo "($0) Pupperware analytics disabled; skipping metric submission"
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
- echo "($0) Sending metrics ${_url}"
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
@@ -3,9 +3,9 @@
3
3
  set -e
4
4
 
5
5
  for f in /docker-entrypoint.d/*.sh; do
6
- echo "Running $f"
6
+ # Don't print out any messages here since this is a CLI container
7
7
  chmod +x "$f"
8
8
  "$f"
9
9
  done
10
10
 
11
- exec /opt/puppetlabs/puppet/bin/r10k "$@"
11
+ exec /usr/bin/r10k "$@"
@@ -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
- %x(docker exec #{@container} r10k puppetfile check)
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
- %x(docker exec #{@container} r10k puppetfile install)
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, :'no-force' => :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, :'no-force' => :self)
75
+ super.merge(environment: true, 'no-force': :self, 'generate-types': :self, 'puppet-path': :self)
72
76
  end
73
77
  end
74
78
  end
@@ -42,10 +42,14 @@ module R10K
42
42
  def setup_settings
43
43
  config_settings = settings_from_config(@opts[:config])
44
44
 
45
- overrides = {:cachedir => @opts[:cachedir]}
46
- overrides.delete_if { |_, val| val.nil? }
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
@@ -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
@@ -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 }
@@ -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.
@@ -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
 
@@ -1,3 +1,3 @@
1
1
  module R10K
2
- VERSION = '3.1.1'
2
+ VERSION = '3.2.0'
3
3
  end
@@ -0,0 +1,5 @@
1
+ ---
2
+ cachedir: /config_cachedir
3
+ deploy:
4
+ generate_types: /config_generate_types
5
+ puppet_path: /config_puppet_path
@@ -0,0 +1,2 @@
1
+ ---
2
+ cachedir: /config_cachedir
@@ -0,0 +1,3 @@
1
+ ---
2
+ deploy:
3
+ generate_types: /config_generate_types
@@ -0,0 +1,3 @@
1
+ ---
2
+ deploy:
3
+ puppet_path: /config_puppet_path
@@ -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)
@@ -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.1.1
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-02-21 00:00:00.000000000 Z
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
data/test DELETED
@@ -1 +0,0 @@
1
- integration