r10k 3.9.3 → 3.10.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/rspec_tests.yml +1 -1
- data/CHANGELOG.mkd +9 -0
- data/doc/dynamic-environments/configuration.mkd +7 -0
- data/integration/Rakefile +1 -1
- data/integration/tests/user_scenario/basic_workflow/negative/neg_specify_deleted_forge_module.rb +3 -9
- data/integration/tests/user_scenario/basic_workflow/single_env_purge_unmanaged_modules.rb +8 -14
- data/lib/r10k/action/deploy/environment.rb +3 -0
- data/lib/r10k/action/runner.rb +11 -6
- data/lib/r10k/git/cache.rb +1 -1
- data/lib/r10k/initializers.rb +7 -0
- data/lib/r10k/module/forge.rb +5 -1
- data/lib/r10k/module_loader/puppetfile.rb +195 -0
- data/lib/r10k/module_loader/puppetfile/dsl.rb +37 -0
- data/lib/r10k/puppetfile.rb +77 -153
- data/lib/r10k/settings.rb +3 -0
- data/lib/r10k/source/base.rb +10 -0
- data/lib/r10k/source/git.rb +5 -0
- data/lib/r10k/source/svn.rb +4 -0
- data/lib/r10k/util/purgeable.rb +70 -8
- data/lib/r10k/version.rb +1 -1
- data/locales/r10k.pot +37 -33
- data/spec/fixtures/unit/action/r10k_forge_auth.yaml +4 -0
- data/spec/fixtures/unit/action/r10k_forge_auth_no_url.yaml +3 -0
- data/spec/fixtures/unit/util/purgeable/managed_one/managed_subdir_1/managed_subdir_2/ignored_1 +0 -0
- data/spec/fixtures/unit/util/purgeable/managed_two/.hidden/unmanaged_3 +0 -0
- data/spec/unit/action/deploy/environment_spec.rb +9 -0
- data/spec/unit/action/deploy/module_spec.rb +38 -14
- data/spec/unit/action/runner_spec.rb +49 -25
- data/spec/unit/git/cache_spec.rb +14 -0
- data/spec/unit/module/forge_spec.rb +8 -1
- data/spec/unit/module_loader/puppetfile_spec.rb +330 -0
- data/spec/unit/puppetfile_spec.rb +99 -193
- data/spec/unit/settings_spec.rb +6 -2
- data/spec/unit/util/purgeable_spec.rb +38 -6
- metadata +10 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db8e1373846da121e13c6bdd3f74c7eadac79d356d65628157d1f0b6c0939f23
|
4
|
+
data.tar.gz: 7fd4694a5e33f692213339db0422fa7db58d38f84d63f2586593665f8acae8cc
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 272021e80cc4ce7ba4d11f3316bd972d7498e102a1f4d4aa9c0bcf83eeef60bd283c9fb4db74ad37e854b2ebc60f6ba28d3c251ae51cb54fb2ae03a4842d4bb8
|
7
|
+
data.tar.gz: 3689ec04b7dd2a4597199fd2fddba3e06a903b682760aacd565f96e42a604c42a6ef340f598c37ee4e1c1cfc4f4912c1132880de98bb734d86aac39475a45342
|
@@ -15,7 +15,7 @@ jobs:
|
|
15
15
|
- {os: ubuntu-18.04, ruby: 2.5}
|
16
16
|
- {os: ubuntu-18.04, ruby: 2.6}
|
17
17
|
- {os: ubuntu-18.04, ruby: 2.7}
|
18
|
-
- {os: ubuntu-18.04, ruby: jruby-9.2.
|
18
|
+
- {os: ubuntu-18.04, ruby: jruby-9.2.10.0}
|
19
19
|
- {os: windows-2016, ruby: 2.5}
|
20
20
|
- {os: windows-2016, ruby: 2.6}
|
21
21
|
- {os: windows-2016, ruby: 2.7}
|
data/CHANGELOG.mkd
CHANGED
@@ -4,6 +4,15 @@ CHANGELOG
|
|
4
4
|
Unreleased
|
5
5
|
----------
|
6
6
|
|
7
|
+
3.10.0
|
8
|
+
------
|
9
|
+
|
10
|
+
- Add `authorization_token` setting to allow authentication to a custom Forge server. [#1181](https://github.com/puppetlabs/r10k/pull/1181)
|
11
|
+
- (RK-135) Attempting to download the latest version for a module that has no Forge releases will now issue a meaningful error. [#1177](https://github.com/puppetlabs/r10k/pull/1177)
|
12
|
+
- Added an interface to R10K::Source::Base named `reload!` for updating the environments list for a given deployment; `reload!` is called before deployment purges to make r10k deploy pools more threadsafe. [#1172](https://github.com/puppetlabs/r10k/pull/1172)
|
13
|
+
- Remove username and password from remote url in cache directory name [#1186](https://github.com/puppetlabs/r10k/pull/1186)
|
14
|
+
- Purging efficiency is greatly improved. R10K will no longer recurse into directories that match recursive purge exclusions. This should significantly improve the deploy times for those users who enable the "environment" purge level. [#1178](https://github.com/puppetlabs/r10k/pull/1178)
|
15
|
+
|
7
16
|
3.9.3
|
8
17
|
-----
|
9
18
|
|
@@ -165,9 +165,16 @@ interactions. See the global proxy setting documentation for more information an
|
|
165
165
|
The 'baseurl' setting indicates where Forge modules should be installed from.
|
166
166
|
This defaults to 'https://forgeapi.puppetlabs.com'
|
167
167
|
|
168
|
+
#### authorization_token
|
169
|
+
|
170
|
+
The 'authorization_token' setting allows you to provide a token for authenticating to a
|
171
|
+
custom Forge server. When set, 'baseurl' must also be set.
|
172
|
+
You will need to prepend your token with 'Bearer ' if using Artifactory as your Forge server.
|
173
|
+
|
168
174
|
```yaml
|
169
175
|
forge:
|
170
176
|
baseurl: 'https://private-forge.mysite'
|
177
|
+
authorization_token: 'Bearer mysupersecretauthtoken'
|
171
178
|
```
|
172
179
|
|
173
180
|
Deployment options
|
data/integration/Rakefile
CHANGED
@@ -65,7 +65,7 @@ rototiller_task :beaker_hostgenerator do |t|
|
|
65
65
|
end
|
66
66
|
|
67
67
|
# This is a hack :(
|
68
|
-
t.add_flag(:name => '', :default => '
|
68
|
+
t.add_flag(:name => '', :default => 'centos7-64mdca-64.fa', :override_env => 'TEST_TARGET')
|
69
69
|
|
70
70
|
t.add_flag(:name => '--global-config', :default => '{forge_host=forge-aio01-petest.puppetlabs.com}', :override_env => 'BHG_GLOBAL_CONFIG')
|
71
71
|
end
|
data/integration/tests/user_scenario/basic_workflow/negative/neg_specify_deleted_forge_module.rb
CHANGED
@@ -10,7 +10,7 @@ last_commit = git_last_commit(master, git_environments_path)
|
|
10
10
|
r10k_fqp = get_r10k_fqp(master)
|
11
11
|
|
12
12
|
#Verification
|
13
|
-
error_notification_regex = /
|
13
|
+
error_notification_regex = /The module puppetlabs-regret does not appear to have any published releases/
|
14
14
|
|
15
15
|
#File
|
16
16
|
puppet_file = <<-PUPPETFILE
|
@@ -40,12 +40,6 @@ git_add_commit_push(master, 'production', 'Add module.', git_environments_path)
|
|
40
40
|
|
41
41
|
#Tests
|
42
42
|
step "Deploy production environment via r10k with specified module deleted"
|
43
|
-
on(master, "#{r10k_fqp} deploy environment -p -v", :acceptable_exit_codes => 1) do |result|
|
44
|
-
|
45
|
-
assert_match(error_notification_regex, result.stderr, 'Unexpected error was detected!')
|
46
|
-
else
|
47
|
-
expect_failure('expected to fail due to RK-135') do
|
48
|
-
assert_match(error_notification_regex, result.stderr, 'Unexpected error was detected!')
|
49
|
-
end
|
50
|
-
end
|
43
|
+
on(master, "#{r10k_fqp} deploy environment -p -v --trace", :acceptable_exit_codes => 1) do |result|
|
44
|
+
assert_match(error_notification_regex, result.stderr, 'Unexpected error was detected!')
|
51
45
|
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'git_utils'
|
2
2
|
require 'r10k_utils'
|
3
3
|
require 'master_manipulator'
|
4
|
-
test_name 'CODEMGMT-
|
4
|
+
test_name 'CODEMGMT-78 - Puppetfile Purge --puppetfile & --moduledir flag usage'
|
5
5
|
|
6
6
|
#Init
|
7
7
|
master_certname = on(master, puppet('config', 'print', 'certname')).stdout.rstrip
|
8
|
+
moduledir = on(master, puppet('config', 'print', 'environmentpath')).stdout.strip + '/production/modules'
|
8
9
|
git_environments_path = '/root/environments'
|
9
10
|
last_commit = git_last_commit(master, git_environments_path)
|
10
11
|
r10k_fqp = get_r10k_fqp(master)
|
@@ -14,8 +15,6 @@ motd_path = '/etc/motd'
|
|
14
15
|
motd_contents = 'Hello!'
|
15
16
|
motd_contents_regex = /\A#{motd_contents}\z/
|
16
17
|
|
17
|
-
error_message_regex = /Blah/
|
18
|
-
|
19
18
|
#File
|
20
19
|
puppet_file = <<-PUPPETFILE
|
21
20
|
mod "puppetlabs/xinetd"
|
@@ -48,9 +47,6 @@ stub_forge_on(master)
|
|
48
47
|
step 'Checkout "production" Branch'
|
49
48
|
git_on(master, 'checkout production', git_environments_path)
|
50
49
|
|
51
|
-
step 'Manually Install the "motd" Module from the Forge'
|
52
|
-
on(master, puppet('module install puppetlabs-motd'))
|
53
|
-
|
54
50
|
step 'Create "Puppetfile" for the "production" Environment'
|
55
51
|
create_remote_file(master, puppet_file_path, puppet_file)
|
56
52
|
|
@@ -60,13 +56,13 @@ inject_site_pp(master, site_pp_path, site_pp)
|
|
60
56
|
step 'Push Changes'
|
61
57
|
git_add_commit_push(master, 'production', 'Update site.pp and add module.', git_environments_path)
|
62
58
|
|
63
|
-
#Tests
|
64
59
|
step 'Deploy Environments via r10k'
|
65
60
|
on(master, "#{r10k_fqp} deploy environment -v -p")
|
66
61
|
|
67
|
-
step '
|
68
|
-
on(
|
62
|
+
step 'Manually Install the "motd" Module from the Forge'
|
63
|
+
on(master, puppet("module install puppetlabs-motd --modulepath #{moduledir}"))
|
69
64
|
|
65
|
+
#Tests
|
70
66
|
agents.each do |agent|
|
71
67
|
step 'Run Puppet Agent Against "production" Environment'
|
72
68
|
on(agent, puppet('agent', '--test', '--environment production'), :acceptable_exit_codes => 2) do |result|
|
@@ -80,14 +76,12 @@ agents.each do |agent|
|
|
80
76
|
end
|
81
77
|
|
82
78
|
step 'Use r10k to Purge Unmanaged Modules'
|
83
|
-
on(master, "#{r10k_fqp} puppetfile purge -v
|
79
|
+
on(master, "#{r10k_fqp} puppetfile purge -v --puppetfile #{puppet_file_path} --moduledir #{moduledir}")
|
84
80
|
|
85
81
|
#Agent will fail because r10k will purge the "motd" module
|
86
82
|
agents.each do |agent|
|
87
83
|
step 'Attempt to Run Puppet Agent'
|
88
|
-
on(agent, puppet('agent', '--test', '--environment production'), :acceptable_exit_codes =>
|
89
|
-
|
90
|
-
assert_match(error_message_regex, result.stderr, 'Expected error was not detected!')
|
91
|
-
end
|
84
|
+
on(agent, puppet('agent', '--test', '--environment production'), :acceptable_exit_codes => 1) do |result|
|
85
|
+
assert_match(/Could not find declared class motd/, result.stderr, 'Module was not purged')
|
92
86
|
end
|
93
87
|
end
|
@@ -116,6 +116,9 @@ module R10K
|
|
116
116
|
|
117
117
|
if @settings.dig(:overrides, :purging, :purge_levels).include?(:deployment)
|
118
118
|
logger.debug("Purging unmanaged environments for deployment...")
|
119
|
+
deployment.sources.each do |source|
|
120
|
+
source.reload!
|
121
|
+
end
|
119
122
|
deployment.purge!
|
120
123
|
end
|
121
124
|
ensure
|
data/lib/r10k/action/runner.rb
CHANGED
@@ -67,15 +67,20 @@ module R10K
|
|
67
67
|
exit(8)
|
68
68
|
end
|
69
69
|
|
70
|
+
# Set up authorization from license file if it wasn't
|
71
|
+
# already set via the config
|
70
72
|
def setup_authorization
|
71
|
-
|
72
|
-
|
73
|
+
if PuppetForge::Connection.authorization.nil?
|
74
|
+
begin
|
75
|
+
license = R10K::Util::License.load
|
73
76
|
|
74
|
-
|
75
|
-
|
77
|
+
if license.respond_to?(:authorization_token)
|
78
|
+
logger.debug "Using token from license to connect to the Forge."
|
79
|
+
PuppetForge::Connection.authorization = license.authorization_token
|
80
|
+
end
|
81
|
+
rescue R10K::Error => e
|
82
|
+
logger.warn e.message
|
76
83
|
end
|
77
|
-
rescue R10K::Error => e
|
78
|
-
logger.warn e.message
|
79
84
|
end
|
80
85
|
end
|
81
86
|
|
data/lib/r10k/git/cache.rb
CHANGED
@@ -111,6 +111,6 @@ class R10K::Git::Cache
|
|
111
111
|
|
112
112
|
# Reformat the remote name into something that can be used as a directory
|
113
113
|
def sanitized_dirname
|
114
|
-
@sanitized_dirname ||= @remote.gsub(/[^@\w\.-]/, '-')
|
114
|
+
@sanitized_dirname ||= @remote.gsub(/(\w+:\/\/)(.*)(@)/, '\1').gsub(/[^@\w\.-]/, '-')
|
115
115
|
end
|
116
116
|
end
|
data/lib/r10k/initializers.rb
CHANGED
@@ -63,6 +63,13 @@ module R10K
|
|
63
63
|
def call
|
64
64
|
with_setting(:baseurl) { |value| PuppetForge.host = value }
|
65
65
|
with_setting(:proxy) { |value| PuppetForge::Connection.proxy = value }
|
66
|
+
with_setting(:authorization_token) { |value|
|
67
|
+
if @settings[:baseurl]
|
68
|
+
PuppetForge::Connection.authorization = value
|
69
|
+
else
|
70
|
+
raise R10K::Error, "Cannot specify a Forge authorization token without configuring a custom baseurl."
|
71
|
+
end
|
72
|
+
}
|
66
73
|
end
|
67
74
|
end
|
68
75
|
end
|
data/lib/r10k/module/forge.rb
CHANGED
@@ -83,7 +83,11 @@ class R10K::Module::Forge < R10K::Module::Base
|
|
83
83
|
def expected_version
|
84
84
|
if @expected_version == :latest
|
85
85
|
begin
|
86
|
-
|
86
|
+
if @v3_module.current_release
|
87
|
+
@expected_version = @v3_module.current_release.version
|
88
|
+
else
|
89
|
+
raise PuppetForge::ReleaseNotFound, _("The module %{title} does not appear to have any published releases, cannot determine latest version.") % { title: @title }
|
90
|
+
end
|
87
91
|
rescue Faraday::ResourceNotFound => e
|
88
92
|
raise PuppetForge::ReleaseNotFound, _("The module %{title} does not exist on %{url}.") % {title: @title, url: PuppetForge::V3::Release.conn.url_prefix}, e.backtrace
|
89
93
|
end
|
@@ -0,0 +1,195 @@
|
|
1
|
+
module R10K
|
2
|
+
module ModuleLoader
|
3
|
+
class Puppetfile
|
4
|
+
|
5
|
+
DEFAULT_MODULEDIR = 'modules'
|
6
|
+
DEFAULT_PUPPETFILE_NAME = 'Puppetfile'
|
7
|
+
DEFAULT_FORGE_API = 'forgeapi.puppetlabs.com'
|
8
|
+
|
9
|
+
attr_accessor :default_branch_override, :environment
|
10
|
+
attr_reader :modules, :moduledir,
|
11
|
+
:managed_directories, :desired_contents, :purge_exclusions
|
12
|
+
|
13
|
+
# @param basedir [String] The path that contains the moduledir &
|
14
|
+
# Puppetfile by default. May be an environment, project, or
|
15
|
+
# simple directory.
|
16
|
+
# @param puppetfile [String] The path to the Puppetfile, either an
|
17
|
+
# absolute full path or a relative path with regards to the basedir.
|
18
|
+
# @param moduledir [String] The path to the moduledir, either an
|
19
|
+
# absolute full path or a relative path with regards to the basedir.
|
20
|
+
# @param forge [String] The url (without protocol) to the Forge
|
21
|
+
# @param overrides [Hash] Configuration for loaded modules' behavior
|
22
|
+
# @param environment [R10K::Environment] When provided, the environment
|
23
|
+
# in which loading takes place
|
24
|
+
def initialize(basedir:,
|
25
|
+
moduledir: DEFAULT_MODULEDIR,
|
26
|
+
puppetfile: DEFAULT_PUPPETFILE_NAME,
|
27
|
+
forge: DEFAULT_FORGE_API,
|
28
|
+
overrides: {},
|
29
|
+
environment: nil)
|
30
|
+
|
31
|
+
@basedir = cleanpath(basedir)
|
32
|
+
@moduledir = resolve_path(@basedir, moduledir)
|
33
|
+
@puppetfile = resolve_path(@basedir, puppetfile)
|
34
|
+
@forge = forge
|
35
|
+
@overrides = overrides
|
36
|
+
@environment = environment
|
37
|
+
@default_branch_override = @overrides.dig(:environments, :default_branch_override)
|
38
|
+
|
39
|
+
@modules = []
|
40
|
+
|
41
|
+
@managed_directories = []
|
42
|
+
@desired_contents = []
|
43
|
+
@purge_exclusions = []
|
44
|
+
end
|
45
|
+
|
46
|
+
def load
|
47
|
+
dsl = R10K::ModuleLoader::Puppetfile::DSL.new(self)
|
48
|
+
dsl.instance_eval(puppetfile_content(@puppetfile), @puppetfile)
|
49
|
+
|
50
|
+
validate_no_duplicate_names(@modules)
|
51
|
+
@modules
|
52
|
+
|
53
|
+
managed_content = @modules.group_by(&:dirname)
|
54
|
+
|
55
|
+
@managed_directories = determine_managed_directories(managed_content)
|
56
|
+
@desired_contents = determine_desired_contents(managed_content)
|
57
|
+
@purge_exclusions = determine_purge_exclusions(@managed_directories)
|
58
|
+
|
59
|
+
{
|
60
|
+
modules: @modules,
|
61
|
+
managed_directories: @managed_directories,
|
62
|
+
desired_contents: @desired_contents,
|
63
|
+
purge_exclusions: @purge_exclusions
|
64
|
+
}
|
65
|
+
|
66
|
+
rescue SyntaxError, LoadError, ArgumentError, NameError => e
|
67
|
+
raise R10K::Error.wrap(e, _("Failed to evaluate %{path}") % {path: @puppetfile})
|
68
|
+
end
|
69
|
+
|
70
|
+
|
71
|
+
##
|
72
|
+
## set_forge, set_moduledir, and add_module are used directly by the DSL class
|
73
|
+
##
|
74
|
+
|
75
|
+
# @param [String] forge
|
76
|
+
def set_forge(forge)
|
77
|
+
@forge = forge
|
78
|
+
end
|
79
|
+
|
80
|
+
# @param [String] moduledir
|
81
|
+
def set_moduledir(moduledir)
|
82
|
+
@moduledir = resolve_path(@basedir, moduledir)
|
83
|
+
end
|
84
|
+
|
85
|
+
# @param [String] name
|
86
|
+
# @param [Hash, String, Symbol, nil] module_info Calling with
|
87
|
+
# anything but a Hash is deprecated. The DSL will now convert
|
88
|
+
# String and Symbol versions to Hashes of the shape
|
89
|
+
# { version: <String or Symbol> }
|
90
|
+
#
|
91
|
+
# String inputs should be valid module versions, the Symbol
|
92
|
+
# `:latest` is allowed, as well as `nil`.
|
93
|
+
#
|
94
|
+
# Non-Hash inputs are only ever used by Forge modules. In
|
95
|
+
# future versions this method will require the caller (the
|
96
|
+
# DSL class, not the Puppetfile author) to do this conversion
|
97
|
+
# itself.
|
98
|
+
#
|
99
|
+
def add_module(name, module_info)
|
100
|
+
if !module_info.is_a?(Hash)
|
101
|
+
module_info = { version: module_info }
|
102
|
+
end
|
103
|
+
|
104
|
+
module_info[:overrides] = @overrides
|
105
|
+
|
106
|
+
if install_path = module_info.delete(:install_path)
|
107
|
+
install_path = resolve_path(@basedir, install_path)
|
108
|
+
validate_install_path(install_path, name)
|
109
|
+
else
|
110
|
+
install_path = @moduledir
|
111
|
+
end
|
112
|
+
|
113
|
+
if @default_branch_override
|
114
|
+
module_info[:default_branch_override] = @default_branch_override
|
115
|
+
end
|
116
|
+
|
117
|
+
mod = R10K::Module.new(name, install_path, module_info, @environment)
|
118
|
+
mod.origin = :puppetfile
|
119
|
+
|
120
|
+
# Do not save modules if they would conflict with the attached
|
121
|
+
# environment
|
122
|
+
if @environment && @environment.module_conflicts?(mod)
|
123
|
+
return @modules
|
124
|
+
end
|
125
|
+
|
126
|
+
@modules << mod
|
127
|
+
end
|
128
|
+
|
129
|
+
private
|
130
|
+
|
131
|
+
# @param [Array<R10K::Module>] modules
|
132
|
+
def validate_no_duplicate_names(modules)
|
133
|
+
dupes = modules
|
134
|
+
.group_by { |mod| mod.name }
|
135
|
+
.select { |_, mods| mods.size > 1 }
|
136
|
+
.map(&:first)
|
137
|
+
unless dupes.empty?
|
138
|
+
msg = _('Puppetfiles cannot contain duplicate module names.')
|
139
|
+
msg += ' '
|
140
|
+
msg += _("Remove the duplicates of the following modules: %{dupes}" % { dupes: dupes.join(' ') })
|
141
|
+
raise R10K::Error.new(msg)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def resolve_path(base, path)
|
146
|
+
if Pathname.new(path).absolute?
|
147
|
+
cleanpath(path)
|
148
|
+
else
|
149
|
+
cleanpath(File.join(base, path))
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def validate_install_path(path, modname)
|
154
|
+
unless /^#{Regexp.escape(@basedir)}.*/ =~ path
|
155
|
+
raise R10K::Error.new("Puppetfile cannot manage content '#{modname}' outside of containing environment: #{path} is not within #{@basedir}")
|
156
|
+
end
|
157
|
+
|
158
|
+
true
|
159
|
+
end
|
160
|
+
|
161
|
+
def determine_managed_directories(managed_content)
|
162
|
+
managed_content.keys.reject { |dir| dir == @basedir }
|
163
|
+
end
|
164
|
+
|
165
|
+
# Returns an array of the full paths to all the content being managed.
|
166
|
+
# @return [Array<String>]
|
167
|
+
def determine_desired_contents(managed_content)
|
168
|
+
managed_content.flat_map do |install_path, mods|
|
169
|
+
mods.collect { |mod| File.join(install_path, mod.name) }
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
def determine_purge_exclusions(managed_dirs)
|
174
|
+
if environment && environment.respond_to?(:desired_contents)
|
175
|
+
managed_dirs + environment.desired_contents
|
176
|
+
else
|
177
|
+
managed_dirs
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
# .cleanpath is as close to a canonical path as we can do without touching
|
182
|
+
# the filesystem. The .realpath methods will choke if some of the
|
183
|
+
# intermediate paths are missing, even though in some cases we will create
|
184
|
+
# them later as needed.
|
185
|
+
def cleanpath(path)
|
186
|
+
Pathname.new(path).cleanpath.to_s
|
187
|
+
end
|
188
|
+
|
189
|
+
# For testing purposes only
|
190
|
+
def puppetfile_content(path)
|
191
|
+
File.read(path)
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module R10K
|
2
|
+
module ModuleLoader
|
3
|
+
class Puppetfile
|
4
|
+
class DSL
|
5
|
+
# A barebones implementation of the Puppetfile DSL
|
6
|
+
#
|
7
|
+
# @api private
|
8
|
+
|
9
|
+
def initialize(librarian)
|
10
|
+
@librarian = librarian
|
11
|
+
end
|
12
|
+
|
13
|
+
def mod(name, args = nil)
|
14
|
+
if args.is_a?(Hash)
|
15
|
+
opts = args
|
16
|
+
else
|
17
|
+
opts = { version: args }
|
18
|
+
end
|
19
|
+
|
20
|
+
@librarian.add_module(name, opts)
|
21
|
+
end
|
22
|
+
|
23
|
+
def forge(location)
|
24
|
+
@librarian.set_forge(location)
|
25
|
+
end
|
26
|
+
|
27
|
+
def moduledir(location)
|
28
|
+
@librarian.set_moduledir(location)
|
29
|
+
end
|
30
|
+
|
31
|
+
def method_missing(method, *args)
|
32
|
+
raise NoMethodError, _("unrecognized declaration '%{method}'") % {method: method}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|