r10k 1.3.5 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +1 -1
  3. data/CHANGELOG.mkd +210 -0
  4. data/CONTRIBUTING.mkd +105 -0
  5. data/Gemfile +2 -6
  6. data/README.mkd +97 -0
  7. data/doc/common-patterns.mkd +44 -0
  8. data/doc/dynamic-environments.mkd +12 -5
  9. data/doc/dynamic-environments/configuration.mkd +16 -1
  10. data/doc/dynamic-environments/{git-environments.markdown → git-environments.mkd} +13 -9
  11. data/doc/dynamic-environments/introduction.mkd +1 -2
  12. data/doc/dynamic-environments/master-configuration.mkd +70 -0
  13. data/doc/dynamic-environments/quickstart.mkd +241 -0
  14. data/doc/dynamic-environments/svn-environments.mkd +45 -0
  15. data/doc/dynamic-environments/usage.mkd +44 -5
  16. data/doc/dynamic-environments/workflow-guide.mkd +247 -0
  17. data/doc/faq.mkd +52 -0
  18. data/doc/puppetfile.mkd +203 -0
  19. data/lib/r10k/action/cri_runner.rb +75 -0
  20. data/lib/r10k/action/deploy.rb +9 -0
  21. data/lib/r10k/action/deploy/display.rb +104 -0
  22. data/lib/r10k/action/deploy/environment.rb +92 -0
  23. data/lib/r10k/action/deploy/module.rb +70 -0
  24. data/lib/r10k/action/puppetfile.rb +10 -0
  25. data/lib/r10k/action/puppetfile/check.rb +41 -0
  26. data/lib/r10k/action/puppetfile/cri_runner.rb +32 -0
  27. data/lib/r10k/action/puppetfile/install.rb +53 -0
  28. data/lib/r10k/action/puppetfile/purge.rb +37 -0
  29. data/lib/r10k/action/runner.rb +36 -0
  30. data/lib/r10k/action/visitor.rb +31 -0
  31. data/lib/r10k/cli/deploy.rb +14 -45
  32. data/lib/r10k/cli/puppetfile.rb +15 -53
  33. data/lib/r10k/deployment.rb +113 -58
  34. data/lib/r10k/deployment/basedir.rb +3 -38
  35. data/lib/r10k/deployment/config.rb +2 -1
  36. data/lib/r10k/deployment/source.rb +2 -0
  37. data/lib/r10k/environment/base.rb +40 -0
  38. data/lib/r10k/environment/git.rb +14 -17
  39. data/lib/r10k/environment/svn.rb +31 -15
  40. data/lib/r10k/errors.rb +33 -22
  41. data/lib/r10k/errors/formatting.rb +28 -0
  42. data/lib/r10k/execution.rb +2 -0
  43. data/lib/r10k/git/cache.rb +1 -6
  44. data/lib/r10k/git/errors.rb +1 -2
  45. data/lib/r10k/git/ref.rb +1 -1
  46. data/lib/r10k/module.rb +1 -1
  47. data/lib/r10k/module/base.rb +94 -2
  48. data/lib/r10k/module/forge.rb +33 -30
  49. data/lib/r10k/module/git.rb +13 -9
  50. data/lib/r10k/module/svn.rb +41 -28
  51. data/lib/r10k/puppetfile.rb +17 -1
  52. data/lib/r10k/semver.rb +2 -0
  53. data/lib/r10k/source/base.rb +8 -0
  54. data/lib/r10k/source/git.rb +1 -1
  55. data/lib/r10k/source/svn.rb +23 -5
  56. data/lib/r10k/svn/remote.rb +23 -3
  57. data/lib/r10k/svn/working_dir.rb +60 -9
  58. data/lib/r10k/task.rb +1 -0
  59. data/lib/r10k/task/deployment.rb +9 -1
  60. data/lib/r10k/task/environment.rb +2 -0
  61. data/lib/r10k/task/module.rb +1 -0
  62. data/lib/r10k/task/puppetfile.rb +3 -0
  63. data/lib/r10k/task_runner.rb +1 -0
  64. data/lib/r10k/util/attempt.rb +84 -0
  65. data/lib/r10k/util/basedir.rb +65 -0
  66. data/lib/r10k/util/purgeable.rb +55 -45
  67. data/lib/r10k/util/setopts.rb +53 -0
  68. data/lib/r10k/util/subprocess.rb +6 -30
  69. data/lib/r10k/util/subprocess/posix/runner.rb +29 -2
  70. data/lib/r10k/util/subprocess/result.rb +17 -4
  71. data/lib/r10k/util/subprocess/subprocess_error.rb +24 -0
  72. data/lib/r10k/version.rb +1 -1
  73. data/r10k.gemspec +7 -29
  74. data/spec/fixtures/unit/puppetfile/invalid-syntax/Puppetfile +1 -0
  75. data/spec/fixtures/unit/puppetfile/load-error/Puppetfile +1 -0
  76. data/spec/matchers/exit_with.rb +28 -0
  77. data/spec/r10k-mocks.rb +3 -0
  78. data/spec/r10k-mocks/mock_config.rb +28 -0
  79. data/spec/r10k-mocks/mock_env.rb +7 -0
  80. data/spec/r10k-mocks/mock_source.rb +10 -0
  81. data/spec/shared-examples/git-ref.rb +7 -7
  82. data/spec/spec_helper.rb +17 -5
  83. data/spec/unit/action/cri_runner_spec.rb +76 -0
  84. data/spec/unit/action/puppetfile/cri_action_spec.rb +65 -0
  85. data/spec/unit/action/runner_spec.rb +64 -0
  86. data/spec/unit/action/visitor_spec.rb +39 -0
  87. data/spec/unit/deployment_spec.rb +142 -0
  88. data/spec/unit/environment/base_spec.rb +38 -0
  89. data/spec/unit/environment/git_spec.rb +40 -10
  90. data/spec/unit/environment/svn_spec.rb +41 -4
  91. data/spec/unit/errors/formatting_spec.rb +84 -0
  92. data/spec/unit/git/alternates_spec.rb +1 -1
  93. data/spec/unit/git/head_spec.rb +1 -1
  94. data/spec/unit/git/ref_spec.rb +1 -1
  95. data/spec/unit/git/working_dir_spec.rb +1 -1
  96. data/spec/unit/module/base_spec.rb +72 -0
  97. data/spec/unit/module/forge_spec.rb +49 -8
  98. data/spec/unit/module/git_spec.rb +78 -0
  99. data/spec/unit/module/svn_spec.rb +40 -4
  100. data/spec/unit/module_spec.rb +3 -3
  101. data/spec/unit/puppetfile_spec.rb +84 -0
  102. data/spec/unit/settings/container_spec.rb +1 -1
  103. data/spec/unit/source/base_spec.rb +31 -0
  104. data/spec/unit/source/git_spec.rb +7 -7
  105. data/spec/unit/source/svn_spec.rb +1 -1
  106. data/spec/unit/svn/working_dir_spec.rb +56 -0
  107. data/spec/unit/util/attempt_spec.rb +82 -0
  108. data/spec/unit/util/setopts_spec.rb +59 -0
  109. data/spec/unit/util/subprocess/result_spec.rb +36 -0
  110. data/spec/unit/util/subprocess/subprocess_error_spec.rb +26 -0
  111. data/spec/unit/util/subprocess_spec.rb +2 -7
  112. metadata +83 -100
  113. data/.nodeset.yml +0 -7
  114. data/.rspec +0 -1
  115. data/README.markdown +0 -276
  116. data/Rakefile +0 -1
  117. data/doc/puppetfile.markdown +0 -87
  118. data/spec/rspec-system-r10k/puppetfile.rb +0 -24
  119. data/spec/rspec-system-r10k/tmpdir.rb +0 -32
  120. data/spec/system-provisioning/el.rb +0 -38
  121. data/spec/system/module/forge/install_spec.rb +0 -51
  122. data/spec/system/module/git/install_spec.rb +0 -117
  123. data/spec/system/module/svn/install_spec.rb +0 -51
  124. data/spec/system/module/svn/update_spec.rb +0 -38
  125. data/spec/system/spec_helper.rb +0 -60
  126. data/spec/system/system-helpers.rb +0 -4
  127. data/spec/system/version_spec.rb +0 -7
