corl 0.4.0 → 0.4.1
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.
- data/Gemfile +5 -10
- data/Gemfile.lock +13 -11
- data/README.rdoc +1 -1
- data/Rakefile +3 -3
- data/VERSION +1 -1
- data/bin/corl +2 -54
- data/bootstrap/bootstrap.sh +91 -0
- data/bootstrap/lib/shell/LICENSE.txt +674 -0
- data/bootstrap/lib/shell/command.sh +214 -0
- data/bootstrap/lib/shell/filesystem.sh +139 -0
- data/bootstrap/lib/shell/load.sh +73 -0
- data/bootstrap/lib/shell/os.sh +67 -0
- data/bootstrap/lib/shell/script.sh +160 -0
- data/bootstrap/lib/shell/starter.sh +64 -0
- data/bootstrap/lib/shell/validators.sh +50 -0
- data/bootstrap/os/ubuntu/00_base.sh +5 -0
- data/bootstrap/os/ubuntu/01_git.sh +5 -0
- data/bootstrap/os/ubuntu/05_ruby.sh +7 -0
- data/bootstrap/os/ubuntu/06_puppet.sh +38 -0
- data/bootstrap/os/ubuntu/10_corl.sh +9 -0
- data/corl.gemspec +61 -124
- data/lib/{corl → CORL}/action/bootstrap.rb +13 -7
- data/lib/CORL/action/exec.rb +39 -0
- data/lib/CORL/action/image.rb +31 -0
- data/lib/{corl → CORL}/action/images.rb +1 -1
- data/lib/CORL/action/lookup.rb +34 -0
- data/lib/{corl → CORL}/action/machines.rb +1 -1
- data/lib/CORL/action/provision.rb +31 -0
- data/lib/{corl → CORL}/action/seed.rb +3 -3
- data/lib/{corl → CORL}/action/spawn.rb +2 -2
- data/lib/CORL/action/start.rb +31 -0
- data/lib/CORL/action/stop.rb +31 -0
- data/lib/{corl → CORL}/configuration/file.rb +1 -1
- data/lib/{corl → CORL}/event/puppet.rb +1 -1
- data/lib/{corl → CORL}/extension/puppetloader.rb +1 -1
- data/lib/{corl → CORL}/machine/fog.rb +3 -3
- data/lib/{corl → CORL}/machine/physical.rb +2 -2
- data/lib/{corl → CORL}/network/default.rb +1 -1
- data/lib/{corl → CORL}/node/aws.rb +0 -4
- data/lib/{corl → CORL}/node/google.rb +0 -4
- data/lib/{corl → CORL}/node/local.rb +1 -1
- data/lib/{corl → CORL}/node/rackspace.rb +0 -4
- data/lib/{corl → CORL}/provisioner/puppetnode.rb +1 -14
- data/lib/{corl → CORL}/provisioner/puppetnode/resource.rb +0 -0
- data/lib/{corl → CORL}/provisioner/puppetnode/resource_group.rb +0 -0
- data/lib/{corl → CORL}/template/environment.rb +1 -1
- data/lib/core/facade.rb +49 -0
- data/lib/{corl_core → core}/mixin/action/keypair.rb +10 -10
- data/lib/{corl_core → core}/mixin/lookup.rb +0 -0
- data/lib/{corl_core → core}/mod/hiera_backend.rb +0 -0
- data/lib/{corl_core/mixin/action/node.rb → core/plugin/action.rb} +66 -33
- data/lib/{corl_core → core}/plugin/configuration.rb +2 -2
- data/lib/{corl/node → core/plugin}/fog.rb +5 -1
- data/lib/{corl_core → core}/plugin/machine.rb +2 -2
- data/lib/{corl_core → core}/plugin/network.rb +4 -4
- data/lib/{corl_core → core}/plugin/node.rb +11 -9
- data/lib/{corl_core → core}/plugin/provisioner.rb +2 -2
- data/lib/{corl_core → core}/util/ssh.rb +1 -1
- data/lib/corl.rb +53 -112
- data/lib/puppet/parser/functions/ensure.rb +0 -4
- data/locales/en.yml +55 -148
- metadata +84 -222
- data/lib/corl/action/add.rb +0 -69
- data/lib/corl/action/clone.rb +0 -40
- data/lib/corl/action/create.rb +0 -55
- data/lib/corl/action/exec.rb +0 -41
- data/lib/corl/action/extract.rb +0 -49
- data/lib/corl/action/image.rb +0 -30
- data/lib/corl/action/lookup.rb +0 -35
- data/lib/corl/action/provision.rb +0 -37
- data/lib/corl/action/remove.rb +0 -51
- data/lib/corl/action/save.rb +0 -53
- data/lib/corl/action/start.rb +0 -37
- data/lib/corl/action/stop.rb +0 -30
- data/lib/corl/action/update.rb +0 -37
- data/lib/corl/command/shell.rb +0 -164
- data/lib/corl/event/regex.rb +0 -52
- data/lib/corl/project/git.rb +0 -465
- data/lib/corl/project/github.rb +0 -108
- data/lib/corl/template/json.rb +0 -16
- data/lib/corl/template/wrapper.rb +0 -16
- data/lib/corl/template/yaml.rb +0 -16
- data/lib/corl/translator/json.rb +0 -27
- data/lib/corl/translator/yaml.rb +0 -27
- data/lib/corl_core/codes.rb +0 -107
- data/lib/corl_core/config.rb +0 -337
- data/lib/corl_core/config/collection.rb +0 -57
- data/lib/corl_core/config/options.rb +0 -70
- data/lib/corl_core/core.rb +0 -59
- data/lib/corl_core/corl.rb +0 -254
- data/lib/corl_core/errors.rb +0 -84
- data/lib/corl_core/facade.rb +0 -126
- data/lib/corl_core/gems.rb +0 -72
- data/lib/corl_core/manager.rb +0 -425
- data/lib/corl_core/mixin/action/commit.rb +0 -58
- data/lib/corl_core/mixin/action/project.rb +0 -53
- data/lib/corl_core/mixin/action/push.rb +0 -52
- data/lib/corl_core/mixin/config/collection.rb +0 -53
- data/lib/corl_core/mixin/config/ops.rb +0 -53
- data/lib/corl_core/mixin/config/options.rb +0 -39
- data/lib/corl_core/mixin/macro/object_interface.rb +0 -361
- data/lib/corl_core/mixin/macro/plugin_interface.rb +0 -380
- data/lib/corl_core/mixin/settings.rb +0 -46
- data/lib/corl_core/mixin/sub_config.rb +0 -148
- data/lib/corl_core/mod/hash.rb +0 -29
- data/lib/corl_core/plugin/action.rb +0 -381
- data/lib/corl_core/plugin/base.rb +0 -374
- data/lib/corl_core/plugin/command.rb +0 -98
- data/lib/corl_core/plugin/event.rb +0 -53
- data/lib/corl_core/plugin/extension.rb +0 -12
- data/lib/corl_core/plugin/project.rb +0 -927
- data/lib/corl_core/plugin/template.rb +0 -80
- data/lib/corl_core/plugin/translator.rb +0 -38
- data/lib/corl_core/util/cli.rb +0 -352
- data/lib/corl_core/util/data.rb +0 -404
- data/lib/corl_core/util/disk.rb +0 -114
- data/lib/corl_core/util/git.rb +0 -47
- data/lib/corl_core/util/interface.rb +0 -319
- data/lib/corl_core/util/liquid.rb +0 -17
- data/lib/corl_core/util/package.rb +0 -93
- data/lib/corl_core/util/shell.rb +0 -239
- data/spec/corl_core/interface_spec.rb +0 -489
@@ -1,98 +0,0 @@
|
|
1
|
-
|
2
|
-
module CORL
|
3
|
-
module Plugin
|
4
|
-
class Command < Base
|
5
|
-
|
6
|
-
#-----------------------------------------------------------------------------
|
7
|
-
# Command plugin interface
|
8
|
-
|
9
|
-
def normalize
|
10
|
-
super
|
11
|
-
end
|
12
|
-
|
13
|
-
#---
|
14
|
-
|
15
|
-
def to_s
|
16
|
-
return build(export)
|
17
|
-
end
|
18
|
-
|
19
|
-
#-----------------------------------------------------------------------------
|
20
|
-
# Property accessor / modifiers
|
21
|
-
|
22
|
-
def command(default = '')
|
23
|
-
return string(get(:command, default))
|
24
|
-
end
|
25
|
-
|
26
|
-
#---
|
27
|
-
|
28
|
-
def command=command
|
29
|
-
set(:command, string(command))
|
30
|
-
end
|
31
|
-
|
32
|
-
#---
|
33
|
-
|
34
|
-
def args(default = [])
|
35
|
-
return array(get(:args, default))
|
36
|
-
end
|
37
|
-
|
38
|
-
#---
|
39
|
-
|
40
|
-
def args=args
|
41
|
-
set(:args, array(args))
|
42
|
-
end
|
43
|
-
|
44
|
-
#---
|
45
|
-
|
46
|
-
def flags(default = [])
|
47
|
-
return array(get(:flags, default))
|
48
|
-
end
|
49
|
-
|
50
|
-
#---
|
51
|
-
|
52
|
-
def flags=flags
|
53
|
-
set(:flags, array(flags))
|
54
|
-
end
|
55
|
-
|
56
|
-
#---
|
57
|
-
|
58
|
-
def data(default = {})
|
59
|
-
return hash(get(:data, default))
|
60
|
-
end
|
61
|
-
|
62
|
-
#---
|
63
|
-
|
64
|
-
def data=data
|
65
|
-
set(:data, hash(data))
|
66
|
-
end
|
67
|
-
|
68
|
-
#---
|
69
|
-
|
70
|
-
def subcommand=subcommand
|
71
|
-
unless Util::Data.empty?(subcommand)
|
72
|
-
set(:subcommand, new(hash(subcommand)))
|
73
|
-
end
|
74
|
-
end
|
75
|
-
|
76
|
-
#-----------------------------------------------------------------------------
|
77
|
-
# Command operations
|
78
|
-
|
79
|
-
def build(components = {}, overrides = nil, override_key = false)
|
80
|
-
logger.debug("Building command with #{components.inspect}")
|
81
|
-
logger.debug("Overrides: #{overrides.inspect}")
|
82
|
-
logger.debug("Override key: #{override_key}")
|
83
|
-
|
84
|
-
return '' # Implement in sub classes
|
85
|
-
end
|
86
|
-
|
87
|
-
#---
|
88
|
-
|
89
|
-
def exec(options = {}, overrides = nil)
|
90
|
-
logger.debug("Executing command with #{options.inspect}")
|
91
|
-
logger.debug("Overrides: #{overrides.inspect}")
|
92
|
-
|
93
|
-
# Implement in sub classes (don't forget the yield!)
|
94
|
-
return true
|
95
|
-
end
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
@@ -1,53 +0,0 @@
|
|
1
|
-
|
2
|
-
module CORL
|
3
|
-
module Plugin
|
4
|
-
class Event < Base
|
5
|
-
|
6
|
-
#-----------------------------------------------------------------------------
|
7
|
-
# Event plugin interface
|
8
|
-
|
9
|
-
|
10
|
-
#-----------------------------------------------------------------------------
|
11
|
-
# Property accessor / modifiers
|
12
|
-
|
13
|
-
#-----------------------------------------------------------------------------
|
14
|
-
# Operations
|
15
|
-
|
16
|
-
def render
|
17
|
-
return name
|
18
|
-
end
|
19
|
-
|
20
|
-
#---
|
21
|
-
|
22
|
-
def check(source)
|
23
|
-
# Implement in sub classes
|
24
|
-
return true
|
25
|
-
end
|
26
|
-
|
27
|
-
#-----------------------------------------------------------------------------
|
28
|
-
# Utilities
|
29
|
-
|
30
|
-
def self.build_info(type, data)
|
31
|
-
data = data.split(/\s*,\s*/) if data.is_a?(String)
|
32
|
-
return super(type, data)
|
33
|
-
end
|
34
|
-
|
35
|
-
#---
|
36
|
-
|
37
|
-
def self.translate(data)
|
38
|
-
options = super(data)
|
39
|
-
|
40
|
-
case data
|
41
|
-
when String
|
42
|
-
components = data.split(':')
|
43
|
-
|
44
|
-
options[:provider] = components.shift
|
45
|
-
options[:string] = components.join(':')
|
46
|
-
|
47
|
-
logger.debug("Translating event options: #{options.inspect}")
|
48
|
-
end
|
49
|
-
return options
|
50
|
-
end
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
@@ -1,12 +0,0 @@
|
|
1
|
-
|
2
|
-
module CORL
|
3
|
-
module Plugin
|
4
|
-
class Extension < Base
|
5
|
-
|
6
|
-
#-----------------------------------------------------------------------------
|
7
|
-
# Extension plugin interface
|
8
|
-
|
9
|
-
# This plugin type is just a system container for various plugin hooks
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
@@ -1,927 +0,0 @@
|
|
1
|
-
|
2
|
-
module CORL
|
3
|
-
module Plugin
|
4
|
-
class Project < Base
|
5
|
-
|
6
|
-
@@projects = {}
|
7
|
-
|
8
|
-
#---
|
9
|
-
|
10
|
-
def self.collection
|
11
|
-
@@projects
|
12
|
-
end
|
13
|
-
|
14
|
-
#-----------------------------------------------------------------------------
|
15
|
-
# Constructor / Destructor
|
16
|
-
|
17
|
-
def self.open(directory, provider, options = {})
|
18
|
-
config = Config.ensure(options)
|
19
|
-
directory = File.expand_path(Util::Disk.filename(directory))
|
20
|
-
|
21
|
-
if ! @@projects.has_key?(directory) || config.get(:reset, false)
|
22
|
-
logger.info("Creating new project at #{directory} with #{provider}")
|
23
|
-
|
24
|
-
return CORL.project(config.import({
|
25
|
-
:name => directory,
|
26
|
-
:directory => directory
|
27
|
-
}), provider)
|
28
|
-
|
29
|
-
else
|
30
|
-
logger.info("Opening existing project at #{directory}")
|
31
|
-
end
|
32
|
-
|
33
|
-
@@projects[directory]
|
34
|
-
end
|
35
|
-
|
36
|
-
#-----------------------------------------------------------------------------
|
37
|
-
# Project plugin interface
|
38
|
-
|
39
|
-
def normalize
|
40
|
-
super
|
41
|
-
|
42
|
-
extension(:normalize)
|
43
|
-
|
44
|
-
set_directory(Util::Disk.filename(get(:directory, Dir.pwd)))
|
45
|
-
set_url(get(:url)) if get(:url, false)
|
46
|
-
|
47
|
-
myself.plugin_name = path if myself.plugin_name == plugin_provider
|
48
|
-
|
49
|
-
if keys = delete(:keys, nil)
|
50
|
-
set(:private_key, keys[:private_key])
|
51
|
-
set(:public_key, keys[:public_key])
|
52
|
-
end
|
53
|
-
|
54
|
-
init_project
|
55
|
-
extension(:init)
|
56
|
-
|
57
|
-
pull if get(:pull, false)
|
58
|
-
end
|
59
|
-
|
60
|
-
#---
|
61
|
-
|
62
|
-
def init_project
|
63
|
-
init_auth
|
64
|
-
init_parent
|
65
|
-
init_remotes
|
66
|
-
load_revision
|
67
|
-
end
|
68
|
-
|
69
|
-
#-----------------------------------------------------------------------------
|
70
|
-
# Plugin operations
|
71
|
-
|
72
|
-
def register
|
73
|
-
super
|
74
|
-
# TODO: Scan project directory looking for plugins
|
75
|
-
end
|
76
|
-
|
77
|
-
#-----------------------------------------------------------------------------
|
78
|
-
# Checks
|
79
|
-
|
80
|
-
def can_persist?
|
81
|
-
return top?(directory) if directory
|
82
|
-
false
|
83
|
-
end
|
84
|
-
|
85
|
-
#---
|
86
|
-
|
87
|
-
def top?(path)
|
88
|
-
return true if File.directory?(path)
|
89
|
-
false
|
90
|
-
end
|
91
|
-
|
92
|
-
#---
|
93
|
-
|
94
|
-
def subproject?(path)
|
95
|
-
false
|
96
|
-
end
|
97
|
-
|
98
|
-
#---
|
99
|
-
|
100
|
-
def project_directory?(path, require_top_level = false)
|
101
|
-
path = File.expand_path(path)
|
102
|
-
return true if File.directory?(path) && (! require_top_level || top?(path))
|
103
|
-
false
|
104
|
-
end
|
105
|
-
protected :project_directory?
|
106
|
-
|
107
|
-
#-----------------------------------------------------------------------------
|
108
|
-
# Property accessor / modifiers
|
109
|
-
|
110
|
-
def reference
|
111
|
-
get(:reference, nil)
|
112
|
-
end
|
113
|
-
|
114
|
-
#---
|
115
|
-
|
116
|
-
def private_key
|
117
|
-
get(:private_key, nil)
|
118
|
-
end
|
119
|
-
|
120
|
-
def private_key_str
|
121
|
-
return Util::Disk.read(private_key) if private_key
|
122
|
-
nil
|
123
|
-
end
|
124
|
-
|
125
|
-
def public_key
|
126
|
-
get(:public_key, nil)
|
127
|
-
end
|
128
|
-
|
129
|
-
def public_key_str
|
130
|
-
return Util::Disk.read(public_key) if public_key
|
131
|
-
nil
|
132
|
-
end
|
133
|
-
|
134
|
-
#---
|
135
|
-
|
136
|
-
def url(default = nil)
|
137
|
-
get(:url, default)
|
138
|
-
end
|
139
|
-
|
140
|
-
#---
|
141
|
-
|
142
|
-
def set_url(url)
|
143
|
-
if url && url = extension_set(:set_url, url.strip)
|
144
|
-
logger.info("Setting project #{name} url to #{url}")
|
145
|
-
|
146
|
-
set(:url, url)
|
147
|
-
set_remote(:origin, url)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
#---
|
152
|
-
|
153
|
-
def edit_url(default = nil)
|
154
|
-
get(:edit, default)
|
155
|
-
end
|
156
|
-
|
157
|
-
#---
|
158
|
-
|
159
|
-
def set_edit_url(url)
|
160
|
-
url = url.strip
|
161
|
-
if url && url = extension_set(:set_edit_url, url)
|
162
|
-
logger.info("Setting project #{name} edit url to #{url}")
|
163
|
-
|
164
|
-
set(:edit, url)
|
165
|
-
set_remote(:edit, url)
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
#---
|
170
|
-
|
171
|
-
def directory(default = nil)
|
172
|
-
get(:directory, default)
|
173
|
-
end
|
174
|
-
|
175
|
-
#---
|
176
|
-
|
177
|
-
def path
|
178
|
-
if parent.nil?
|
179
|
-
return directory
|
180
|
-
end
|
181
|
-
directory.gsub(parent.directory + File::SEPARATOR, '')
|
182
|
-
end
|
183
|
-
|
184
|
-
#---
|
185
|
-
|
186
|
-
def set_directory(directory)
|
187
|
-
if Util::Data.empty?(directory)
|
188
|
-
current_directory = Dir.pwd
|
189
|
-
else
|
190
|
-
current_directory = File.expand_path(Util::Disk.filename(directory))
|
191
|
-
end
|
192
|
-
|
193
|
-
if current_directory = extension_set(:set_directory, current_directory)
|
194
|
-
logger.info("Setting project #{name} directory to #{current_directory}")
|
195
|
-
|
196
|
-
@@projects.delete(get(:directory)) if get(:directory)
|
197
|
-
@@projects[current_directory] = myself
|
198
|
-
|
199
|
-
set(:directory, current_directory)
|
200
|
-
end
|
201
|
-
end
|
202
|
-
protected :set_directory
|
203
|
-
|
204
|
-
#---
|
205
|
-
|
206
|
-
def set_location(directory)
|
207
|
-
set_directory(directory)
|
208
|
-
|
209
|
-
yield if block_given?
|
210
|
-
|
211
|
-
init_project
|
212
|
-
end
|
213
|
-
|
214
|
-
#---
|
215
|
-
|
216
|
-
def parent(default = nil)
|
217
|
-
get(:parent, default)
|
218
|
-
end
|
219
|
-
|
220
|
-
#---
|
221
|
-
|
222
|
-
def subprojects(default = nil)
|
223
|
-
get(:subprojects, default)
|
224
|
-
end
|
225
|
-
|
226
|
-
#---
|
227
|
-
|
228
|
-
def revision(default = nil)
|
229
|
-
get(:revision, default).to_s
|
230
|
-
end
|
231
|
-
|
232
|
-
#---
|
233
|
-
|
234
|
-
def config(name, options = {})
|
235
|
-
localize do
|
236
|
-
config = Config.ensure(options)
|
237
|
-
can_persist? && block_given? ? yield(config) : nil
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
#---
|
242
|
-
|
243
|
-
def set_config(name, value, options = {})
|
244
|
-
localize do
|
245
|
-
config = Config.ensure(options)
|
246
|
-
|
247
|
-
if can_persist? && value = extension_set(:set_config, value, { :name => name, :config => config })
|
248
|
-
logger.info("Setting project #{self.name} configuration: #{name} = #{value.inspect}")
|
249
|
-
|
250
|
-
yield(config, value) if block_given?
|
251
|
-
end
|
252
|
-
end
|
253
|
-
end
|
254
|
-
|
255
|
-
#---
|
256
|
-
|
257
|
-
def delete_config(name, options = {})
|
258
|
-
localize do
|
259
|
-
config = Config.ensure(options)
|
260
|
-
|
261
|
-
if can_persist? && extension_check(:delete_config, { :name => name, :config => config })
|
262
|
-
logger.info("Removing project #{self.name} configuration: #{name}")
|
263
|
-
|
264
|
-
yield(config) if block_given?
|
265
|
-
end
|
266
|
-
end
|
267
|
-
end
|
268
|
-
|
269
|
-
#---
|
270
|
-
|
271
|
-
def subproject_config(options = {})
|
272
|
-
result = {}
|
273
|
-
|
274
|
-
localize do
|
275
|
-
if can_persist?
|
276
|
-
config = Config.ensure(options)
|
277
|
-
result = yield(config) if block_given?
|
278
|
-
|
279
|
-
extension(:subproject_config, { :config => result })
|
280
|
-
|
281
|
-
logger.debug("Subproject configuration: #{result.inspect}")
|
282
|
-
end
|
283
|
-
end
|
284
|
-
result
|
285
|
-
end
|
286
|
-
protected :subproject_config
|
287
|
-
|
288
|
-
#-----------------------------------------------------------------------------
|
289
|
-
# Project operations
|
290
|
-
|
291
|
-
def init_auth
|
292
|
-
if can_persist?
|
293
|
-
localize do
|
294
|
-
logger.info("Initializing project #{name} authorization")
|
295
|
-
yield if block_given?
|
296
|
-
end
|
297
|
-
else
|
298
|
-
logger.warn("Project #{name} does not meet the criteria for persistence can not be authorized")
|
299
|
-
end
|
300
|
-
end
|
301
|
-
protected :init_auth
|
302
|
-
|
303
|
-
#---
|
304
|
-
|
305
|
-
def init_parent
|
306
|
-
delete(:parent)
|
307
|
-
|
308
|
-
logger.info("Initializing project #{name} parents")
|
309
|
-
|
310
|
-
if top?(directory)
|
311
|
-
logger.debug("Project #{name} has no parents to initialize")
|
312
|
-
else
|
313
|
-
search_dir = directory
|
314
|
-
last_dir = nil
|
315
|
-
|
316
|
-
while File.directory?((search_dir = File.expand_path('..', search_dir)))
|
317
|
-
logger.debug("Scanning directory #{search_dir} for parent project")
|
318
|
-
|
319
|
-
unless last_dir.nil? || last_dir != search_dir
|
320
|
-
break
|
321
|
-
end
|
322
|
-
if project_directory?(search_dir)
|
323
|
-
logger.debug("Directory #{search_dir} is a valid parent for this #{plugin_provider} project")
|
324
|
-
|
325
|
-
project = myself.class.open(search_dir, plugin_provider)
|
326
|
-
|
327
|
-
extension(:init_parent, { :parent => project })
|
328
|
-
|
329
|
-
set(:parent, project)
|
330
|
-
logger.debug("Setting parent to #{parent.inspect}")
|
331
|
-
break;
|
332
|
-
end
|
333
|
-
last_dir = search_dir
|
334
|
-
end
|
335
|
-
end
|
336
|
-
end
|
337
|
-
protected :init_parent
|
338
|
-
|
339
|
-
#---
|
340
|
-
|
341
|
-
def load_revision
|
342
|
-
if can_persist?
|
343
|
-
localize do
|
344
|
-
logger.info("Loading project #{name} revision")
|
345
|
-
|
346
|
-
current_revision = revision.to_s
|
347
|
-
current_revision = yield if block_given?
|
348
|
-
|
349
|
-
if current_revision && extended_revision = extension_set(:load_revision, current_revision).to_s.strip
|
350
|
-
set(:revision, extended_revision)
|
351
|
-
checkout(extended_revision) if current_revision != extended_revision
|
352
|
-
|
353
|
-
logger.debug("Loaded revision: #{revision}")
|
354
|
-
|
355
|
-
load_subprojects
|
356
|
-
end
|
357
|
-
end
|
358
|
-
else
|
359
|
-
logger.warn("Project #{name} does not meet the criteria for persistence and has no revision")
|
360
|
-
end
|
361
|
-
end
|
362
|
-
protected :load_revision
|
363
|
-
|
364
|
-
#---
|
365
|
-
|
366
|
-
def checkout(revision)
|
367
|
-
if can_persist?
|
368
|
-
localize do
|
369
|
-
if extension_check(:checkout, { :revision => revision })
|
370
|
-
logger.info("Checking out project #{name} revision: #{revision}")
|
371
|
-
|
372
|
-
success = true
|
373
|
-
success = yield(success) if block_given?
|
374
|
-
|
375
|
-
if success
|
376
|
-
set(:revision, revision)
|
377
|
-
|
378
|
-
extension(:checkout_success, { :revision => revision })
|
379
|
-
load_subprojects
|
380
|
-
end
|
381
|
-
end
|
382
|
-
end
|
383
|
-
else
|
384
|
-
logger.warn("Project #{name} does not meet the criteria for persistence and can not checkout a revision")
|
385
|
-
end
|
386
|
-
end
|
387
|
-
|
388
|
-
#---
|
389
|
-
|
390
|
-
def commit(files = '.', options = {})
|
391
|
-
success = false
|
392
|
-
|
393
|
-
if can_persist?
|
394
|
-
localize do
|
395
|
-
config = Config.ensure(options)
|
396
|
-
|
397
|
-
if extension_check(:commit, { :files => files, :config => config })
|
398
|
-
logger.info("Committing changes to project #{name}: #{files.inspect}")
|
399
|
-
|
400
|
-
time = Time.new.strftime("%Y-%m-%d %H:%M:%S")
|
401
|
-
user = config.delete(:user, ENV['USER'] + '@' + fact(:hostname))
|
402
|
-
|
403
|
-
message = config.get(:message, '')
|
404
|
-
message = 'Saving state: ' + ( files.is_a?(Array) ? "\n\n" + files.join("\n") : files.to_s ) if message.empty?
|
405
|
-
|
406
|
-
user = 'UNKNOWN' unless user && ! user.empty?
|
407
|
-
|
408
|
-
logger.debug("Commit by #{user} at #{time} with #{message}")
|
409
|
-
success = yield(config, time, user, message) if block_given?
|
410
|
-
|
411
|
-
if success
|
412
|
-
load_revision
|
413
|
-
|
414
|
-
extension(:commit_success, { :files => files })
|
415
|
-
|
416
|
-
if ! parent.nil? && config.get(:propogate, true)
|
417
|
-
logger.debug("Commit to parent as parent exists and propogate option given")
|
418
|
-
|
419
|
-
parent.load_revision
|
420
|
-
parent.commit(directory, config.import({
|
421
|
-
:message => "Updating #{path}: #{message}"
|
422
|
-
}))
|
423
|
-
end
|
424
|
-
end
|
425
|
-
end
|
426
|
-
end
|
427
|
-
else
|
428
|
-
logger.warn("Project #{name} does not meet the criteria for persistence and can be committed to")
|
429
|
-
end
|
430
|
-
success
|
431
|
-
end
|
432
|
-
|
433
|
-
#-----------------------------------------------------------------------------
|
434
|
-
# Subproject operations
|
435
|
-
|
436
|
-
def load_subprojects(options = {})
|
437
|
-
subprojects = {}
|
438
|
-
|
439
|
-
if can_persist?
|
440
|
-
config = Config.ensure(options)
|
441
|
-
|
442
|
-
logger.info("Loading sub projects for project #{name}")
|
443
|
-
|
444
|
-
subproject_config(config).each do |path, data|
|
445
|
-
project_path = File.join(directory, path)
|
446
|
-
|
447
|
-
if File.directory?(project_path)
|
448
|
-
logger.debug("Checking if project path #{project_path} is a valid sub project")
|
449
|
-
|
450
|
-
add_project = true
|
451
|
-
add_project = yield(project_path, data) if block_given?
|
452
|
-
|
453
|
-
if add_project
|
454
|
-
logger.debug("Directory #{project_path} is a valid sub project for this #{plugin_provider} project")
|
455
|
-
|
456
|
-
project = myself.class.open(project_path, plugin_provider)
|
457
|
-
|
458
|
-
extension(:load_project, { :project => project })
|
459
|
-
subprojects[path] = project
|
460
|
-
else
|
461
|
-
logger.warn("Directory #{project_path} is not a valid sub project for this #{plugin_provider} project")
|
462
|
-
end
|
463
|
-
else
|
464
|
-
logger.warn("Sub project configuration points to a location that is not a directory: #{project_path}")
|
465
|
-
end
|
466
|
-
end
|
467
|
-
else
|
468
|
-
logger.warn("Project #{name} does not meet the criteria for persistence and can not have sub projects")
|
469
|
-
end
|
470
|
-
set(:subprojects, subprojects)
|
471
|
-
end
|
472
|
-
protected :load_subprojects
|
473
|
-
|
474
|
-
#---
|
475
|
-
|
476
|
-
def add_subproject(path, url, revision, options = {})
|
477
|
-
success = true
|
478
|
-
|
479
|
-
if can_persist?
|
480
|
-
localize do
|
481
|
-
config = Config.ensure(options).import({ :path => path, :url => url, :revision => revision })
|
482
|
-
|
483
|
-
if extension_check(:add_project, { :config => config })
|
484
|
-
logger.info("Adding a sub project to #{config[:path]} from #{config[:url]} at #{config[:revision]}")
|
485
|
-
|
486
|
-
success = yield(config) if block_given?
|
487
|
-
|
488
|
-
if success
|
489
|
-
extension(:add_project_success, { :config => config })
|
490
|
-
|
491
|
-
config.init(:files, '.')
|
492
|
-
config.init(:message, "Adding project #{config[:url]} to #{config[:path]}")
|
493
|
-
|
494
|
-
commit(config[:files], { :message => config[:message] })
|
495
|
-
update_subprojects
|
496
|
-
end
|
497
|
-
else
|
498
|
-
success = false
|
499
|
-
end
|
500
|
-
end
|
501
|
-
else
|
502
|
-
logger.warn("Project #{name} does not meet the criteria for persistence and can not have sub projects")
|
503
|
-
end
|
504
|
-
success
|
505
|
-
end
|
506
|
-
|
507
|
-
#---
|
508
|
-
|
509
|
-
def delete_subproject(path)
|
510
|
-
success = true
|
511
|
-
|
512
|
-
if can_persist?
|
513
|
-
localize do
|
514
|
-
config = Config.new({ :path => path })
|
515
|
-
|
516
|
-
if extension_check(:delete_project, { :config => config })
|
517
|
-
logger.info("Deleting a sub project at #{config[:path]}")
|
518
|
-
|
519
|
-
success = yield(config) if block_given?
|
520
|
-
|
521
|
-
if success
|
522
|
-
extension(:delete_project_success, { :config => config })
|
523
|
-
|
524
|
-
config.init(:files, '.')
|
525
|
-
config.init(:message, "Removing project at #{config[:path]}")
|
526
|
-
|
527
|
-
commit(config[:files], { :message => config[:message] })
|
528
|
-
update_subprojects
|
529
|
-
end
|
530
|
-
end
|
531
|
-
end
|
532
|
-
else
|
533
|
-
logger.warn("Project #{name} does not meet the criteria for persistence and can not have sub projects")
|
534
|
-
end
|
535
|
-
success
|
536
|
-
end
|
537
|
-
|
538
|
-
#---
|
539
|
-
|
540
|
-
def update_subprojects
|
541
|
-
if can_persist?
|
542
|
-
localize do
|
543
|
-
if extension_check(:update_projects)
|
544
|
-
logger.info("Updating sub projects in project #{name}")
|
545
|
-
|
546
|
-
success = false
|
547
|
-
success = yield if block_given?
|
548
|
-
|
549
|
-
if success
|
550
|
-
extension(:update_projects_success)
|
551
|
-
load_subprojects
|
552
|
-
end
|
553
|
-
end
|
554
|
-
end
|
555
|
-
else
|
556
|
-
logger.warn("Project #{name} does not meet the criteria for persistence and can not have sub projects")
|
557
|
-
end
|
558
|
-
end
|
559
|
-
protected :update_subprojects
|
560
|
-
|
561
|
-
#---
|
562
|
-
|
563
|
-
def foreach!
|
564
|
-
if can_persist?
|
565
|
-
localize do
|
566
|
-
logger.info("Iterating through all sub projects of project #{name}")
|
567
|
-
|
568
|
-
subprojects.each do |path, project|
|
569
|
-
extension(:process_project, { :project => project })
|
570
|
-
|
571
|
-
logger.debug("Running process on sub project #{path}")
|
572
|
-
yield(path, project)
|
573
|
-
end
|
574
|
-
end
|
575
|
-
else
|
576
|
-
logger.warn("Project #{name} does not meet the criteria for persistence and can not have sub projects")
|
577
|
-
end
|
578
|
-
end
|
579
|
-
|
580
|
-
#-----------------------------------------------------------------------------
|
581
|
-
# Remote operations
|
582
|
-
|
583
|
-
def init_remotes
|
584
|
-
if can_persist?
|
585
|
-
localize do
|
586
|
-
logger.info("Initializing project #{name} remotes")
|
587
|
-
|
588
|
-
origin_url = url
|
589
|
-
origin_url = yield if block_given?
|
590
|
-
|
591
|
-
if origin_url && origin_url = extension_set(:init_remotes, origin_url).to_s.strip
|
592
|
-
set(:url, origin_url)
|
593
|
-
set_edit_url(translate_edit_url(url))
|
594
|
-
end
|
595
|
-
end
|
596
|
-
else
|
597
|
-
logger.warn("Project #{name} does not meet the criteria for persistence and can not have remotes")
|
598
|
-
end
|
599
|
-
end
|
600
|
-
protected :init_remotes
|
601
|
-
|
602
|
-
#---
|
603
|
-
|
604
|
-
def remote(name)
|
605
|
-
url = nil
|
606
|
-
if can_persist?
|
607
|
-
localize do
|
608
|
-
logger.info("Fetching remote url for #{name}")
|
609
|
-
url = yield if block_given?
|
610
|
-
end
|
611
|
-
end
|
612
|
-
url
|
613
|
-
end
|
614
|
-
|
615
|
-
#---
|
616
|
-
|
617
|
-
def set_remote(name, url)
|
618
|
-
if can_persist?
|
619
|
-
localize do
|
620
|
-
if ! url.strip.empty? && url = extension_set(:set_remote, url, { :name => name })
|
621
|
-
delete_remote(name)
|
622
|
-
|
623
|
-
logger.info("Setting project remote #{name} to #{url}")
|
624
|
-
yield(url) if block_given?
|
625
|
-
end
|
626
|
-
end
|
627
|
-
else
|
628
|
-
logger.warn("Project #{self.name} does not meet the criteria for persistence and can not have remotes")
|
629
|
-
end
|
630
|
-
end
|
631
|
-
|
632
|
-
#---
|
633
|
-
|
634
|
-
def add_remote_url(name, url, options = {})
|
635
|
-
if can_persist?
|
636
|
-
localize do
|
637
|
-
config = Config.ensure(options)
|
638
|
-
|
639
|
-
if url = extension_set(:add_remote_url, url, { :name => name, :config => config })
|
640
|
-
logger.info("Adding project remote url #{url} to #{name}")
|
641
|
-
yield(config, url) if block_given?
|
642
|
-
end
|
643
|
-
end
|
644
|
-
else
|
645
|
-
logger.warn("Project #{self.name} does not meet the criteria for persistence and can not have remotes")
|
646
|
-
end
|
647
|
-
end
|
648
|
-
|
649
|
-
#---
|
650
|
-
|
651
|
-
def set_host_remote(name, hosts, path, options = {})
|
652
|
-
if can_persist?
|
653
|
-
localize do
|
654
|
-
config = Config.ensure(options).import({ :path => path })
|
655
|
-
hosts = array(hosts)
|
656
|
-
|
657
|
-
unless hosts.empty?
|
658
|
-
if hosts = extension_set(:set_host_remote, hosts, { :name => name, :config => config })
|
659
|
-
unless ! hosts || hosts.empty?
|
660
|
-
path = config.delete(:path)
|
661
|
-
|
662
|
-
logger.info("Setting host remote #{name} for #{hosts.inspect} at #{path}")
|
663
|
-
set_remote(name, translate_url(hosts.shift, path, config.export))
|
664
|
-
|
665
|
-
hosts.each do |host|
|
666
|
-
logger.debug("Adding remote url to #{host}")
|
667
|
-
add_remote_url(name, translate_url(host, path, config.export), config)
|
668
|
-
end
|
669
|
-
end
|
670
|
-
end
|
671
|
-
end
|
672
|
-
end
|
673
|
-
else
|
674
|
-
logger.warn("Project #{self.name} does not meet the criteria for persistence and can not have remotes")
|
675
|
-
end
|
676
|
-
end
|
677
|
-
|
678
|
-
#---
|
679
|
-
|
680
|
-
def delete_remote(name)
|
681
|
-
if can_persist?
|
682
|
-
localize do
|
683
|
-
if extension_check(:delete_remote, { :name => name })
|
684
|
-
logger.info("Deleting project remote #{name}")
|
685
|
-
yield if block_given?
|
686
|
-
end
|
687
|
-
end
|
688
|
-
else
|
689
|
-
logger.warn("Project #{self.name} does not meet the criteria for persistence and can not have remotes")
|
690
|
-
end
|
691
|
-
end
|
692
|
-
|
693
|
-
#---
|
694
|
-
|
695
|
-
def syncronize(network, options = {})
|
696
|
-
if can_persist?
|
697
|
-
localize do
|
698
|
-
config = Config.ensure(options)
|
699
|
-
|
700
|
-
if extension_check(:syncronize, { :network => network, :config => config })
|
701
|
-
yield(config) if block_given?
|
702
|
-
|
703
|
-
remote_path = config.delete(:remote_path, '/var/corl')
|
704
|
-
|
705
|
-
logger.info("Syncronizing network remotes for project #{name} remote path: #{remote_path}")
|
706
|
-
|
707
|
-
node_hosts = []
|
708
|
-
|
709
|
-
network.nodes.each do |provider, nodes|
|
710
|
-
logger.debug("Iterating over nodes of provider #{provider}")
|
711
|
-
|
712
|
-
nodes.each do |node_name, node|
|
713
|
-
logger.debug("Syncronizing node #{node_name} with hostname: #{node.hostname}")
|
714
|
-
|
715
|
-
node_hosts << node.hostname
|
716
|
-
set_host_remote(node_name, node.hostname, remote_path, config)
|
717
|
-
end
|
718
|
-
end
|
719
|
-
|
720
|
-
logger.debug("Setting 'all' remote to bridge hosts: #{node_hosts.inspect}")
|
721
|
-
set_host_remote('all', node_hosts, remote_path, config) unless node_hosts.empty?
|
722
|
-
end
|
723
|
-
end
|
724
|
-
else
|
725
|
-
logger.warn("Project #{name} does not meet the criteria for persistence and can not have remotes")
|
726
|
-
end
|
727
|
-
true
|
728
|
-
end
|
729
|
-
|
730
|
-
#-----------------------------------------------------------------------------
|
731
|
-
# Remote operations
|
732
|
-
|
733
|
-
def pull(remote = :origin, options = {})
|
734
|
-
success = false
|
735
|
-
|
736
|
-
if can_persist?
|
737
|
-
localize do
|
738
|
-
config = Config.ensure(options).import({ :remote => remote })
|
739
|
-
|
740
|
-
if extension_check(:pull, { :directory => directory, :config => config })
|
741
|
-
remote = config.delete(:remote)
|
742
|
-
|
743
|
-
logger.info("Pulling from #{remote} into #{directory}")
|
744
|
-
|
745
|
-
success = yield(config, remote) if block_given?
|
746
|
-
|
747
|
-
if success
|
748
|
-
load_revision
|
749
|
-
update_subprojects
|
750
|
-
|
751
|
-
extension(:pull_success, { :directory => directory, :remote => remote, :config => config })
|
752
|
-
|
753
|
-
if ! parent.nil? && config.get(:propogate, true)
|
754
|
-
logger.debug("Commit to parent as parent exists and propogate option was given")
|
755
|
-
|
756
|
-
parent.commit(directory, config.import({
|
757
|
-
:message => "Pulling updates for subproject #{path}",
|
758
|
-
:allow_empty => true
|
759
|
-
}))
|
760
|
-
end
|
761
|
-
end
|
762
|
-
end
|
763
|
-
end
|
764
|
-
else
|
765
|
-
logger.warn("Project #{name} does not meet the criteria for persistence and can not pull from remotes")
|
766
|
-
end
|
767
|
-
success
|
768
|
-
end
|
769
|
-
|
770
|
-
#---
|
771
|
-
|
772
|
-
def push(remote = :edit, options = {})
|
773
|
-
success = false
|
774
|
-
|
775
|
-
if can_persist?
|
776
|
-
localize do
|
777
|
-
config = Config.ensure(options).import({ :remote => remote })
|
778
|
-
|
779
|
-
if extension_check(:push, { :directory => directory, :config => config })
|
780
|
-
remote = config.delete(:remote)
|
781
|
-
|
782
|
-
logger.info("Pushing to #{remote} from #{directory}")
|
783
|
-
|
784
|
-
success = yield(config, remote) if block_given?
|
785
|
-
|
786
|
-
if success
|
787
|
-
config.delete(:revision)
|
788
|
-
|
789
|
-
extension(:push_success, { :directory => directory, :remote => remote, :config => config })
|
790
|
-
|
791
|
-
if config.get(:propogate, true)
|
792
|
-
logger.debug("Pushing sub projects as propogate option was given")
|
793
|
-
|
794
|
-
foreach! do |path, project|
|
795
|
-
project.push(remote, config)
|
796
|
-
end
|
797
|
-
end
|
798
|
-
end
|
799
|
-
end
|
800
|
-
end
|
801
|
-
else
|
802
|
-
logger.warn("Project #{name} does not meet the criteria for persistence and can not push to remotes")
|
803
|
-
end
|
804
|
-
success
|
805
|
-
end
|
806
|
-
|
807
|
-
#-----------------------------------------------------------------------------
|
808
|
-
# Utilities
|
809
|
-
|
810
|
-
def self.build_info(type, data)
|
811
|
-
data = data.split(/\s*,\s*/) if data.is_a?(String)
|
812
|
-
super(type, data)
|
813
|
-
end
|
814
|
-
|
815
|
-
#---
|
816
|
-
|
817
|
-
def self.translate(data)
|
818
|
-
options = super(data)
|
819
|
-
|
820
|
-
case data
|
821
|
-
when String
|
822
|
-
options = { :url => data }
|
823
|
-
when Hash
|
824
|
-
options = data
|
825
|
-
end
|
826
|
-
|
827
|
-
if options.has_key?(:url)
|
828
|
-
if matches = translate_reference(options[:url])
|
829
|
-
options[:provider] = matches[:provider]
|
830
|
-
options[:url] = matches[:url]
|
831
|
-
options[:revision] = matches[:revision] unless options.has_key?(:revision)
|
832
|
-
|
833
|
-
logger.debug("Translating project options: #{options.inspect}")
|
834
|
-
end
|
835
|
-
end
|
836
|
-
options
|
837
|
-
end
|
838
|
-
|
839
|
-
#---
|
840
|
-
|
841
|
-
def self.translate_reference(reference, editable = false)
|
842
|
-
# ex: github:::username/project[branch/revision]
|
843
|
-
if reference && reference.match(/^\s*([a-zA-Z0-9_-]+):::([^\]\s]+)\s*(?:\[\s*([^\]\s]+)\s*\])?\s*$/)
|
844
|
-
provider = $1
|
845
|
-
url = $2
|
846
|
-
revision = $3
|
847
|
-
|
848
|
-
logger.debug("Translating project reference: #{provider} #{url} #{revision}")
|
849
|
-
|
850
|
-
if provider && Manager.connection.loaded_plugins(:project).keys.include?(provider.to_sym)
|
851
|
-
klass = CORL.class_const([ :corl, :project, provider ])
|
852
|
-
expanded_url = klass.send(:expand_url, url, editable) if klass.respond_to?(:expand_url)
|
853
|
-
end
|
854
|
-
expanded_url = url unless expanded_url
|
855
|
-
|
856
|
-
info = {
|
857
|
-
:provider => provider,
|
858
|
-
:reference => url,
|
859
|
-
:url => expanded_url,
|
860
|
-
:revision => revision
|
861
|
-
}
|
862
|
-
|
863
|
-
logger.debug("Project reference info: #{info.inspect}")
|
864
|
-
return info
|
865
|
-
end
|
866
|
-
nil
|
867
|
-
end
|
868
|
-
|
869
|
-
#---
|
870
|
-
|
871
|
-
def translate_reference(reference, editable = false)
|
872
|
-
myself.class.translate_reference(reference, editable)
|
873
|
-
end
|
874
|
-
|
875
|
-
#---
|
876
|
-
|
877
|
-
def translate_url(host, path, options = {})
|
878
|
-
config = Config.ensure(options)
|
879
|
-
url = "#{host}/#{path}"
|
880
|
-
|
881
|
-
if block_given?
|
882
|
-
temp_url = yield(config)
|
883
|
-
url = temp_url if temp_url
|
884
|
-
end
|
885
|
-
url
|
886
|
-
end
|
887
|
-
|
888
|
-
#---
|
889
|
-
|
890
|
-
def translate_edit_url(url, options = {})
|
891
|
-
config = Config.ensure(options)
|
892
|
-
|
893
|
-
if block_given?
|
894
|
-
temp_url = yield(config)
|
895
|
-
url = temp_url if temp_url
|
896
|
-
end
|
897
|
-
url
|
898
|
-
end
|
899
|
-
|
900
|
-
#---
|
901
|
-
|
902
|
-
def localize
|
903
|
-
prev_directory = Dir.pwd
|
904
|
-
Dir.chdir(directory)
|
905
|
-
|
906
|
-
result = safe_exec(true) do
|
907
|
-
yield
|
908
|
-
end
|
909
|
-
|
910
|
-
Dir.chdir(prev_directory)
|
911
|
-
result
|
912
|
-
end
|
913
|
-
|
914
|
-
#---
|
915
|
-
|
916
|
-
def local_path(file_path)
|
917
|
-
file_path.gsub(directory + File::SEPARATOR, '')
|
918
|
-
end
|
919
|
-
|
920
|
-
#---
|
921
|
-
|
922
|
-
def full_path(local_path)
|
923
|
-
File.join(directory, local_path)
|
924
|
-
end
|
925
|
-
end
|
926
|
-
end
|
927
|
-
end
|