r10k 1.1.4 → 1.2.0rc1

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