@@ -0,0 +1,75 @@
1
+ require 'r10k/action/runner'
2
+
3
+ module R10K
4
+ module Action
5
+
6
+ # Adapt the Cri runner interface to the R10K::Action::Runner interface
7
+ #
8
+ # This class provides the necessary glue to translate behavior specific
9
+ # to Cri and the CLI component in general to the interface agnostic runner
10
+ # class.
11
+ #
12
+ # @api private
13
+ class CriRunner
14
+
15
+ def self.wrap(klass)
16
+ new(klass)
17
+ end
18
+
19
+ def initialize(klass)
20
+ @klass = klass
21
+ end
22
+
23
+ # Intercept any instatiations of klass
24
+ #
25
+ # Defining #new allows this object to proxy method calls on the wrapped
26
+ # runner and decorate various methods. Doing so allows this class to
27
+ # manage CLI specific behaviors and isolate the underlying code from
28
+ # having to deal with those particularities
29
+ #
30
+ # @param opts [Hash]
31
+ # @param argv [Array<String>]
32
+ # @param _cmd [Cri::Command] The command that was invoked. This value
33
+ # is not used and is only present to adapt the Cri interface to r10k.
34
+ # @return [self]
35
+ def new(opts, argv, _cmd = nil)
36
+ handle_opts(opts)
37
+ handle_argv(argv)
38
+ @runner = R10K::Action::Runner.new(@opts, @argv, @klass)
39
+ self
40
+ end
41
+
42
+ # @return [Hash] The adapted options for the runner
43
+ def handle_opts(opts)
44
+ # Translate from the Cri verbose logging option to the internal logging setting.
45
+ loglevel = opts.delete(:verbose)
46
+ case loglevel
47
+ when String, Numeric
48
+ opts[:loglevel] = loglevel
49
+ when TrueClass
50
+ opts[:loglevel] = 'INFO'
51
+ when NilClass
52
+ # pass
53
+ else
54
+ # When the type is unsure just pass it in as-is and let the internals
55
+ # raise the appropriate errors.
56
+ opts[:loglevel] = loglevel
57
+ end
58
+
59
+ @opts = opts
60
+ end
61
+
62
+ # @return [Array] The adapted arguments for the runner
63
+ def handle_argv(argv)
64
+ @argv = argv
65
+ end
66
+
67
+ # Invoke the wrapped behavior, determine if it succeeded, and exit with
68
+ # the resulting exit code.
69
+ def call
70
+ rv = @runner.call
71
+ exit(rv ? 0 : 1)
72
+ end
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,9 @@
1
+ module R10K
2
+ module Action
3
+ module Deploy
4
+ require 'r10k/action/deploy/environment'
5
+ require 'r10k/action/deploy/module'
6
+ require 'r10k/action/deploy/display'
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,104 @@
1
+ require 'r10k/util/setopts'
2
+ require 'r10k/deployment'
3
+ require 'r10k/logging'
4
+
5
+ module R10K
6
+ module Action
7
+ module Deploy
8
+ class Display
9
+
10
+ include R10K::Util::Setopts
11
+ include R10K::Logging
12
+
13
+ def initialize(opts, argv)
14
+ @opts = opts
15
+ @argv = argv
16
+ setopts(opts, {
17
+ :config => :self,
18
+ :puppetfile => :self,
19
+ :detail => :self,
20
+ :trace => :self
21
+ })
22
+
23
+ @level = 4
24
+ @indent = 0
25
+ end
26
+
27
+ def call
28
+ @visit_ok = true
29
+ deployment = R10K::Deployment.load_config(@config)
30
+ deployment.accept(self)
31
+ @visit_ok
32
+ end
33
+
34
+ include R10K::Action::Visitor
35
+
36
+ private
37
+
38
+ def visit_deployment(deployment)
39
+ yield
40
+ end
41
+
42
+ def visit_source(source)
43
+ source.generate_environments
44
+ display_text("#{source.name} (#{source.basedir})")
45
+ yield
46
+ end
47
+
48
+ def visit_environment(environment)
49
+ if !(@argv.empty? || @argv.include?(environment.dirname))
50
+ return
51
+ end
52
+
53
+ indent do
54
+ display_text("- " + environment.dirname)
55
+ if @puppetfile
56
+ indent do
57
+ display_text("modules:")
58
+ yield
59
+ end
60
+ end
61
+ end
62
+ end
63
+
64
+ def visit_puppetfile(puppetfile)
65
+ puppetfile.load
66
+ yield
67
+ end
68
+
69
+ def visit_module(mod)
70
+ indent do
71
+ display_text("- " + mod.title)
72
+ if @detail
73
+ indent do
74
+ properties = mod.properties
75
+ str = properties.keys.sort.map do |key|
76
+ "#{key}: #{properties[key]}"
77
+ end.join("\n")
78
+ display_text(str)
79
+ end
80
+ end
81
+ end
82
+ end
83
+
84
+ def indent(&block)
85
+ @indent += @level
86
+ block.call
87
+ ensure
88
+ @indent -= @level
89
+ end
90
+
91
+ def indent_text(str)
92
+ space = " " * @indent
93
+ str.lines.map do |line|
94
+ space + line
95
+ end.join
96
+ end
97
+
98
+ def display_text(str)
99
+ puts indent_text(str)
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,92 @@
1
+ require 'r10k/util/setopts'
2
+ require 'r10k/deployment'
3
+ require 'r10k/logging'
4
+ require 'r10k/action/visitor'
5
+
6
+ module R10K
7
+ module Action
8
+ module Deploy
9
+ class Environment
10
+
11
+ include R10K::Util::Setopts
12
+ include R10K::Logging
13
+
14
+ def initialize(opts, argv)
15
+ @opts = opts
16
+ @argv = argv
17
+ setopts(opts, {
18
+ :config => :self,
19
+ :puppetfile => :self,
20
+ :purge => :self,
21
+ :trace => :self
22
+ })
23
+
24
+ @purge = true
25
+ end
26
+
27
+ def call
28
+ @visit_ok = true
29
+ deployment = R10K::Deployment.load_config(@config)
30
+ deployment.accept(self)
31
+ @visit_ok
32
+ end
33
+
34
+ include R10K::Action::Visitor
35
+
36
+ private
37
+
38
+ def visit_deployment(deployment)
39
+ # Ensure that everything can be preloaded. If we cannot preload all
40
+ # sources then we can't fully enumerate all environments which
41
+ # could be dangerous. If this fails then an exception will be raised
42
+ # and execution will be halted.
43
+ deployment.preload!
44
+ deployment.validate!
45
+
46
+ yield
47
+
48
+ deployment.purge! if @purge
49
+
50
+ ensure
51
+ if (postcmd = deployment.config.setting(:postrun))
52
+ subproc = R10K::Util::Subprocess.new(postcmd)
53
+ subproc.logger = logger
54
+ subproc.execute
55
+ end
56
+ end
57
+
58
+ def visit_source(source)
59
+ yield
60
+ end
61
+
62
+ def visit_environment(environment)
63
+ if !(@argv.empty? || @argv.any? { |name| environment.dirname == name })
64
+ logger.debug1("Environment #{environment.dirname} does not match environment name filter, skipping")
65
+ return
66
+ end
67
+ status = environment.status
68
+ logger.info "Deploying environment #{environment.path}"
69
+ environment.sync
70
+
71
+ if status == :absent || @puppetfile
72
+ if status == :absent
73
+ logger.debug("Environment #{environment.dirname} is new, updating all modules")
74
+ end
75
+ yield
76
+ end
77
+ end
78
+
79
+ def visit_puppetfile(puppetfile)
80
+ puppetfile.load
81
+ yield
82
+ puppetfile.purge!
83
+ end
84
+
85
+ def visit_module(mod)
86
+ logger.info "Deploying module #{mod.path}"
87
+ mod.sync
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,70 @@
1
+ require 'r10k/util/setopts'
2
+ require 'r10k/deployment'
3
+ require 'r10k/action/visitor'
4
+ require 'r10k/logging'
5
+
6
+ module R10K
7
+ module Action
8
+ module Deploy
9
+ class Module
10
+
11
+ include R10K::Logging
12
+ include R10K::Util::Setopts
13
+
14
+ def initialize(opts, argv)
15
+ @opts = opts
16
+ @argv = argv
17
+ setopts(opts, {
18
+ :config => :self,
19
+ :environment => nil,
20
+ :trace => :self
21
+ })
22
+
23
+ @purge = true
24
+ end
25
+
26
+ def call
27
+ @visit_ok = true
28
+ deployment = R10K::Deployment.load_config(@config)
29
+ deployment.accept(self)
30
+ @visit_ok
31
+ end
32
+
33
+ include R10K::Action::Visitor
34
+
35
+ private
36
+
37
+ def visit_deployment(deployment)
38
+ yield
39
+ end
40
+
41
+ def visit_source(source)
42
+ yield
43
+ end
44
+
45
+ def visit_environment(environment)
46
+ if @opts[:environment] && (@opts[:environment] != environment.dirname)
47
+ logger.debug1("Only updating modules in environment #{@opts[:environment]}, skipping environment #{environment.path}")
48
+ else
49
+ logger.debug1("Updating modules #{@argv.inspect} in environment #{environment.path}")
50
+ yield
51
+ end
52
+ end
53
+
54
+ def visit_puppetfile(puppetfile)
55
+ puppetfile.load
56
+ yield
57
+ end
58
+
59
+ def visit_module(mod)
60
+ if @argv.include?(mod.name)
61
+ logger.info "Deploying module #{mod.path}"
62
+ mod.sync
63
+ else
64
+ logger.debug1("Only updating modules #{@argv.inspect}, skipping module #{mod.name}")
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,10 @@
1
+ module R10K
2
+ module Action
3
+ module Puppetfile
4
+ require 'r10k/action/puppetfile/cri_runner'
5
+ require 'r10k/action/puppetfile/install'
6
+ require 'r10k/action/puppetfile/check'
7
+ require 'r10k/action/puppetfile/purge'
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,41 @@
1
+ require 'r10k/puppetfile'
2
+ require 'r10k/util/setopts'
3
+ require 'r10k/errors/formatting'
4
+ require 'r10k/logging'
5
+
6
+ module R10K
7
+ module Action
8
+ module Puppetfile
9
+ class Check
10
+ include R10K::Logging
11
+ include R10K::Util::Setopts
12
+
13
+ def initialize(opts, argv)
14
+ @opts = opts
15
+ @argv = argv
16
+
17
+ setopts(opts, {
18
+ :root => :self,
19
+ :moduledir => :self,
20
+ :puppetfile => :path,
21
+ :trace => :self,
22
+ })
23
+ end
24
+
25
+ def call
26
+ pf = R10K::Puppetfile.new(@root, @moduledir, @path)
27
+
28
+ begin
29
+ pf.load
30
+ $stderr.puts "Syntax OK"
31
+ true
32
+ rescue R10K::Error => e
33
+ $stderr.puts R10K::Errors::Formatting.format_exception(e, @trace)
34
+ false
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+
@@ -0,0 +1,32 @@
1
+ require 'r10k/action/cri_runner'
2
+
3
+ module R10K
4
+ module Action
5
+ module Puppetfile
6
+ # Extend the default Cri Runner to use the PUPPETFILE environment
7
+ # variables.
8
+ #
9
+ # @api private
10
+ # @deprecated The use of these environment variables is deprecated and
11
+ # will be removed in 2.0.0.
12
+ class CriRunner < R10K::Action::CriRunner
13
+ def handle_opts(opts)
14
+ opts[:root] ||= wd
15
+ opts[:moduledir] ||= env['PUPPETFILE_DIR']
16
+ opts[:puppetfile] ||= env['PUPPETFILE']
17
+ super(opts)
18
+ end
19
+
20
+ private
21
+
22
+ def env
23
+ ENV
24
+ end
25
+
26
+ def wd
27
+ Dir.getwd
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,53 @@
1
+ require 'r10k/puppetfile'
2
+ require 'r10k/util/setopts'
3
+ require 'r10k/errors/formatting'
4
+ require 'r10k/logging'
5
+
6
+ module R10K
7
+ module Action
8
+ module Puppetfile
9
+ class Install
10
+ include R10K::Logging
11
+ include R10K::Util::Setopts
12
+
13
+ def initialize(opts, argv)
14
+ @opts = opts
15
+ @argv = argv
16
+
17
+ @ok = true
18
+
19
+ setopts(opts, {
20
+ :root => :self,
21
+ :moduledir => :self,
22
+ :puppetfile => :path,
23
+ :trace => :self,
24
+ })
25
+ end
26
+
27
+ def call
28
+ pf = R10K::Puppetfile.new(@root, @moduledir, @path)
29
+ pf.accept(self)
30
+ @ok
31
+ end
32
+
33
+ def visit(type, other, &block)
34
+ send("visit_#{type}", other, &block)
35
+ rescue => e
36
+ logger.error R10K::Errors::Formatting.format_exception(e, @trace)
37
+ @ok = false
38
+ end
39
+
40
+ def visit_puppetfile(pf)
41
+ pf.load
42
+ yield
43
+ pf.purge!
44
+ end
45
+
46
+ def visit_module(mod)
47
+ logger.info "Updating module #{mod.path}"
48
+ mod.sync
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end