r10k 1.1.4 → 1.2.0rc1

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.
Files changed (69) hide show
  1. checksums.yaml +8 -8
  2. data/.gitignore +1 -0
  3. data/.nodeset.yml +7 -0
  4. data/.rspec +1 -0
  5. data/.travis.yml +2 -1
  6. data/CHANGELOG +17 -12
  7. data/Gemfile +8 -0
  8. data/README.markdown +4 -2
  9. data/Rakefile +1 -0
  10. data/doc/dynamic-environments.markdown +206 -0
  11. data/doc/puppetfile.markdown +87 -0
  12. data/lib/r10k/cli.rb +1 -1
  13. data/lib/r10k/errors.rb +30 -3
  14. data/lib/r10k/execution.rb +5 -2
  15. data/lib/r10k/git/cache.rb +26 -42
  16. data/lib/r10k/git/commit.rb +22 -0
  17. data/lib/r10k/git/errors.rb +31 -22
  18. data/lib/r10k/git/head.rb +33 -0
  19. data/lib/r10k/git/ref.rb +63 -0
  20. data/lib/r10k/git/repository.rb +65 -36
  21. data/lib/r10k/git/tag.rb +26 -0
  22. data/lib/r10k/git/working_dir.rb +93 -83
  23. data/lib/r10k/git.rb +14 -0
  24. data/lib/r10k/module/forge.rb +129 -62
  25. data/lib/r10k/module/git.rb +72 -6
  26. data/lib/r10k/module/metadata.rb +47 -0
  27. data/lib/r10k/module/svn.rb +99 -0
  28. data/lib/r10k/module.rb +1 -0
  29. data/lib/r10k/module_repository/forge.rb +64 -0
  30. data/lib/r10k/module_repository.rb +8 -0
  31. data/lib/r10k/semver.rb +1 -1
  32. data/lib/r10k/svn/working_dir.rb +76 -0
  33. data/lib/r10k/task/deployment.rb +21 -28
  34. data/lib/r10k/util/subprocess/io.rb +12 -0
  35. data/lib/r10k/util/subprocess/result.rb +36 -0
  36. data/lib/r10k/util/subprocess/runner.rb +88 -0
  37. data/lib/r10k/util/subprocess.rb +107 -0
  38. data/lib/r10k/version.rb +1 -1
  39. data/r10k.gemspec +11 -1
  40. data/spec/fixtures/vcr/cassettes/R10K_ModuleRepository_Forge/and_the_expected_version_is_latest/can_fetch_all_versions_of_a_given_module.yml +42 -0
  41. data/spec/fixtures/vcr/cassettes/R10K_ModuleRepository_Forge/and_the_expected_version_is_latest/can_fetch_the_latest_version_of_a_given_module.yml +42 -0
  42. data/spec/fixtures/vcr/cassettes/R10K_ModuleRepository_Forge/looking_up_versions/can_fetch_all_versions_of_a_given_module.yml +42 -0
  43. data/spec/fixtures/vcr/cassettes/R10K_ModuleRepository_Forge/looking_up_versions/can_fetch_the_latest_version_of_a_given_module.yml +42 -0
  44. data/spec/fixtures/vcr/cassettes/R10K_ModuleRepository_Forge/looking_up_versions.yml +42 -0
  45. data/spec/fixtures/vcr/cassettes/R10K_Module_Forge/and_the_expected_version_is_latest/sets_the_expected_version_based_on_the_latest_forge_version.yml +42 -0
  46. data/spec/rspec-system-r10k/puppetfile.rb +24 -0
  47. data/spec/rspec-system-r10k/tmpdir.rb +32 -0
  48. data/spec/shared-examples/git-ref.rb +49 -0
  49. data/spec/spec_helper.rb +23 -0
  50. data/spec/system/module/forge/install_spec.rb +51 -0
  51. data/spec/system/module/git/install_spec.rb +117 -0
  52. data/spec/system/module/svn/install_spec.rb +51 -0
  53. data/spec/system/module/svn/update_spec.rb +38 -0
  54. data/spec/system/spec_helper.rb +60 -0
  55. data/spec/system/system-helpers.rb +4 -0
  56. data/spec/system/version_spec.rb +7 -0
  57. data/spec/system-provisioning/el.rb +38 -0
  58. data/spec/unit/deployment/source_spec.rb +1 -1
  59. data/spec/unit/git/cache_spec.rb +38 -0
  60. data/spec/unit/git/commit_spec.rb +33 -0
  61. data/spec/unit/git/head_spec.rb +27 -0
  62. data/spec/unit/git/ref_spec.rb +68 -0
  63. data/spec/unit/git/tag_spec.rb +31 -0
  64. data/spec/unit/module/forge_spec.rb +157 -37
  65. data/spec/unit/module/git_spec.rb +49 -0
  66. data/spec/unit/module/metadata_spec.rb +68 -0
  67. data/spec/unit/module/svn_spec.rb +146 -0
  68. data/spec/unit/module_repository/forge_spec.rb +32 -0
  69. metadata +151 -8
