r10k 3.13.0 → 3.14.0
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 +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|
|