puppet-armature 0.3.0 → 0.4.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/Gemfile.lock +6 -5
- data/TODO.md +0 -8
- data/bin/armature +21 -6
- data/lib/armature.rb +12 -4
- data/lib/armature/cache.rb +98 -73
- data/lib/armature/environments.rb +53 -20
- data/lib/armature/errors.rb +7 -0
- data/lib/armature/puppetfile.rb +41 -17
- data/lib/armature/ref/base.rb +21 -0
- data/lib/armature/ref/identity.rb +5 -0
- data/lib/armature/ref/immutable.rb +5 -0
- data/lib/armature/ref/mutable.rb +5 -0
- data/lib/armature/repo.rb +56 -0
- data/lib/armature/repo/forge.rb +154 -0
- data/lib/armature/repo/git.rb +228 -0
- data/lib/armature/run.rb +44 -13
- data/lib/armature/util.rb +51 -2
- data/lib/armature/version.rb +2 -1
- data/puppet-armature.gemspec +1 -1
- data/test/deploy_test.rb +39 -39
- data/test/helpers.rb +27 -25
- data/test/puppetfile_test.rb +41 -0
- metadata +12 -4
- data/lib/armature/gitrepo.rb +0 -139
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 39ee81e7821523113eb5b9868a0dca398ef3a6b0
|
4
|
+
data.tar.gz: 31da92d00fb15e345c8fdb28fce24e6e07fb1ec0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a2c928a9daa31005a7d80b757080c6f41cd7b3785703c05bb61b10a51df848675b7907da9b63381d15a48b745ce6dfe3de1c19d50cbb7dbea2f83dfc69a8f141
|
7
|
+
data.tar.gz: d174e15de2dd26fbe228fed75383ffc6377afd166e79388a690e689f6d8f27329ebc4603e40bdd65e111cb91b94a2e295ce9f7b7fecf14d1f707bba29b87bba9
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
puppet-armature (0.
|
4
|
+
puppet-armature (0.4.0)
|
5
5
|
gli (= 2.14.0)
|
6
6
|
logging (~> 2)
|
7
7
|
|
@@ -9,19 +9,20 @@ GEM
|
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
11
|
gli (2.14.0)
|
12
|
-
little-plugger (1.1.
|
13
|
-
logging (2.
|
12
|
+
little-plugger (1.1.4)
|
13
|
+
logging (2.2.2)
|
14
14
|
little-plugger (~> 1.1)
|
15
15
|
multi_json (~> 1.10)
|
16
16
|
minitest (5.10.1)
|
17
|
-
multi_json (1.
|
17
|
+
multi_json (1.13.1)
|
18
18
|
|
19
19
|
PLATFORMS
|
20
20
|
ruby
|
21
|
+
x86_64-darwin-16
|
21
22
|
|
22
23
|
DEPENDENCIES
|
23
24
|
minitest (~> 5.9)
|
24
25
|
puppet-armature!
|
25
26
|
|
26
27
|
BUNDLED WITH
|
27
|
-
1.
|
28
|
+
1.17.1
|
data/TODO.md
CHANGED
@@ -1,13 +1,5 @@
|
|
1
1
|
# Future development
|
2
2
|
|
3
|
-
### Update module branches when updating an environment
|
4
|
-
|
5
|
-
Rather than waiting for a periodic `update-branches` job to run, update module
|
6
|
-
branches when their environment is deployed.
|
7
|
-
|
8
|
-
This will require some caching so that work is not duplicated when updating all
|
9
|
-
environments.
|
10
|
-
|
11
3
|
### Webhook endpoints
|
12
4
|
|
13
5
|
I'm unsure if I want this. Webhooks are definitely useful, but I can get that
|
data/bin/armature
CHANGED
@@ -20,6 +20,9 @@ switch [:v,:verbose]
|
|
20
20
|
desc 'Show DEBUG level output'
|
21
21
|
switch [:d,:debug]
|
22
22
|
|
23
|
+
desc 'Add timestamp for each line in log'
|
24
|
+
switch [:"log-time"]
|
25
|
+
|
23
26
|
if Process.uid == 0
|
24
27
|
environments_default = '/etc/puppetlabs/code/environments'
|
25
28
|
cache_default = '/srv/armature-cache'
|
@@ -47,12 +50,12 @@ command "deploy-ref" do |c|
|
|
47
50
|
# This should fail as early as possible (e.g. if the path isn't correct)
|
48
51
|
environments = Armature::Environments.new(@environments_path, @cache)
|
49
52
|
|
50
|
-
repo = @cache
|
53
|
+
repo = Armature::Repo::Git.from_url(@cache, arguments.shift)
|
51
54
|
ref = arguments.shift
|
52
55
|
name = arguments.shift
|
53
56
|
|
54
57
|
begin
|
55
|
-
environments.
|
58
|
+
environments.check_out_ref(repo, ref, name)
|
56
59
|
rescue
|
57
60
|
@logger.error("Error deploying ref '#{ref}' as '#{name}'")
|
58
61
|
raise
|
@@ -68,11 +71,14 @@ arg 'BRANCH', :multiple=>true
|
|
68
71
|
command "deploy-branches" do |c|
|
69
72
|
c.desc "Delete environments that aren't being deployed"
|
70
73
|
c.switch [:d,"delete-other"]
|
74
|
+
c.desc "Fix environment names instead of skipping them"
|
75
|
+
c.switch [:x,"fix-environment-names"]
|
71
76
|
c.action do |global_options, options, arguments|
|
72
77
|
# This should fail as early as possible (e.g. if the path isn't correct)
|
73
78
|
environments = Armature::Environments.new(@environments_path, @cache)
|
79
|
+
environments.fix_environment_names = options["fix-environment-names"]
|
74
80
|
|
75
|
-
repo = @cache
|
81
|
+
repo = Armature::Repo::Git.from_url(@cache, arguments.shift)
|
76
82
|
all_branches = repo.get_branches()
|
77
83
|
branches = Set.new()
|
78
84
|
|
@@ -96,7 +102,7 @@ command "deploy-branches" do |c|
|
|
96
102
|
|
97
103
|
branches.each do |branch|
|
98
104
|
begin
|
99
|
-
environments.
|
105
|
+
environments.check_out_ref(repo, branch)
|
100
106
|
rescue => e
|
101
107
|
@logger.error("Error deploying branch '#{branch}' (skipping): #{e}")
|
102
108
|
end
|
@@ -111,11 +117,20 @@ end
|
|
111
117
|
|
112
118
|
desc 'Update all branches in the cache'
|
113
119
|
command :update do |c|
|
114
|
-
c.action { @cache.
|
120
|
+
c.action { @cache.update_mutable_refs() }
|
115
121
|
end
|
116
122
|
|
117
123
|
pre do |global_options, command, options, arguments|
|
118
|
-
|
124
|
+
appender = Logging.appenders.stdout
|
125
|
+
|
126
|
+
if global_options[:"log-time"]
|
127
|
+
appender.layout = Logging.layouts.pattern.new(
|
128
|
+
:pattern => "%d %-5l [%c] %m\n",
|
129
|
+
:date_pattern => "%Y-%m-%d %H:%M:%S",
|
130
|
+
)
|
131
|
+
end
|
132
|
+
|
133
|
+
Logging.logger.root.add_appenders(appender)
|
119
134
|
|
120
135
|
Logging.logger.root.level = :info if global_options[:verbose]
|
121
136
|
Logging.logger.root.level = :debug if global_options[:debug]
|
data/lib/armature.rb
CHANGED
@@ -1,10 +1,18 @@
|
|
1
|
+
module Armature
|
2
|
+
end
|
3
|
+
|
4
|
+
require "armature/errors.rb"
|
5
|
+
|
1
6
|
require "armature/cache.rb"
|
2
7
|
require "armature/environments.rb"
|
3
|
-
require "armature/gitrepo.rb"
|
4
8
|
require "armature/puppetfile.rb"
|
9
|
+
require "armature/ref/base.rb"
|
10
|
+
require "armature/ref/identity.rb"
|
11
|
+
require "armature/ref/immutable.rb"
|
12
|
+
require "armature/ref/mutable.rb"
|
13
|
+
require "armature/repo.rb"
|
14
|
+
require "armature/repo/git.rb"
|
15
|
+
require "armature/repo/forge.rb"
|
5
16
|
require "armature/run.rb"
|
6
17
|
require "armature/util.rb"
|
7
18
|
require "armature/version.rb"
|
8
|
-
|
9
|
-
module Armature
|
10
|
-
end
|
data/lib/armature/cache.rb
CHANGED
@@ -19,73 +19,48 @@ module Armature
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
# Get the path to a repo on disk.
|
23
|
+
#
|
24
|
+
# If the repo doesn't exist locally, then it creates the path, locks it,
|
25
|
+
# and runs the passed block to create the repo.
|
26
|
+
def open_repo(type, url)
|
27
|
+
repo_id = _fs_repo_id(type, url)
|
28
|
+
repo_path = "#{@path}/repo/#{repo_id}"
|
29
|
+
|
30
|
+
if Dir.exist? repo_path
|
31
|
+
return repo_path
|
26
32
|
end
|
27
|
-
end
|
28
33
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
repo_path = "#{@path}/repo/#{safe_url}"
|
36
|
-
if ! Dir.exist? repo_path
|
37
|
-
@logger.info("Cloning '#{url}' for the first time")
|
38
|
-
Armature::Util::lock repo_path, File::LOCK_EX, "clone" do
|
39
|
-
if Dir.exist? repo_path
|
40
|
-
@logger.info("Another process cloned '#{url}' while we were blocked")
|
41
|
-
else
|
42
|
-
# Mirror copies *all* refs, not just branches. Ignore output.
|
43
|
-
Armature::Run.command(
|
44
|
-
"git", "clone", "--quiet", "--mirror", url, repo_path)
|
45
|
-
@logger.debug("Done cloning '#{url}'")
|
46
|
-
end
|
34
|
+
@logger.debug("Creating repo for #{type} '#{url}'")
|
35
|
+
Armature::Util::lock(repo_path, File::LOCK_EX, "create") do
|
36
|
+
if Dir.exist? repo_path
|
37
|
+
@logger.debug("Another process created repo for #{type} '#{url}' while we were waiting")
|
38
|
+
return repo_path
|
47
39
|
end
|
48
|
-
end
|
49
40
|
|
50
|
-
|
51
|
-
|
41
|
+
temp_path = new_temp_path()
|
42
|
+
Dir.mkdir(temp_path)
|
52
43
|
|
53
|
-
|
54
|
-
def get_repo_by_name(safe_url)
|
55
|
-
@repos[safe_url] ||= GitRepo.new("#{@path}/repo/#{safe_url}", safe_url)
|
56
|
-
end
|
44
|
+
yield temp_path
|
57
45
|
|
58
|
-
|
59
|
-
def checkout(repo, ref, refresh=false, options={})
|
60
|
-
if refresh
|
61
|
-
# Don't check the cache; refresh it from source.
|
62
|
-
repo.freshen()
|
63
|
-
ref = repo.canonical_ref(ref)
|
64
|
-
else
|
65
|
-
# This will raise a RefError if the ref doesn't exist
|
66
|
-
begin
|
67
|
-
ref = repo.canonical_ref(ref)
|
68
|
-
rescue RefError
|
69
|
-
repo.freshen()
|
70
|
-
ref = repo.canonical_ref(ref)
|
71
|
-
end
|
46
|
+
File.rename(temp_path, repo_path)
|
72
47
|
end
|
73
48
|
|
74
|
-
|
75
|
-
|
76
|
-
repo_path = "#{@path}/ref/#{type}/#{repo.name}"
|
77
|
-
ref_path = "#{repo_path}/#{safe_ref}"
|
49
|
+
return repo_path
|
50
|
+
end
|
78
51
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
end
|
84
|
-
end
|
52
|
+
def open_ref(ref)
|
53
|
+
safe_ref = fs_sanitize(ref.canonical_name)
|
54
|
+
repo_path = "#{@path}/ref/#{ref.type}/#{fs_repo_id(ref.repo)}"
|
55
|
+
ref_path = "#{repo_path}/#{safe_ref}"
|
85
56
|
|
86
57
|
FileUtils.mkdir_p(repo_path)
|
87
58
|
|
88
|
-
|
59
|
+
@logger.debug("Checking for #{ref} in #{ref.repo}")
|
60
|
+
identity_path = open_identity(ref.repo, ref.identity) do |object_path|
|
61
|
+
yield object_path
|
62
|
+
end
|
63
|
+
|
89
64
|
if identity_path != ref_path
|
90
65
|
atomic_symlink(identity_path, ref_path)
|
91
66
|
end
|
@@ -93,6 +68,33 @@ module Armature
|
|
93
68
|
ref_path
|
94
69
|
end
|
95
70
|
|
71
|
+
def register_repo(repo)
|
72
|
+
@repos[fs_repo_id(repo)] = repo
|
73
|
+
end
|
74
|
+
|
75
|
+
# Takes a string like "git:https://github.com/a/b.git" and returns Repo::Git
|
76
|
+
def repo_klass(repo_id)
|
77
|
+
type = repo_id.split(":", 2).first
|
78
|
+
Repo.const_get(type.capitalize())
|
79
|
+
end
|
80
|
+
|
81
|
+
# Get a repo object for an existing local repo by its santized URL
|
82
|
+
def repo_by_id(repo_id)
|
83
|
+
@repos[repo_id] ||= repo_klass(repo_id).from_path(self, "#{@path}/repo/#{repo_id}")
|
84
|
+
end
|
85
|
+
|
86
|
+
def get_repo(type, url)
|
87
|
+
@repos[_fs_repo_id(type, url)]
|
88
|
+
end
|
89
|
+
|
90
|
+
# This is used in the testing code
|
91
|
+
def flush_memory!
|
92
|
+
@logger.debug("Flushing in-memory caches for all repos")
|
93
|
+
@repos.each do |name, repo|
|
94
|
+
repo.flush_memory!
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
96
98
|
# Creates a symlink atomically
|
97
99
|
#
|
98
100
|
# That is, if a symlink or file exists at new_path, then this will replace
|
@@ -102,8 +104,6 @@ module Armature
|
|
102
104
|
def atomic_symlink(target_path, new_path)
|
103
105
|
new_path.chomp!("/")
|
104
106
|
|
105
|
-
@logger.debug("#{new_path} -> #{target_path}")
|
106
|
-
|
107
107
|
begin
|
108
108
|
if File.readlink(new_path) == target_path
|
109
109
|
return
|
@@ -111,6 +111,8 @@ module Armature
|
|
111
111
|
rescue Errno::ENOENT
|
112
112
|
end
|
113
113
|
|
114
|
+
@logger.debug("Updating symlink #{new_path} -> #{target_path}")
|
115
|
+
|
114
116
|
temp_path = new_temp_path()
|
115
117
|
File.symlink(target_path, temp_path)
|
116
118
|
File.rename(temp_path, new_path)
|
@@ -119,15 +121,15 @@ module Armature
|
|
119
121
|
raise
|
120
122
|
end
|
121
123
|
|
122
|
-
def
|
124
|
+
def update_mutable_refs()
|
123
125
|
Dir.glob("#{@path}/ref/mutable/*/*") do |path|
|
124
|
-
|
125
|
-
|
126
|
-
@logger.info("Updating #{ref} ref from #{repo
|
126
|
+
repo = repo_by_id(File.basename(File.dirname(path)))
|
127
|
+
ref = repo.mutable_fs_ref(fs_unsanitize(File.basename(path)))
|
128
|
+
@logger.info("Updating #{ref} ref from #{repo}")
|
127
129
|
|
128
130
|
begin
|
129
|
-
|
130
|
-
rescue RefError
|
131
|
+
ref.check_out()
|
132
|
+
rescue Armature::RefError
|
131
133
|
# The ref no longer exists, so we can't update it. Leave the old
|
132
134
|
# checkout in place for safety; garbage collection will remove it if
|
133
135
|
# it's no longer used.
|
@@ -167,6 +169,18 @@ module Armature
|
|
167
169
|
@lock_file = nil
|
168
170
|
end
|
169
171
|
|
172
|
+
# Open a temp directory, chdir into it, yield, then delete the directory
|
173
|
+
def open_temp
|
174
|
+
path = new_temp_path()
|
175
|
+
|
176
|
+
Dir.mkdir(path)
|
177
|
+
Dir.chdir(path) do
|
178
|
+
yield
|
179
|
+
end
|
180
|
+
|
181
|
+
FileUtils.remove_entry(path)
|
182
|
+
end
|
183
|
+
|
170
184
|
private
|
171
185
|
|
172
186
|
def new_temp_path
|
@@ -183,20 +197,29 @@ module Armature
|
|
183
197
|
"#{@path}/object/#{@process_prefix}.#{@sequence}#{name}"
|
184
198
|
end
|
185
199
|
|
186
|
-
def
|
200
|
+
def fs_repo_id(repo)
|
201
|
+
_fs_repo_id(repo.type, repo.url)
|
202
|
+
end
|
203
|
+
|
204
|
+
def _fs_repo_id(type, url)
|
205
|
+
fs_sanitize("#{type}:#{url}")
|
206
|
+
end
|
207
|
+
|
208
|
+
### FIXME write tests for this
|
209
|
+
def fs_sanitize(str)
|
187
210
|
# Escape | and replace / with |. Also escape a leading .
|
188
|
-
|
211
|
+
str.sub(/\A\./, "\\.").gsub(/[\\|]/, '\\\0').gsub(%r{/}, '|')
|
189
212
|
end
|
190
213
|
|
191
|
-
|
192
|
-
|
214
|
+
### FIXME write tests for this
|
215
|
+
def fs_unsanitize(str)
|
216
|
+
str.gsub(/\\([\\|])/, '\0').gsub(/\|/, '/').sub(/^\A\\\./, '.')
|
193
217
|
end
|
194
218
|
|
195
|
-
|
196
|
-
def checkout_identity(repo, identity)
|
219
|
+
def open_identity(repo, identity)
|
197
220
|
safe_identity = fs_sanitize(identity)
|
198
221
|
|
199
|
-
repo_path = "#{@path}/identity/#{repo
|
222
|
+
repo_path = "#{@path}/ref/identity/#{fs_repo_id(repo)}"
|
200
223
|
identity_path = "#{repo_path}/#{safe_identity}"
|
201
224
|
if Dir.exist? identity_path
|
202
225
|
return identity_path
|
@@ -204,7 +227,7 @@ module Armature
|
|
204
227
|
|
205
228
|
FileUtils.mkdir_p(repo_path)
|
206
229
|
|
207
|
-
Armature::Util::lock
|
230
|
+
Armature::Util::lock(identity_path, File::LOCK_EX, "check out") do
|
208
231
|
# Another process may have created the object before we got the lock
|
209
232
|
if Dir.exist? identity_path
|
210
233
|
return identity_path
|
@@ -214,11 +237,13 @@ module Armature
|
|
214
237
|
FileUtils.mkdir_p object_path
|
215
238
|
|
216
239
|
@logger.debug(
|
217
|
-
"Checking out '#{identity}' from '#{repo
|
218
|
-
|
240
|
+
"Checking out '#{identity}' from '#{repo}' into '#{object_path}'")
|
241
|
+
yield object_path
|
219
242
|
atomic_symlink(object_path, identity_path)
|
220
243
|
end
|
221
244
|
|
245
|
+
@logger.debug("Finished checking out \"#{identity}\" from \"#{repo}\"")
|
246
|
+
|
222
247
|
identity_path
|
223
248
|
end
|
224
249
|
|
@@ -1,11 +1,37 @@
|
|
1
1
|
module Armature
|
2
2
|
class Environments
|
3
|
+
class InvalidNameError < Armature::Error
|
4
|
+
end
|
5
|
+
|
6
|
+
# The documentation claims that uppercase letters are invalid, but in
|
7
|
+
# practice they seem to be fine.
|
8
|
+
#
|
9
|
+
# https://docs.puppet.com/puppet/latest/reference/lang_reserved.html#environments
|
10
|
+
def self.valid_environment_name?(name)
|
11
|
+
name =~ /\A[A-Za-z0-9_]+\Z/
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.assert_valid_environment_name(name)
|
15
|
+
if ! valid_environment_name?(name)
|
16
|
+
raise InvalidNameError, "Invalid environment name '#{name}'"
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# Same rules as for a class
|
21
|
+
def self.assert_valid_module_name(name)
|
22
|
+
if name !~ /\A[a-z][a-z0-9_]*\Z/
|
23
|
+
raise InvalidNameError, "Invalid module name '#{name}'"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
3
27
|
attr_reader :path
|
28
|
+
attr_accessor :fix_environment_names
|
4
29
|
|
5
30
|
# path is the path to the directory containing all the environments
|
6
31
|
def initialize(path, cache)
|
7
32
|
@cache = cache
|
8
33
|
@logger = Logging.logger[self]
|
34
|
+
@fix_environment_names = false
|
9
35
|
|
10
36
|
if not File.directory? path
|
11
37
|
abort "Puppet environments path does not exist: '#{path}'"
|
@@ -25,23 +51,32 @@ module Armature
|
|
25
51
|
@logger.debug "Environment '#{name}' does not exist"
|
26
52
|
end
|
27
53
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
if name !~ /\A[a-z0-9_]+\Z/
|
34
|
-
raise "Invalid environment name '#{name}'"
|
54
|
+
def normalize_environment_name(name)
|
55
|
+
if @fix_environment_names && ! self.class.valid_environment_name?(name)
|
56
|
+
old = name
|
57
|
+
name = old.gsub(/[^A-Za-z0-9_]/, "_")
|
58
|
+
@logger.info("Changing invalid environment name \"#{old}\" to \"#{name}\"")
|
35
59
|
end
|
36
60
|
|
61
|
+
self.class.assert_valid_environment_name(name)
|
62
|
+
name
|
63
|
+
end
|
64
|
+
|
65
|
+
# Create an environment from a ref
|
66
|
+
#
|
67
|
+
# This will add and update a modules dir in any repo, even if the repo is
|
68
|
+
# used in a Puppetfile. (Perhaps the cache is used for multiple repos?)
|
69
|
+
def check_out_ref(repo, ref_str, name=ref_str)
|
70
|
+
name = normalize_environment_name(name)
|
71
|
+
|
37
72
|
@cache.lock File::LOCK_SH do
|
38
|
-
@logger.info "Deploying ref '#{
|
73
|
+
@logger.info "Deploying ref '#{ref_str}' from '#{repo}' as" \
|
39
74
|
" environment '#{name}'"
|
40
75
|
|
41
76
|
begin
|
42
|
-
ref_path =
|
43
|
-
rescue RefError
|
44
|
-
@logger.info "Ref '#{
|
77
|
+
ref_path = repo.general_ref(ref_str).check_out()
|
78
|
+
rescue Armature::RefError
|
79
|
+
@logger.info "Ref '#{ref_str}' does not exist; ensuring environment" \
|
45
80
|
" '#{name}' is gone"
|
46
81
|
remove(name)
|
47
82
|
return
|
@@ -50,7 +85,7 @@ module Armature
|
|
50
85
|
puppetfile_path = "#{ref_path}/Puppetfile"
|
51
86
|
if File.exist?(puppetfile_path)
|
52
87
|
@logger.debug "Found Puppetfile in environment '#{name}'"
|
53
|
-
module_refs = Armature::Puppetfile.new().include(puppetfile_path)
|
88
|
+
module_refs = Armature::Puppetfile.new(@cache).include(puppetfile_path)
|
54
89
|
@logger.debug "Loaded Puppetfile in environment '#{name}' with" \
|
55
90
|
" #{module_refs.length} modules"
|
56
91
|
else
|
@@ -60,8 +95,9 @@ module Armature
|
|
60
95
|
|
61
96
|
update_modules(ref_path, module_refs)
|
62
97
|
|
98
|
+
# Make the change live
|
63
99
|
@cache.atomic_symlink(ref_path, "#{@path}/#{name}")
|
64
|
-
@logger.debug "Done deploying ref '#{
|
100
|
+
@logger.debug "Done deploying ref '#{ref_str}' from '#{repo}' as" \
|
65
101
|
" environment '#{name}'"
|
66
102
|
end
|
67
103
|
end
|
@@ -69,6 +105,8 @@ module Armature
|
|
69
105
|
private
|
70
106
|
|
71
107
|
# Apply the results of the Puppetfile to a ref (e.g. an environment)
|
108
|
+
#
|
109
|
+
### FIXME This could update modules in an existing check out.
|
72
110
|
def update_modules(target_path, module_refs)
|
73
111
|
modules_path = "#{target_path}/modules"
|
74
112
|
if ! Dir.exist? modules_path
|
@@ -76,14 +114,9 @@ module Armature
|
|
76
114
|
end
|
77
115
|
|
78
116
|
module_refs.each do |name, info|
|
79
|
-
|
80
|
-
raise "Module name may not start with period: '#{name}'"
|
81
|
-
elsif name =~ /\//
|
82
|
-
raise "Module name may not contain /: '#{name}'"
|
83
|
-
end
|
84
|
-
|
85
|
-
ref_path = @cache.checkout(@cache.get_repo(info[:git]), info[:ref])
|
117
|
+
self.class.assert_valid_module_name(name)
|
86
118
|
|
119
|
+
ref_path = info[:ref].check_out()
|
87
120
|
@cache.atomic_symlink(ref_path, "#{modules_path}/#{name}")
|
88
121
|
end
|
89
122
|
|