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.
- checksums.yaml +8 -8
- data/.gitignore +1 -0
- data/.nodeset.yml +7 -0
- data/.rspec +1 -0
- data/.travis.yml +2 -1
- data/CHANGELOG +17 -12
- data/Gemfile +8 -0
- data/README.markdown +4 -2
- data/Rakefile +1 -0
- data/doc/dynamic-environments.markdown +206 -0
- data/doc/puppetfile.markdown +87 -0
- data/lib/r10k/cli.rb +1 -1
- data/lib/r10k/errors.rb +30 -3
- data/lib/r10k/execution.rb +5 -2
- data/lib/r10k/git/cache.rb +26 -42
- data/lib/r10k/git/commit.rb +22 -0
- data/lib/r10k/git/errors.rb +31 -22
- data/lib/r10k/git/head.rb +33 -0
- data/lib/r10k/git/ref.rb +63 -0
- data/lib/r10k/git/repository.rb +65 -36
- data/lib/r10k/git/tag.rb +26 -0
- data/lib/r10k/git/working_dir.rb +93 -83
- data/lib/r10k/git.rb +14 -0
- data/lib/r10k/module/forge.rb +129 -62
- data/lib/r10k/module/git.rb +72 -6
- data/lib/r10k/module/metadata.rb +47 -0
- data/lib/r10k/module/svn.rb +99 -0
- data/lib/r10k/module.rb +1 -0
- data/lib/r10k/module_repository/forge.rb +64 -0
- data/lib/r10k/module_repository.rb +8 -0
- data/lib/r10k/semver.rb +1 -1
- data/lib/r10k/svn/working_dir.rb +76 -0
- data/lib/r10k/task/deployment.rb +21 -28
- data/lib/r10k/util/subprocess/io.rb +12 -0
- data/lib/r10k/util/subprocess/result.rb +36 -0
- data/lib/r10k/util/subprocess/runner.rb +88 -0
- data/lib/r10k/util/subprocess.rb +107 -0
- data/lib/r10k/version.rb +1 -1
- data/r10k.gemspec +11 -1
- 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
- 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
- data/spec/fixtures/vcr/cassettes/R10K_ModuleRepository_Forge/looking_up_versions/can_fetch_all_versions_of_a_given_module.yml +42 -0
- data/spec/fixtures/vcr/cassettes/R10K_ModuleRepository_Forge/looking_up_versions/can_fetch_the_latest_version_of_a_given_module.yml +42 -0
- data/spec/fixtures/vcr/cassettes/R10K_ModuleRepository_Forge/looking_up_versions.yml +42 -0
- 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
- data/spec/rspec-system-r10k/puppetfile.rb +24 -0
- data/spec/rspec-system-r10k/tmpdir.rb +32 -0
- data/spec/shared-examples/git-ref.rb +49 -0
- data/spec/spec_helper.rb +23 -0
- data/spec/system/module/forge/install_spec.rb +51 -0
- data/spec/system/module/git/install_spec.rb +117 -0
- data/spec/system/module/svn/install_spec.rb +51 -0
- data/spec/system/module/svn/update_spec.rb +38 -0
- data/spec/system/spec_helper.rb +60 -0
- data/spec/system/system-helpers.rb +4 -0
- data/spec/system/version_spec.rb +7 -0
- data/spec/system-provisioning/el.rb +38 -0
- data/spec/unit/deployment/source_spec.rb +1 -1
- data/spec/unit/git/cache_spec.rb +38 -0
- data/spec/unit/git/commit_spec.rb +33 -0
- data/spec/unit/git/head_spec.rb +27 -0
- data/spec/unit/git/ref_spec.rb +68 -0
- data/spec/unit/git/tag_spec.rb +31 -0
- data/spec/unit/module/forge_spec.rb +157 -37
- data/spec/unit/module/git_spec.rb +49 -0
- data/spec/unit/module/metadata_spec.rb +68 -0
- data/spec/unit/module/svn_spec.rb +146 -0
- data/spec/unit/module_repository/forge_spec.rb +32 -0
- metadata +151 -8
@@ -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
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 '
|
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
|