r10k 3.13.0 → 3.14.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/docker.yml +1 -1
- data/.github/workflows/rspec_tests.yml +2 -2
- data/.travis.yml +1 -1
- data/CHANGELOG.mkd +10 -0
- data/doc/dynamic-environments/configuration.mkd +24 -0
- data/doc/puppetfile.mkd +13 -0
- data/lib/r10k/environment/name.rb +14 -9
- data/lib/r10k/environment/tarball.rb +78 -0
- data/lib/r10k/environment.rb +1 -0
- data/lib/r10k/forge/module_release.rb +2 -1
- data/lib/r10k/git/cache.rb +4 -13
- data/lib/r10k/git/rugged/base_repository.rb +12 -1
- data/lib/r10k/git/rugged/cache.rb +8 -0
- data/lib/r10k/git/stateful_repository.rb +2 -0
- data/lib/r10k/initializers.rb +10 -0
- data/lib/r10k/module/tarball.rb +101 -0
- data/lib/r10k/module.rb +1 -0
- data/lib/r10k/module_loader/puppetfile.rb +10 -1
- data/lib/r10k/source/git.rb +18 -18
- data/lib/r10k/tarball.rb +183 -0
- data/lib/r10k/util/cacheable.rb +31 -0
- data/lib/r10k/util/downloader.rb +134 -0
- data/lib/r10k/version.rb +1 -1
- data/locales/r10k.pot +39 -23
- data/r10k.gemspec +2 -2
- data/spec/fixtures/tarball/tarball.tar.gz +0 -0
- data/spec/integration/git/rugged/cache_spec.rb +33 -0
- data/spec/shared-contexts/tarball.rb +32 -0
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/action/deploy/module_spec.rb +2 -2
- data/spec/unit/environment/name_spec.rb +18 -0
- data/spec/unit/environment/tarball_spec.rb +45 -0
- data/spec/unit/git/cache_spec.rb +2 -15
- data/spec/unit/git/rugged/cache_spec.rb +19 -0
- data/spec/unit/module/tarball_spec.rb +70 -0
- data/spec/unit/module_loader/puppetfile_spec.rb +4 -1
- data/spec/unit/tarball_spec.rb +57 -0
- data/spec/unit/util/cacheable_spec.rb +23 -0
- data/spec/unit/util/downloader_spec.rb +98 -0
- metadata +29 -16
data/lib/r10k/tarball.rb
ADDED
@@ -0,0 +1,183 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'find'
|
3
|
+
require 'minitar'
|
4
|
+
require 'tempfile'
|
5
|
+
require 'uri'
|
6
|
+
require 'zlib'
|
7
|
+
require 'r10k/settings'
|
8
|
+
require 'r10k/settings/mixin'
|
9
|
+
require 'r10k/util/platform'
|
10
|
+
require 'r10k/util/cacheable'
|
11
|
+
require 'r10k/util/downloader'
|
12
|
+
|
13
|
+
module R10K
|
14
|
+
class Tarball
|
15
|
+
|
16
|
+
include R10K::Settings::Mixin
|
17
|
+
include R10K::Util::Cacheable
|
18
|
+
include R10K::Util::Downloader
|
19
|
+
|
20
|
+
def_setting_attr :proxy # Defaults to global proxy setting
|
21
|
+
def_setting_attr :cache_root, R10K::Util::Cacheable.default_cachedir
|
22
|
+
|
23
|
+
# @!attribute [rw] name
|
24
|
+
# @return [String] The tarball's name
|
25
|
+
attr_accessor :name
|
26
|
+
|
27
|
+
# @!attribute [rw] source
|
28
|
+
# @return [String] The tarball's source
|
29
|
+
attr_accessor :source
|
30
|
+
|
31
|
+
# @!attribute [rw] checksum
|
32
|
+
# @return [String] The tarball's expected sha256 digest
|
33
|
+
attr_accessor :checksum
|
34
|
+
|
35
|
+
# @param name [String] The name of the tarball content
|
36
|
+
# @param source [String] The source for the tarball content
|
37
|
+
# @param checksum [String] The sha256 digest of the tarball content
|
38
|
+
def initialize(name, source, checksum: nil)
|
39
|
+
@name = name
|
40
|
+
@source = source
|
41
|
+
@checksum = checksum
|
42
|
+
|
43
|
+
# At this time, the only checksum type supported is sha256. In the future,
|
44
|
+
# we may decide to support other algorithms if a use case arises. TBD.
|
45
|
+
checksum_algorithm = :SHA256
|
46
|
+
end
|
47
|
+
|
48
|
+
# @return [String] Directory. Where the cache_basename file will be created.
|
49
|
+
def cache_dirname
|
50
|
+
File.join(settings[:cache_root], 'tarball')
|
51
|
+
end
|
52
|
+
|
53
|
+
# The final cache_path should match one of the templates:
|
54
|
+
#
|
55
|
+
# - {cachedir}/{checksum}.tar.gz
|
56
|
+
# - {cachedir}/{source}.tar.gz
|
57
|
+
#
|
58
|
+
# @return [String] File. The full file path the tarball will be cached to.
|
59
|
+
def cache_path
|
60
|
+
File.join(cache_dirname, cache_basename)
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return [String] The basename of the tarball cache file.
|
64
|
+
def cache_basename
|
65
|
+
if checksum.nil?
|
66
|
+
sanitized_dirname(source) + '.tar.gz'
|
67
|
+
else
|
68
|
+
checksum + '.tar.gz'
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
# Extract the cached tarball to the target directory.
|
73
|
+
#
|
74
|
+
# @param target_dir [String] Where to unpack the tarball
|
75
|
+
def unpack(target_dir)
|
76
|
+
file = File.open(cache_path, 'rb')
|
77
|
+
reader = Zlib::GzipReader.new(file)
|
78
|
+
begin
|
79
|
+
Minitar.unpack(reader, target_dir)
|
80
|
+
ensure
|
81
|
+
reader.close
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# @param target_dir [String] The directory to check if is in sync with the
|
86
|
+
# tarball content
|
87
|
+
# @param ignore_untracked_files [Boolean] If true, consider the target
|
88
|
+
# dir to be in sync as long as all tracked content matches.
|
89
|
+
#
|
90
|
+
# @return [Boolean]
|
91
|
+
def insync?(target_dir, ignore_untracked_files: false)
|
92
|
+
target_tree_entries = Find.find(target_dir).map(&:to_s) - [target_dir]
|
93
|
+
each_tarball_entry do |entry|
|
94
|
+
found = target_tree_entries.delete(File.join(target_dir, entry.full_name.chomp('/')))
|
95
|
+
return false if found.nil?
|
96
|
+
next if entry.directory?
|
97
|
+
return false unless file_digest(found) == reader_digest(entry)
|
98
|
+
end
|
99
|
+
|
100
|
+
if ignore_untracked_files
|
101
|
+
# We wouldn't have gotten this far if there were discrepancies in
|
102
|
+
# tracked content
|
103
|
+
true
|
104
|
+
else
|
105
|
+
# If there are still files in target_tree_entries, then there is
|
106
|
+
# untracked content present in the target tree. If not, we're in sync.
|
107
|
+
target_tree_entries.empty?
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Download the tarball from @source to @cache_path
|
112
|
+
def get
|
113
|
+
Tempfile.open(cache_basename) do |tempfile|
|
114
|
+
tempfile.binmode
|
115
|
+
src_uri = URI.parse(source)
|
116
|
+
|
117
|
+
temp_digest = case src_uri.scheme
|
118
|
+
when 'file', nil
|
119
|
+
copy(src_uri.path, tempfile)
|
120
|
+
when %r{^[a-z]$} # Windows drive letter
|
121
|
+
copy(src_uri.to_s, tempfile)
|
122
|
+
when %r{^https?$}
|
123
|
+
download(src_uri, tempfile)
|
124
|
+
else
|
125
|
+
raise "Unexpected source scheme #{src_uri.scheme}"
|
126
|
+
end
|
127
|
+
|
128
|
+
# Verify the download
|
129
|
+
unless (checksum == temp_digest) || checksum.nil?
|
130
|
+
raise 'Downloaded file does not match checksum'
|
131
|
+
end
|
132
|
+
|
133
|
+
# Move the download to cache_path
|
134
|
+
FileUtils::mkdir_p(cache_dirname)
|
135
|
+
begin
|
136
|
+
FileUtils.mv(tempfile.path, cache_path)
|
137
|
+
rescue Errno::EACCES
|
138
|
+
# It may be the case that permissions don't permit moving the file
|
139
|
+
# into place, but do permit overwriting an existing in-place file.
|
140
|
+
FileUtils.cp(tempfile.path, cache_path)
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# Checks the cached tarball's digest against the expected checksum. Returns
|
146
|
+
# false if no cached file is present. If the tarball has no expected
|
147
|
+
# checksum, any cached file is assumed to be valid.
|
148
|
+
#
|
149
|
+
# @return [Boolean]
|
150
|
+
def cache_valid?
|
151
|
+
return false unless File.exist?(cache_path)
|
152
|
+
return true if checksum.nil?
|
153
|
+
checksum == file_digest(cache_path)
|
154
|
+
end
|
155
|
+
|
156
|
+
# List all of the files contained in the tarball and their paths. This is
|
157
|
+
# useful for implementing R10K::Purgable
|
158
|
+
#
|
159
|
+
# @return [Array] A normalized list of file paths contained in the archive
|
160
|
+
def paths
|
161
|
+
names = Array.new
|
162
|
+
each_tarball_entry { |entry| names << Pathname.new(entry).cleanpath.to_s }
|
163
|
+
names - ['.']
|
164
|
+
end
|
165
|
+
|
166
|
+
def cache_checksum
|
167
|
+
raise R10K::Error, _("Cache not present at %{path}") % {path: cache_path} unless File.exist?(cache_path)
|
168
|
+
file_digest(cache_path)
|
169
|
+
end
|
170
|
+
|
171
|
+
private
|
172
|
+
|
173
|
+
def each_tarball_entry(&block)
|
174
|
+
File.open(cache_path, 'rb') do |file|
|
175
|
+
Zlib::GzipReader.wrap(file) do |reader|
|
176
|
+
Archive::Tar::Minitar::Input.each_entry(reader) do |entry|
|
177
|
+
yield entry
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module R10K
|
2
|
+
module Util
|
3
|
+
|
4
|
+
# Utility mixin for classes that need to implement caches
|
5
|
+
#
|
6
|
+
# @abstract Classes using this mixin need to implement {#managed_directory} and
|
7
|
+
# {#desired_contents}
|
8
|
+
module Cacheable
|
9
|
+
|
10
|
+
# Provide a default cachedir location. This is consumed by R10K::Settings
|
11
|
+
# for appropriate global default values.
|
12
|
+
#
|
13
|
+
# @return [String] Path to the default cache directory
|
14
|
+
def self.default_cachedir(basename = 'cache')
|
15
|
+
if R10K::Util::Platform.windows?
|
16
|
+
File.join(ENV['LOCALAPPDATA'], 'r10k', basename)
|
17
|
+
else
|
18
|
+
File.join(ENV['HOME'] || '/root', '.r10k', basename)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Reformat a string into something that can be used as a directory
|
23
|
+
#
|
24
|
+
# @param string [String] An identifier to create a sanitized dirname for
|
25
|
+
# @return [String] A sanitized dirname for the given string
|
26
|
+
def sanitized_dirname(string)
|
27
|
+
string.gsub(/(\w+:\/\/)(.*)(@)/, '\1').gsub(/[^@\w\.-]/, '-')
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require 'digest'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
module R10K
|
5
|
+
module Util
|
6
|
+
|
7
|
+
# Utility mixin for classes that need to download files
|
8
|
+
module Downloader
|
9
|
+
|
10
|
+
# Downloader objects need to checksum downloaded or saved content. The
|
11
|
+
# algorithm used to perform this checksumming (and therefore the kinds of
|
12
|
+
# checksums returned by various methods) is reported by this method.
|
13
|
+
#
|
14
|
+
# @return [Symbol] The checksum algorithm the downloader uses
|
15
|
+
def checksum_algorithm
|
16
|
+
@checksum_algorithm ||= :SHA256
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# Set the checksum algorithm the downloader should use. It should be a
|
22
|
+
# symbol, and a valid Ruby 'digest' library algorithm. The default is
|
23
|
+
# :SHA256.
|
24
|
+
#
|
25
|
+
# @param algorithm [Symbol] The checksum algorithm the downloader should use
|
26
|
+
def checksum_algorithm=(algorithm)
|
27
|
+
@checksum_algorithm = algorithm
|
28
|
+
end
|
29
|
+
|
30
|
+
CHUNK_SIZE = 64 * 1024 # 64 kb
|
31
|
+
|
32
|
+
# @param src_uri [URI] The URI to download from
|
33
|
+
# @param dst_file [String] The file or path to save to
|
34
|
+
# @return [String] The downloaded file's hex digest
|
35
|
+
def download(src_uri, dst_file)
|
36
|
+
digest = Digest(checksum_algorithm).new
|
37
|
+
http_get(src_uri) do |resp|
|
38
|
+
File.open(dst_file, 'wb') do |output_stream|
|
39
|
+
resp.read_body do |chunk|
|
40
|
+
output_stream.write(chunk)
|
41
|
+
digest.update(chunk)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
digest.hexdigest
|
47
|
+
end
|
48
|
+
|
49
|
+
# @param src_file The file or path to copy from
|
50
|
+
# @param dst_file The file or path to copy to
|
51
|
+
# @return [String] The copied file's sha256 hex digest
|
52
|
+
def copy(src_file, dst_file)
|
53
|
+
digest = Digest(checksum_algorithm).new
|
54
|
+
File.open(src_file, 'rb') do |input_stream|
|
55
|
+
File.open(dst_file, 'wb') do |output_stream|
|
56
|
+
until input_stream.eof?
|
57
|
+
chunk = input_stream.read(CHUNK_SIZE)
|
58
|
+
output_stream.write(chunk)
|
59
|
+
digest.update(chunk)
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
digest.hexdigest
|
65
|
+
end
|
66
|
+
|
67
|
+
# Start a Net::HTTP::Get connection, then yield the Net::HTTPSuccess object
|
68
|
+
# to the caller's block. Follow redirects if Net::HTTPRedirection responses
|
69
|
+
# are encountered, and use a proxy if directed.
|
70
|
+
#
|
71
|
+
# @param uri [URI] The URI to download the file from
|
72
|
+
# @param redirect_limit [Integer] How many redirects to permit before failing
|
73
|
+
# @param proxy [URI, String] The URI to use as a proxy
|
74
|
+
def http_get(uri, redirect_limit: 10, proxy: nil, &block)
|
75
|
+
raise "HTTP redirect too deep" if redirect_limit.zero?
|
76
|
+
|
77
|
+
session = Net::HTTP.new(uri.host, uri.port, *proxy_to_array(proxy))
|
78
|
+
session.use_ssl = true if uri.scheme == 'https'
|
79
|
+
session.start
|
80
|
+
|
81
|
+
begin
|
82
|
+
session.request_get(uri) do |response|
|
83
|
+
case response
|
84
|
+
when Net::HTTPRedirection
|
85
|
+
redirect = response['location']
|
86
|
+
session.finish
|
87
|
+
return http_get(URI.parse(redirect), redirect_limit: redirect_limit - 1, proxy: proxy, &block)
|
88
|
+
when Net::HTTPSuccess
|
89
|
+
yield response
|
90
|
+
else
|
91
|
+
raise "Unexpected response code #{response.code}: #{response}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
ensure
|
95
|
+
session.finish if session.active?
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
# Helper method to translate a proxy URI to array arguments for
|
100
|
+
# Net::HTTP#new. A nil argument returns nil array elements.
|
101
|
+
def proxy_to_array(proxy_uri)
|
102
|
+
if proxy_uri
|
103
|
+
px = proxy_uri.is_a?(URI) ? proxy_uri : URI.parse(proxy_uri)
|
104
|
+
[px.host, px.port, px.user, px.password]
|
105
|
+
else
|
106
|
+
[nil, nil, nil, nil]
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
# Return the sha256 digest of the file at the given path
|
111
|
+
#
|
112
|
+
# @param path [String] The path to the file
|
113
|
+
# @return [String] The file's sha256 hex digest
|
114
|
+
def file_digest(path)
|
115
|
+
File.open(path) do |file|
|
116
|
+
reader_digest(file)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
# Return the sha256 digest of the readable data
|
121
|
+
#
|
122
|
+
# @param reader [String] An object that responds to #read
|
123
|
+
# @return [String] The read data's sha256 hex digest
|
124
|
+
def reader_digest(reader)
|
125
|
+
digest = Digest(checksum_algorithm).new
|
126
|
+
while chunk = reader.read(CHUNK_SIZE)
|
127
|
+
digest.update(chunk)
|
128
|
+
end
|
129
|
+
|
130
|
+
digest.hexdigest
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
data/lib/r10k/version.rb
CHANGED
@@ -2,5 +2,5 @@ module R10K
|
|
2
2
|
# When updating to a new major (X) or minor (Y) version, include `#major` or
|
3
3
|
# `#minor` (respectively) in your commit message to trigger the appropriate
|
4
4
|
# release. Otherwise, a new patch (Z) version will be released.
|
5
|
-
VERSION = '3.
|
5
|
+
VERSION = '3.14.0'
|
6
6
|
end
|
data/locales/r10k.pot
CHANGED
@@ -6,11 +6,11 @@
|
|
6
6
|
#, fuzzy
|
7
7
|
msgid ""
|
8
8
|
msgstr ""
|
9
|
-
"Project-Id-Version: r10k 3.9.3-
|
9
|
+
"Project-Id-Version: r10k 3.9.3-170-g8cb36435\n"
|
10
10
|
"\n"
|
11
11
|
"Report-Msgid-Bugs-To: docs@puppetlabs.com\n"
|
12
|
-
"POT-Creation-Date: 2021-
|
13
|
-
"PO-Revision-Date: 2021-
|
12
|
+
"POT-Creation-Date: 2021-11-16 21:43+0000\n"
|
13
|
+
"PO-Revision-Date: 2021-11-16 21:43+0000\n"
|
14
14
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
15
15
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
16
16
|
"Language: \n"
|
@@ -75,15 +75,15 @@ msgstr ""
|
|
75
75
|
msgid "Syntax OK"
|
76
76
|
msgstr ""
|
77
77
|
|
78
|
-
#: ../lib/r10k/action/runner.rb:
|
78
|
+
#: ../lib/r10k/action/runner.rb:63 ../lib/r10k/deployment/config.rb:42
|
79
79
|
msgid "Overriding config file setting '%{key}': '%{old_val}' -> '%{new_val}'"
|
80
80
|
msgstr ""
|
81
81
|
|
82
|
-
#: ../lib/r10k/action/runner.rb:
|
82
|
+
#: ../lib/r10k/action/runner.rb:105
|
83
83
|
msgid "Reading configuration from %{config_path}"
|
84
84
|
msgstr ""
|
85
85
|
|
86
|
-
#: ../lib/r10k/action/runner.rb:
|
86
|
+
#: ../lib/r10k/action/runner.rb:108
|
87
87
|
msgid "No config file explicitly given and no default config file could be found, default settings will be used."
|
88
88
|
msgstr ""
|
89
89
|
|
@@ -155,19 +155,19 @@ msgstr ""
|
|
155
155
|
msgid "Proc %{block} for feature %{name} returned %{output}"
|
156
156
|
msgstr ""
|
157
157
|
|
158
|
-
#: ../lib/r10k/forge/module_release.rb:
|
158
|
+
#: ../lib/r10k/forge/module_release.rb:197
|
159
159
|
msgid "Unpacking %{tarball_cache_path} to %{target_dir} (with tmpdir %{tmp_path})"
|
160
160
|
msgstr ""
|
161
161
|
|
162
|
-
#: ../lib/r10k/forge/module_release.rb:
|
162
|
+
#: ../lib/r10k/forge/module_release.rb:199
|
163
163
|
msgid "Valid files unpacked: %{valid_files}"
|
164
164
|
msgstr ""
|
165
165
|
|
166
|
-
#: ../lib/r10k/forge/module_release.rb:
|
166
|
+
#: ../lib/r10k/forge/module_release.rb:201
|
167
167
|
msgid "These files existed in the module's tar file, but are invalid filetypes and were not unpacked: %{invalid_files}"
|
168
168
|
msgstr ""
|
169
169
|
|
170
|
-
#: ../lib/r10k/forge/module_release.rb:
|
170
|
+
#: ../lib/r10k/forge/module_release.rb:204
|
171
171
|
msgid "Symlinks are unsupported and were not unpacked from the module tarball. %{release_slug} contained these ignored symlinks: %{symlinks}"
|
172
172
|
msgstr ""
|
173
173
|
|
@@ -203,11 +203,11 @@ msgstr ""
|
|
203
203
|
msgid "Cannot write %{file}; parent directory does not exist"
|
204
204
|
msgstr ""
|
205
205
|
|
206
|
-
#: ../lib/r10k/git/cache.rb:
|
206
|
+
#: ../lib/r10k/git/cache.rb:57
|
207
207
|
msgid "%{class}#path is deprecated; use #git_dir"
|
208
208
|
msgstr ""
|
209
209
|
|
210
|
-
#: ../lib/r10k/git/cache.rb:
|
210
|
+
#: ../lib/r10k/git/cache.rb:86
|
211
211
|
msgid "Creating new git cache for %{remote}"
|
212
212
|
msgstr ""
|
213
213
|
|
@@ -223,6 +223,14 @@ msgstr ""
|
|
223
223
|
msgid "Rugged versions prior to 0.24.0 do not support pruning stale branches during fetch, please upgrade your \\'rugged\\' gem. (Current version is: %{version})"
|
224
224
|
msgstr ""
|
225
225
|
|
226
|
+
#: ../lib/r10k/git/rugged/base_repository.rb:24
|
227
|
+
msgid "Unable to resolve %{pattern}: %{e} "
|
228
|
+
msgstr ""
|
229
|
+
|
230
|
+
#: ../lib/r10k/git/rugged/base_repository.rb:69
|
231
|
+
msgid "Remote URL is different from cache, updating %{orig} to %{update}"
|
232
|
+
msgstr ""
|
233
|
+
|
226
234
|
#: ../lib/r10k/git/rugged/credentials.rb:28
|
227
235
|
msgid "Authentication failed for Git remote %{url}."
|
228
236
|
msgstr ""
|
@@ -367,7 +375,7 @@ msgstr ""
|
|
367
375
|
msgid "%{repo_path} is already at Git ref %{ref}"
|
368
376
|
msgstr ""
|
369
377
|
|
370
|
-
#: ../lib/r10k/initializers.rb:
|
378
|
+
#: ../lib/r10k/initializers.rb:31
|
371
379
|
msgid "the purgedirs key in r10k.yaml is deprecated. it is currently ignored."
|
372
380
|
msgstr ""
|
373
381
|
|
@@ -379,7 +387,7 @@ msgstr ""
|
|
379
387
|
msgid "No class registered for %{key}"
|
380
388
|
msgstr ""
|
381
389
|
|
382
|
-
#: ../lib/r10k/logging.rb:
|
390
|
+
#: ../lib/r10k/logging.rb:73 ../lib/r10k/logging.rb:100 ../lib/r10k/logging.rb:109
|
383
391
|
msgid "Invalid log level '%{val}'. Valid levels are %{log_levels}"
|
384
392
|
msgstr ""
|
385
393
|
|
@@ -439,39 +447,43 @@ msgstr ""
|
|
439
447
|
msgid "Could not read metadata.json"
|
440
448
|
msgstr ""
|
441
449
|
|
442
|
-
#: ../lib/r10k/module_loader/puppetfile.rb:
|
450
|
+
#: ../lib/r10k/module_loader/puppetfile.rb:64
|
443
451
|
msgid "Using Puppetfile '%{puppetfile}'"
|
444
452
|
msgstr ""
|
445
453
|
|
446
|
-
#: ../lib/r10k/module_loader/puppetfile.rb:
|
454
|
+
#: ../lib/r10k/module_loader/puppetfile.rb:65
|
447
455
|
msgid "Using moduledir '%{moduledir}'"
|
448
456
|
msgstr ""
|
449
457
|
|
450
|
-
#: ../lib/r10k/module_loader/puppetfile.rb:
|
458
|
+
#: ../lib/r10k/module_loader/puppetfile.rb:86
|
451
459
|
msgid "Failed to evaluate %{path}"
|
452
460
|
msgstr ""
|
453
461
|
|
454
|
-
#: ../lib/r10k/module_loader/puppetfile.rb:
|
462
|
+
#: ../lib/r10k/module_loader/puppetfile.rb:103
|
455
463
|
msgid "Unable to preload Puppetfile because of %{msg}"
|
456
464
|
msgstr ""
|
457
465
|
|
458
|
-
#: ../lib/r10k/module_loader/puppetfile.rb:
|
466
|
+
#: ../lib/r10k/module_loader/puppetfile.rb:121
|
459
467
|
msgid "Using Forge from Puppetfile: %{forge}"
|
460
468
|
msgstr ""
|
461
469
|
|
462
|
-
#: ../lib/r10k/module_loader/puppetfile.rb:
|
470
|
+
#: ../lib/r10k/module_loader/puppetfile.rb:124
|
463
471
|
msgid "Ignoring Forge declaration in Puppetfile, using value from settings: %{forge}."
|
464
472
|
msgstr ""
|
465
473
|
|
466
|
-
#: ../lib/r10k/module_loader/puppetfile.rb:
|
474
|
+
#: ../lib/r10k/module_loader/puppetfile.rb:173
|
475
|
+
msgid "\"basedir\" is deprecated. Please use \"environment_name\" instead. \"basedir\" will be removed in a future version."
|
476
|
+
msgstr ""
|
477
|
+
|
478
|
+
#: ../lib/r10k/module_loader/puppetfile.rb:192 ../lib/r10k/puppetfile.rb:104
|
467
479
|
msgid "Puppetfile %{path} missing or unreadable"
|
468
480
|
msgstr ""
|
469
481
|
|
470
|
-
#: ../lib/r10k/module_loader/puppetfile.rb:
|
482
|
+
#: ../lib/r10k/module_loader/puppetfile.rb:228
|
471
483
|
msgid "Puppetfiles cannot contain duplicate module names."
|
472
484
|
msgstr ""
|
473
485
|
|
474
|
-
#: ../lib/r10k/module_loader/puppetfile.rb:
|
486
|
+
#: ../lib/r10k/module_loader/puppetfile.rb:230
|
475
487
|
msgid "Remove the duplicates of the following modules: %{dupes}"
|
476
488
|
msgstr ""
|
477
489
|
|
@@ -602,6 +614,10 @@ msgstr ""
|
|
602
614
|
msgid "Both username and password must be specified"
|
603
615
|
msgstr ""
|
604
616
|
|
617
|
+
#: ../lib/r10k/tarball.rb:167
|
618
|
+
msgid "Cache not present at %{path}"
|
619
|
+
msgstr ""
|
620
|
+
|
605
621
|
#: ../lib/r10k/util/basedir.rb:34
|
606
622
|
msgid "Expected Array<#desired_contents>, got R10K::Deployment"
|
607
623
|
msgstr ""
|
data/r10k.gemspec
CHANGED
@@ -32,18 +32,18 @@ Gem::Specification.new do |s|
|
|
32
32
|
|
33
33
|
s.add_dependency 'gettext-setup', '~>0.24'
|
34
34
|
# These two pins narrow what is allowed by gettext-setup,
|
35
|
-
# to
|
35
|
+
# to preserve compatability with Ruby 2.4
|
36
36
|
s.add_dependency 'fast_gettext', '~> 1.1.0'
|
37
37
|
s.add_dependency 'gettext', ['>= 3.0.2', '< 3.3.0']
|
38
38
|
|
39
39
|
s.add_dependency 'jwt', '~> 2.2.3'
|
40
|
+
s.add_dependency 'minitar', '~> 0.9.0'
|
40
41
|
|
41
42
|
s.add_development_dependency 'rspec', '~> 3.1'
|
42
43
|
|
43
44
|
s.add_development_dependency 'rake'
|
44
45
|
|
45
46
|
s.add_development_dependency 'yard', '~> 0.9.11'
|
46
|
-
s.add_development_dependency 'minitar', '~> 0.9.0'
|
47
47
|
|
48
48
|
s.files = %x[git ls-files].split($/)
|
49
49
|
s.require_path = 'lib'
|
Binary file
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'r10k/git/rugged/cache'
|
3
|
+
|
4
|
+
describe R10K::Git::Rugged::Cache, :if => R10K::Features.available?(:rugged) do
|
5
|
+
include_context 'Git integration'
|
6
|
+
|
7
|
+
let(:dirname) { 'working-repo' }
|
8
|
+
let(:remote_name) { 'origin' }
|
9
|
+
|
10
|
+
subject { described_class.new(remote) }
|
11
|
+
|
12
|
+
context "syncing with the remote" do
|
13
|
+
before(:each) do
|
14
|
+
subject.reset!
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "with the correct configuration" do
|
18
|
+
it "is able to sync with the remote" do
|
19
|
+
subject.sync
|
20
|
+
expect(subject.synced?).to eq(true)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "with a out of date cached remote" do
|
25
|
+
it "updates the cached remote configuration" do
|
26
|
+
subject.repo.update_remote('foo', remote_name)
|
27
|
+
expect(subject.repo.remotes[remote_name]).to eq('foo')
|
28
|
+
subject.sync
|
29
|
+
expect(subject.repo.remotes[remote_name]).to eq(remote)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
shared_context "Tarball" do
|
5
|
+
# Suggested subject:
|
6
|
+
#
|
7
|
+
# subject { described_class.new('fixture-tarball', fixture_tarball, checksum: fixture_checksum) }
|
8
|
+
#
|
9
|
+
let(:fixture_tarball) do
|
10
|
+
File.expand_path('spec/fixtures/tarball/tarball.tar.gz', PROJECT_ROOT)
|
11
|
+
end
|
12
|
+
|
13
|
+
let(:fixture_checksum) { '292e692ad18faabd4f9b21037d51f0185e04b69f82c522a54af91fb5b88c2d3b' }
|
14
|
+
|
15
|
+
# Use tmpdir for cached tarballs
|
16
|
+
let(:tmpdir) { Dir.mktmpdir }
|
17
|
+
|
18
|
+
# `moduledir` and `cache_root` are available for examples to use in creating
|
19
|
+
# their subjects
|
20
|
+
let(:moduledir) { File.join(tmpdir, 'modules').tap { |path| Dir.mkdir(path) } }
|
21
|
+
let(:cache_root) { File.join(tmpdir, 'cache').tap { |path| Dir.mkdir(path) } }
|
22
|
+
|
23
|
+
around(:each) do |example|
|
24
|
+
if subject.is_a?(R10K::Tarball)
|
25
|
+
subject.settings[:cache_root] = cache_root
|
26
|
+
elsif subject.respond_to?(:tarball) && subject.tarball.is_a?(R10K::Tarball)
|
27
|
+
subject.tarball.settings[:cache_root] = cache_root
|
28
|
+
end
|
29
|
+
example.run
|
30
|
+
FileUtils.remove_entry_secure(tmpdir)
|
31
|
+
end
|
32
|
+
end
|
data/spec/spec_helper.rb
CHANGED
@@ -19,6 +19,7 @@ require 'r10k'
|
|
19
19
|
Dir.glob(File.expand_path('spec/shared-examples/**/*.rb', PROJECT_ROOT)).each { |file| require file }
|
20
20
|
|
21
21
|
require 'shared-contexts/git-fixtures'
|
22
|
+
require 'shared-contexts/tarball'
|
22
23
|
require 'matchers/exit_with'
|
23
24
|
require 'matchers/match_realpath'
|
24
25
|
require 'r10k-mocks'
|
@@ -241,7 +241,7 @@ describe R10K::Action::Deploy::Module do
|
|
241
241
|
|
242
242
|
allow(R10K::Git::StatefulRepository).to receive(:new).and_return(repo)
|
243
243
|
allow(R10K::Git).to receive_message_chain(:cache, :generate).and_return(cache)
|
244
|
-
allow_any_instance_of(R10K::Source::Git).to receive(:
|
244
|
+
allow_any_instance_of(R10K::Source::Git).to receive(:environment_names).and_return([R10K::Environment::Name.new('first', {})])
|
245
245
|
|
246
246
|
expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
|
247
247
|
# For this test we want to have realistic Modules and access to
|
@@ -300,7 +300,7 @@ describe R10K::Action::Deploy::Module do
|
|
300
300
|
|
301
301
|
allow(R10K::Git::StatefulRepository).to receive(:new).and_return(repo)
|
302
302
|
allow(R10K::Git).to receive_message_chain(:cache, :generate).and_return(cache)
|
303
|
-
allow_any_instance_of(R10K::Source::Git).to receive(:
|
303
|
+
allow_any_instance_of(R10K::Source::Git).to receive(:environment_names).and_return([R10K::Environment::Name.new('first', {}),
|
304
304
|
R10K::Environment::Name.new('second', {})])
|
305
305
|
|
306
306
|
expect(subject).to receive(:visit_environment).and_wrap_original do |original, environment, &block|
|