@@ -0,0 +1,12 @@
1
+ class R10K::Util::Subprocess::IO
2
+
3
+ attr_reader :stdin
4
+
5
+ attr_accessor :stdout
6
+ attr_accessor :stderr
7
+
8
+ def initialize
9
+ @stdout = '/dev/null'
10
+ @stderr = '/dev/null'
11
+ end
12
+ end
@@ -0,0 +1,36 @@
1
+ # @api private
2
+ class R10K::Util::Subprocess::Result
3
+
4
+ # @!attribute [r] argv
5
+ # @return [Array<String>]
6
+ attr_reader :argv
7
+
8
+ # @!attribute [r] cmd
9
+ # @return [String]
10
+ attr_reader :cmd
11
+
12
+ # @!attribute [r] stdout
13
+ # @return [String]
14
+ attr_reader :stdout
15
+
16
+ # @!attribute [r] stderr
17
+ # @return [String]
18
+ attr_reader :stderr
19
+
20
+ # @!attribute [r] exit_code
21
+ # @return [Integer]
22
+ attr_reader :exit_code
23
+
24
+
25
+ def initialize(argv, stdout, stderr, exit_code)
26
+ @argv = argv
27
+ @cmd = argv.join(' ')
28
+ @stdout = stdout
29
+ @stderr = stderr
30
+ @exit_code = exit_code
31
+ end
32
+
33
+ def [](field)
34
+ send(field)
35
+ end
36
+ end
@@ -0,0 +1,88 @@
1
+ require 'fcntl'
2
+
3
+ # @api private
4
+ class R10K::Util::Subprocess::Runner
5
+
6
+ attr_accessor :cwd
7
+
8
+ attr_reader :io
9
+
10
+ attr_reader :pid
11
+
12
+ attr_reader :status
13
+
14
+ def initialize(argv)
15
+ @argv = argv
16
+
17
+ @io = R10K::Util::Subprocess::IO.new
18
+ end
19
+
20
+ def start
21
+ exec_r, exec_w = status_pipe()
22
+
23
+ @pid = fork do
24
+ exec_r.close
25
+ execute_child(exec_w)
26
+ end
27
+
28
+ exec_w.close
29
+ execute_parent(exec_r)
30
+ end
31
+
32
+ def wait
33
+ if @pid
34
+ _, @status = Process.waitpid2(@pid)
35
+ end
36
+ end
37
+
38
+ def crashed?
39
+ exit_code != 0
40
+ end
41
+
42
+ def exit_code
43
+ @status.exitstatus
44
+ end
45
+
46
+ private
47
+
48
+ def execute_child(exec_w)
49
+ if @cwd
50
+ Dir.chdir @cwd
51
+ end
52
+
53
+ # Create a new session for the forked child. This prevents children from
54
+ # ever being the foreground process on a TTY, which is almost always what
55
+ # we want in r10k.
56
+ Process.setsid
57
+
58
+ # Reopen file descriptors
59
+ STDOUT.reopen(io.stdout)
60
+ STDERR.reopen(io.stderr)
61
+
62
+ executable = @argv.shift
63
+ exec([executable, executable], *@argv)
64
+ rescue SystemCallError => e
65
+ exec_w.write(e.message)
66
+ end
67
+
68
+ def execute_parent(exec_r)
69
+
70
+ if not exec_r.eof?
71
+ msg = exec_r.read || "exec() failed"
72
+ raise "Could not execute #{@argv.join(' ')}: #{msg}"
73
+ end
74
+ end
75
+
76
+ # Create a pipe so that the parent can verify that the child process
77
+ # successfully executed. The pipe will be closed on a successful exec(),
78
+ # and will contain an error message on failure.
79
+ #
80
+ # @return [IO, IO] The reader and writer for this pipe
81
+ def status_pipe
82
+ r_pipe, w_pipe = ::IO.pipe
83
+
84
+ w_pipe.fcntl(Fcntl::F_SETFD, Fcntl::FD_CLOEXEC)
85
+
86
+ [r_pipe, w_pipe]
87
+ end
88
+ end
@@ -0,0 +1,107 @@
1
+ require 'r10k/logging'
2
+ require 'r10k/errors'
3
+
4
+ module R10K
5
+ module Util
6
+
7
+ # The subprocess namespace implements a subset of childprocess. It has
8
+ # three # main differences.
9
+ #
10
+ # 1. child processes invoke setsid()
11
+ # 2. there are no dependencies on C extensions (ffi)
12
+ # 3. it only support unixy systems.
13
+ class Subprocess
14
+
15
+ require 'r10k/util/subprocess/runner'
16
+ require 'r10k/util/subprocess/io'
17
+ require 'r10k/util/subprocess/result'
18
+
19
+ include R10K::Logging
20
+
21
+ attr_accessor :raise_on_fail
22
+ attr_accessor :cwd
23
+
24
+ attr_writer :logger
25
+
26
+ def initialize(argv)
27
+ @argv = argv
28
+
29
+ @raise_on_fail = false
30
+ end
31
+
32
+ def execute
33
+ subprocess = R10K::Util::Subprocess::Runner.new(@argv)
34
+ subprocess.cwd = @cwd
35
+
36
+ stdout_r, stdout_w = attach_pipe(subprocess.io, :stdout, :reader)
37
+ stderr_r, stderr_w = attach_pipe(subprocess.io, :stderr, :reader)
38
+
39
+ logmsg = "Execute: #{@argv.join(' ')}"
40
+ logmsg << "(cwd: #{@cwd})" if @cwd
41
+ logger.debug1 logmsg
42
+
43
+ subprocess.start
44
+ stdout_w.close
45
+ stderr_w.close
46
+ subprocess.wait
47
+
48
+ stdout = stdout_r.read
49
+ stderr = stderr_r.read
50
+
51
+ result = Result.new(@argv, stdout, stderr, subprocess.exit_code)
52
+
53
+ logger.debug2 "[#{result.cmd}] STDOUT: #{result.stdout.chomp}" unless result.stdout.empty?
54
+ logger.debug2 "[#{result.cmd}] STDERR: #{result.stderr.chomp}" unless result.stderr.empty?
55
+
56
+ if @raise_on_fail and subprocess.crashed?
57
+ raise SubprocessError.new(:result => result)
58
+ end
59
+
60
+ result
61
+ end
62
+
63
+ private
64
+
65
+ # Attach a pipe to the given process, and return the requested end of the
66
+ # pipe.
67
+ #
68
+ # @param subproc [Runner]
69
+ # @param name [Symbol] The name of the setter method on the subproc
70
+ # @param type [Symbol] One of (:reader, :writer) denoting the type to return
71
+ #
72
+ # @return [Array<IO>] The reader and writer endpoints of the pipe
73
+ def attach_pipe(subproc, name, type)
74
+ rd, wr = ::IO.pipe
75
+
76
+ case type
77
+ when :reader
78
+ other = wr
79
+ when :writer
80
+ other = rd
81
+ end
82
+
83
+ subproc.send("#{name}=", other)
84
+
85
+ [rd, wr]
86
+ end
87
+
88
+ class SubprocessError < R10KError
89
+
90
+ attr_reader :result
91
+
92
+ def initialize(mesg = nil, options = {})
93
+ super
94
+ @result = @options[:result]
95
+ end
96
+
97
+ def to_s
98
+ if @mesg
99
+ @mesg
100
+ else
101
+ "Command #{@result.cmd} exited with #{@result.exit_code}: #{@result.stderr}"
102
+ end
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
data/lib/r10k/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module R10K
2
- VERSION = '1.1.4'
2
+ VERSION = '1.2.0rc1'
3
3
  end
