corl 0.4.0 → 0.4.1

Sign up to get free protection for your applications and to get access to all the features.
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