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 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