data/r10k.gemspec CHANGED
@@ -22,11 +22,21 @@ Gem::Specification.new do |s|
22
22
 
23
23
  s.add_dependency 'colored', '>= 1.2'
24
24
  s.add_dependency 'cri', '~> 2.4.0'
25
+
25
26
  s.add_dependency 'systemu', '~> 2.5.2'
27
+
26
28
  s.add_dependency 'log4r', '>= 1.1.10'
27
- s.add_dependency 'json_pure'
29
+ s.add_dependency 'multi_json', '~> 1.8.2'
30
+ s.add_dependency 'json_pure', '~> 1.8.1'
31
+
32
+ s.add_dependency 'faraday', '~> 0.8.8'
33
+ s.add_dependency 'faraday_middleware', '~> 0.9.0'
34
+ s.add_dependency 'faraday_middleware-multi_json', '~> 0.0.5'
28
35
 
29
36
  s.add_development_dependency 'rspec', '~> 2.14.0'
37
+ s.add_development_dependency 'vcr', '~> 2.8.0'
38
+
39
+ s.add_development_dependency 'yard', '~> 0.8.7.3'
30
40
 
31
41
  s.files = %x[git ls-files].split($/)
32
42
  s.require_path = 'lib'
@@ -0,0 +1,42 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://forge.puppetlabs.com/api/v1/releases.json?module=adrien%2Fboolean
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.8.8
12
+ response:
13
+ status:
14
+ code: 200
15
+ message:
16
+ headers:
17
+ server:
18
+ - nginx
19
+ date:
20
+ - Tue, 31 Dec 2013 02:53:38 GMT
21
+ content-type:
22
+ - application/json
23
+ content-length:
24
+ - '432'
25
+ connection:
26
+ - close
27
+ status:
28
+ - 200 OK
29
+ x-frame-options:
30
+ - sameorigin
31
+ x-xss-protection:
32
+ - 1; mode=block
33
+ x-node:
34
+ - forgeweb04
35
+ x-revision:
36
+ - b288c1e7e86f82eef7692085670c78693062c84d
37
+ body:
38
+ encoding: US-ASCII
39
+ string: ! '{"adrien/boolean":[{"file":"/system/releases/a/adrien/adrien-boolean-0.9.0-rc1.tar.gz","version":"0.9.0-rc1","dependencies":[]},{"file":"/system/releases/a/adrien/adrien-boolean-0.9.0.tar.gz","version":"0.9.0","dependencies":[]},{"file":"/system/releases/a/adrien/adrien-boolean-1.0.0.tar.gz","version":"1.0.0","dependencies":[]},{"file":"/system/releases/a/adrien/adrien-boolean-1.0.1.tar.gz","version":"1.0.1","dependencies":[]}]}'
40
+ http_version:
41
+ recorded_at: Tue, 31 Dec 2013 02:54:56 GMT
42
+ recorded_with: VCR 2.8.0
@@ -0,0 +1,42 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://forge.puppetlabs.com/api/v1/releases.json?module=adrien%2Fboolean
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.8.8
12
+ response:
13
+ status:
14
+ code: 200
15
+ message:
16
+ headers:
17
+ server:
18
+ - nginx
19
+ date:
20
+ - Tue, 31 Dec 2013 02:53:38 GMT
21
+ content-type:
22
+ - application/json
23
+ content-length:
24
+ - '432'
25
+ connection:
26
+ - close
27
+ status:
28
+ - 200 OK
29
+ x-frame-options:
30
+ - sameorigin
31
+ x-xss-protection:
32
+ - 1; mode=block
33
+ x-node:
34
+ - forgeweb02
35
+ x-revision:
36
+ - b288c1e7e86f82eef7692085670c78693062c84d
37
+ body:
38
+ encoding: US-ASCII
39
+ string: ! '{"adrien/boolean":[{"file":"/system/releases/a/adrien/adrien-boolean-0.9.0-rc1.tar.gz","version":"0.9.0-rc1","dependencies":[]},{"file":"/system/releases/a/adrien/adrien-boolean-0.9.0.tar.gz","version":"0.9.0","dependencies":[]},{"file":"/system/releases/a/adrien/adrien-boolean-1.0.0.tar.gz","version":"1.0.0","dependencies":[]},{"file":"/system/releases/a/adrien/adrien-boolean-1.0.1.tar.gz","version":"1.0.1","dependencies":[]}]}'
40
+ http_version:
41
+ recorded_at: Tue, 31 Dec 2013 02:54:57 GMT
42
+ recorded_with: VCR 2.8.0
@@ -0,0 +1,42 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://forge.puppetlabs.com/api/v1/releases.json?module=adrien%2Fboolean
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.8.8
12
+ response:
13
+ status:
14
+ code: 200
15
+ message:
16
+ headers:
17
+ server:
18
+ - nginx
19
+ date:
20
+ - Wed, 25 Dec 2013 23:48:29 GMT
21
+ content-type:
22
+ - application/json
23
+ content-length:
24
+ - '432'
25
+ connection:
26
+ - close
27
+ status:
28
+ - 200 OK
29
+ x-frame-options:
30
+ - sameorigin
31
+ x-xss-protection:
32
+ - 1; mode=block
33
+ x-node:
34
+ - forgeweb03
35
+ x-revision:
36
+ - b288c1e7e86f82eef7692085670c78693062c84d
37
+ body:
38
+ encoding: US-ASCII
39
+ string: ! '{"adrien/boolean":[{"file":"/system/releases/a/adrien/adrien-boolean-0.9.0-rc1.tar.gz","version":"0.9.0-rc1","dependencies":[]},{"file":"/system/releases/a/adrien/adrien-boolean-0.9.0.tar.gz","version":"0.9.0","dependencies":[]},{"file":"/system/releases/a/adrien/adrien-boolean-1.0.0.tar.gz","version":"1.0.0","dependencies":[]},{"file":"/system/releases/a/adrien/adrien-boolean-1.0.1.tar.gz","version":"1.0.1","dependencies":[]}]}'
40
+ http_version:
41
+ recorded_at: Wed, 25 Dec 2013 23:49:42 GMT
42
+ recorded_with: VCR 2.8.0
@@ -0,0 +1,42 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://forge.puppetlabs.com/api/v1/releases.json?module=adrien%2Fboolean
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ User-Agent:
11
+ - Faraday v0.8.8
12
+ response:
13
+ status:
14
+ code: 200
15
+ message:
16
+ headers:
17
+ server:
18
+ - nginx
19
+ date:
20
+ - Wed, 25 Dec 2013 23:48:29 GMT
21
+ content-type:
22
+ - application/json
23
+ content-length:
24
+ - '432'
25
+ connection:
26
+ - close
27
+ status:
28
+ - 200 OK
29
+ x-frame-options:
30
+ - sameorigin
31
+ x-xss-protection:
32
+ - 1; mode=block
33
+ x-node:
34
+ - forgeweb01
35
+ x-revision:
36
+ - b288c1e7e86f82eef7692085670c78693062c84d
37
+ body:
38
+ encoding: US-ASCII
39
+ string: ! '{"adrien/boolean":[{"file":"/system/releases/a/adrien/adrien-boolean-0.9.0-rc1.tar.gz","version":"0.9.0-rc1","dependencies":[]},{"file":"/system/releases/a/adrien/adrien-boolean-0.9.0.tar.gz","version":"0.9.0","dependencies":[]},{"file":"/system/releases/a/adrien/adrien-boolean-1.0.0.tar.gz","version":"1.0.0","dependencies":[]},{"file":"/system/releases/a/adrien/adrien-boolean-1.0.1.tar.gz","version":"1.0.1","dependencies":[]}]}'
40
+ http_version:
41
+ recorded_at: Wed, 25 Dec 2013 23:49:43 GMT
42
+ recorded_with: VCR 2.8.0