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.
Files changed (122) hide show
  1. data/Gemfile +5 -10
  2. data/Gemfile.lock +13 -11
  3. data/README.rdoc +1 -1
  4. data/Rakefile +3 -3
  5. data/VERSION +1 -1
  6. data/bin/corl +2 -54
  7. data/bootstrap/bootstrap.sh +91 -0
  8. data/bootstrap/lib/shell/LICENSE.txt +674 -0
  9. data/bootstrap/lib/shell/command.sh +214 -0
  10. data/bootstrap/lib/shell/filesystem.sh +139 -0
  11. data/bootstrap/lib/shell/load.sh +73 -0
  12. data/bootstrap/lib/shell/os.sh +67 -0
  13. data/bootstrap/lib/shell/script.sh +160 -0
  14. data/bootstrap/lib/shell/starter.sh +64 -0
  15. data/bootstrap/lib/shell/validators.sh +50 -0
  16. data/bootstrap/os/ubuntu/00_base.sh +5 -0
  17. data/bootstrap/os/ubuntu/01_git.sh +5 -0
  18. data/bootstrap/os/ubuntu/05_ruby.sh +7 -0
  19. data/bootstrap/os/ubuntu/06_puppet.sh +38 -0
  20. data/bootstrap/os/ubuntu/10_corl.sh +9 -0
  21. data/corl.gemspec +61 -124
  22. data/lib/{corl → CORL}/action/bootstrap.rb +13 -7
  23. data/lib/CORL/action/exec.rb +39 -0
  24. data/lib/CORL/action/image.rb +31 -0
  25. data/lib/{corl → CORL}/action/images.rb +1 -1
  26. data/lib/CORL/action/lookup.rb +34 -0
  27. data/lib/{corl → CORL}/action/machines.rb +1 -1
  28. data/lib/CORL/action/provision.rb +31 -0
  29. data/lib/{corl → CORL}/action/seed.rb +3 -3
  30. data/lib/{corl → CORL}/action/spawn.rb +2 -2
  31. data/lib/CORL/action/start.rb +31 -0
  32. data/lib/CORL/action/stop.rb +31 -0
  33. data/lib/{corl → CORL}/configuration/file.rb +1 -1
  34. data/lib/{corl → CORL}/event/puppet.rb +1 -1
  35. data/lib/{corl → CORL}/extension/puppetloader.rb +1 -1
  36. data/lib/{corl → CORL}/machine/fog.rb +3 -3
  37. data/lib/{corl → CORL}/machine/physical.rb +2 -2
  38. data/lib/{corl → CORL}/network/default.rb +1 -1
  39. data/lib/{corl → CORL}/node/aws.rb +0 -4
  40. data/lib/{corl → CORL}/node/google.rb +0 -4
  41. data/lib/{corl → CORL}/node/local.rb +1 -1
  42. data/lib/{corl → CORL}/node/rackspace.rb +0 -4
  43. data/lib/{corl → CORL}/provisioner/puppetnode.rb +1 -14
  44. data/lib/{corl → CORL}/provisioner/puppetnode/resource.rb +0 -0
  45. data/lib/{corl → CORL}/provisioner/puppetnode/resource_group.rb +0 -0
  46. data/lib/{corl → CORL}/template/environment.rb +1 -1
  47. data/lib/core/facade.rb +49 -0
  48. data/lib/{corl_core → core}/mixin/action/keypair.rb +10 -10
  49. data/lib/{corl_core → core}/mixin/lookup.rb +0 -0
  50. data/lib/{corl_core → core}/mod/hiera_backend.rb +0 -0
  51. data/lib/{corl_core/mixin/action/node.rb → core/plugin/action.rb} +66 -33
  52. data/lib/{corl_core → core}/plugin/configuration.rb +2 -2
  53. data/lib/{corl/node → core/plugin}/fog.rb +5 -1
  54. data/lib/{corl_core → core}/plugin/machine.rb +2 -2
  55. data/lib/{corl_core → core}/plugin/network.rb +4 -4
  56. data/lib/{corl_core → core}/plugin/node.rb +11 -9
  57. data/lib/{corl_core → core}/plugin/provisioner.rb +2 -2
  58. data/lib/{corl_core → core}/util/ssh.rb +1 -1
  59. data/lib/corl.rb +53 -112
  60. data/lib/puppet/parser/functions/ensure.rb +0 -4
  61. data/locales/en.yml +55 -148
  62. metadata +84 -222
  63. data/lib/corl/action/add.rb +0 -69
  64. data/lib/corl/action/clone.rb +0 -40
  65. data/lib/corl/action/create.rb +0 -55
  66. data/lib/corl/action/exec.rb +0 -41
  67. data/lib/corl/action/extract.rb +0 -49
  68. data/lib/corl/action/image.rb +0 -30
  69. data/lib/corl/action/lookup.rb +0 -35
  70. data/lib/corl/action/provision.rb +0 -37
  71. data/lib/corl/action/remove.rb +0 -51
  72. data/lib/corl/action/save.rb +0 -53
  73. data/lib/corl/action/start.rb +0 -37
  74. data/lib/corl/action/stop.rb +0 -30
  75. data/lib/corl/action/update.rb +0 -37
  76. data/lib/corl/command/shell.rb +0 -164
  77. data/lib/corl/event/regex.rb +0 -52
  78. data/lib/corl/project/git.rb +0 -465
  79. data/lib/corl/project/github.rb +0 -108
  80. data/lib/corl/template/json.rb +0 -16
  81. data/lib/corl/template/wrapper.rb +0 -16
  82. data/lib/corl/template/yaml.rb +0 -16
  83. data/lib/corl/translator/json.rb +0 -27
  84. data/lib/corl/translator/yaml.rb +0 -27
  85. data/lib/corl_core/codes.rb +0 -107
  86. data/lib/corl_core/config.rb +0 -337
  87. data/lib/corl_core/config/collection.rb +0 -57
  88. data/lib/corl_core/config/options.rb +0 -70
  89. data/lib/corl_core/core.rb +0 -59
  90. data/lib/corl_core/corl.rb +0 -254
  91. data/lib/corl_core/errors.rb +0 -84
  92. data/lib/corl_core/facade.rb +0 -126
  93. data/lib/corl_core/gems.rb +0 -72
  94. data/lib/corl_core/manager.rb +0 -425
  95. data/lib/corl_core/mixin/action/commit.rb +0 -58
  96. data/lib/corl_core/mixin/action/project.rb +0 -53
  97. data/lib/corl_core/mixin/action/push.rb +0 -52
  98. data/lib/corl_core/mixin/config/collection.rb +0 -53
  99. data/lib/corl_core/mixin/config/ops.rb +0 -53
  100. data/lib/corl_core/mixin/config/options.rb +0 -39
  101. data/lib/corl_core/mixin/macro/object_interface.rb +0 -361
  102. data/lib/corl_core/mixin/macro/plugin_interface.rb +0 -380
  103. data/lib/corl_core/mixin/settings.rb +0 -46
  104. data/lib/corl_core/mixin/sub_config.rb +0 -148
  105. data/lib/corl_core/mod/hash.rb +0 -29
  106. data/lib/corl_core/plugin/action.rb +0 -381
  107. data/lib/corl_core/plugin/base.rb +0 -374
  108. data/lib/corl_core/plugin/command.rb +0 -98
  109. data/lib/corl_core/plugin/event.rb +0 -53
  110. data/lib/corl_core/plugin/extension.rb +0 -12
  111. data/lib/corl_core/plugin/project.rb +0 -927
  112. data/lib/corl_core/plugin/template.rb +0 -80
  113. data/lib/corl_core/plugin/translator.rb +0 -38
  114. data/lib/corl_core/util/cli.rb +0 -352
  115. data/lib/corl_core/util/data.rb +0 -404
  116. data/lib/corl_core/util/disk.rb +0 -114
  117. data/lib/corl_core/util/git.rb +0 -47
  118. data/lib/corl_core/util/interface.rb +0 -319
  119. data/lib/corl_core/util/liquid.rb +0 -17
  120. data/lib/corl_core/util/package.rb +0 -93
  121. data/lib/corl_core/util/shell.rb +0 -239
  122. 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