logical-construct 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. data/bin/flight-deck +3 -0
  2. data/doc/DESIGN +48 -0
  3. data/doc/EC2-baking-notes +70 -0
  4. data/doc/ExampleStartupRakefile +152 -0
  5. data/doc/ExampleTargetRakefile +4 -0
  6. data/doc/TODO +148 -0
  7. data/doc/Vb-EC2-translation-notes +96 -0
  8. data/doc/hating-chef +32 -0
  9. data/lib/logical-construct/archive-tasks.rb +307 -0
  10. data/lib/logical-construct/ground-control.rb +4 -1
  11. data/lib/logical-construct/ground-control/build-plan.rb +95 -0
  12. data/lib/logical-construct/ground-control/core.rb +1 -1
  13. data/lib/logical-construct/ground-control/generate-manifest.rb +67 -0
  14. data/lib/logical-construct/ground-control/provision.rb +73 -168
  15. data/lib/logical-construct/ground-control/run-on-target.rb +1 -1
  16. data/lib/logical-construct/ground-control/setup.rb +1 -4
  17. data/lib/logical-construct/ground-control/setup/copy-files.rb +2 -2
  18. data/lib/logical-construct/ground-control/tools.rb +66 -0
  19. data/lib/logical-construct/node-client.rb +112 -0
  20. data/lib/logical-construct/plan.rb +2 -0
  21. data/lib/logical-construct/plan/core.rb +45 -0
  22. data/lib/logical-construct/plan/standalone-bundle.rb +80 -0
  23. data/lib/logical-construct/port-open-check.rb +41 -0
  24. data/lib/logical-construct/protocol.rb +2 -0
  25. data/lib/logical-construct/protocol/plan-validation.rb +46 -0
  26. data/lib/logical-construct/protocol/ssh-tunnel.rb +127 -0
  27. data/lib/logical-construct/protocol/vocabulary.rb +8 -0
  28. data/lib/logical-construct/target/Implement.rake +8 -0
  29. data/lib/logical-construct/target/command-line.rb +90 -0
  30. data/lib/logical-construct/target/flight-deck.rb +341 -0
  31. data/lib/logical-construct/target/implementation.rb +33 -0
  32. data/lib/logical-construct/target/plan-records.rb +317 -0
  33. data/lib/logical-construct/target/resolution-server.rb +153 -0
  34. data/lib/logical-construct/target/{unpack-cookbook.rb → unpack-plan.rb} +8 -4
  35. data/lib/logical-construct/template-file.rb +41 -0
  36. data/lib/templates/Rakefile.erb +8 -0
  37. data/spec/ground-control/smoke-test.rb +8 -7
  38. data/spec/node_resolution.rb +62 -0
  39. data/spec/target/plan-records.rb +142 -0
  40. data/spec/target/provisioning.rb +21 -0
  41. data/spec_help/file-sandbox.rb +12 -6
  42. data/spec_help/fixtures/Manifest +1 -0
  43. data/spec_help/fixtures/source/one.tbz +1 -0
  44. data/spec_help/fixtures/source/three.tbz +1 -0
  45. data/spec_help/fixtures/source/two.tbz +1 -0
  46. data/spec_help/spec_helper.rb +5 -7
  47. metadata +165 -72
  48. data/lib/logical-construct/ground-control/setup/build-files.rb +0 -93
  49. data/lib/logical-construct/ground-control/setup/create-construct-directory.rb +0 -22
  50. data/lib/logical-construct/ground-control/setup/install-init.rb +0 -32
  51. data/lib/logical-construct/resolving-task.rb +0 -141
  52. data/lib/logical-construct/satisfiable-task.rb +0 -87
  53. data/lib/logical-construct/target.rb +0 -4
  54. data/lib/logical-construct/target/chef-solo.rb +0 -37
  55. data/lib/logical-construct/target/platforms.rb +0 -51
  56. data/lib/logical-construct/target/platforms/aws.rb +0 -8
  57. data/lib/logical-construct/target/platforms/default/chef-config.rb +0 -134
  58. data/lib/logical-construct/target/platforms/default/resolve-configuration.rb +0 -44
  59. data/lib/logical-construct/target/platforms/default/volume.rb +0 -11
  60. data/lib/logical-construct/target/platforms/virtualbox.rb +0 -8
  61. data/lib/logical-construct/target/platforms/virtualbox/volume.rb +0 -15
  62. data/lib/logical-construct/target/provision.rb +0 -36
  63. data/lib/logical-construct/target/sinatra-resolver.rb +0 -99
  64. data/lib/logical-construct/testing/resolve-configuration.rb +0 -32
  65. data/lib/logical-construct/testing/resolving-task.rb +0 -15
  66. data/lib/templates/chef.rb.erb +0 -9
  67. data/lib/templates/construct.init.d.erb +0 -18
  68. data/lib/templates/resolver/finished.html.erb +0 -1
  69. data/lib/templates/resolver/index.html.erb +0 -17
  70. data/lib/templates/resolver/task-file-form.html.erb +0 -6
  71. data/lib/templates/resolver/task-form.html.erb +0 -6
  72. data/spec/resolution.rb +0 -147
  73. data/spec/target/chef-config.rb +0 -67
  74. data/spec/target/chef-solo.rb +0 -55
  75. data/spec/target/platforms.rb +0 -36
  76. data/spec/target/smoke-test.rb +0 -45
  77. data/spec_help/ungemmer.rb +0 -36
@@ -0,0 +1,32 @@
1
+ Notes about tasks that Chef performs:
2
+
3
+ Install software (i.e. emerge <thing>)
4
+ Template configs (w/o regard to changes)
5
+ Edit files (not using patch)
6
+ Create files (a la GNU install), directories
7
+
8
+ Doesn't: manage archives (tarballs)
9
+
10
+
11
+
12
+ So, tasks that would be nice:
13
+ emerge (or apt-get or ...)
14
+ template files
15
+ apply patches
16
+ edit files? (still seems dicey)
17
+ create files/directories like GNU install does
18
+ unpack tarballs
19
+ manage symlinks
20
+ VCS checkouts
21
+
22
+ restart/start/enable services
23
+
24
+ run arbitrary shell commands (as little as possible)
25
+ (Maybe just: template a file, run bash (file))
26
+
27
+
28
+ One thing Chef does that's useful is "notifies ... :delayed" - basically tasks that are only needed if this one is, but happen later
29
+ So: a Task type (mixin) that is #needed? based on a boolean - by default, not, but other tasks can say something like arm that:other:task ->
30
+ Rake::application[that:other:task].needed = true. Order of execution determined by dependency.
31
+
32
+ For package installs, consider /etc/portage/sets
@@ -0,0 +1,307 @@
1
+ require 'mattock'
2
+ module LogicalConstruct
3
+ class TarballTask < ::Mattock::Rake::FileCommandTask
4
+ setting :compression, :auto
5
+ setting :compression_flag, nil
6
+ setting :exclude_vcs, true
7
+
8
+ dir(:unpacked_parent, dir(:unpacked_dir))
9
+ dir(:archive_parent, path(:archive))
10
+
11
+ setting :basename, nil
12
+ setting :extension, "tbz"
13
+
14
+ def default_configuration
15
+ super
16
+ self.compression_flag ||=
17
+ case compression
18
+ when :auto
19
+ "--auto-compress"
20
+ when :gzip
21
+ "--gzip"
22
+ when :bzip, :bzip2
23
+ "--bzip2"
24
+ when :xz
25
+ "--xz"
26
+ when :lzip
27
+ "--lzip"
28
+ when :lzma
29
+ "--lzma"
30
+ when :lzop
31
+ "--lzop"
32
+ when :compress
33
+ "--compress"
34
+ else
35
+ ""
36
+ end
37
+
38
+ self.basename = name
39
+ end
40
+
41
+ def resolve_configuration
42
+ extension.sub(/[.]$/,'')
43
+
44
+ unpacked_parent.absolute_path ||= absolute_path
45
+ archive_parent.absolute_path ||= absolute_path
46
+
47
+ unless basename.nil?
48
+ unpacked_dir.relative_path ||= basename
49
+ archive.relative_path ||= [basename, extension].join(".")
50
+ end
51
+
52
+ resolve_paths
53
+ super
54
+ end
55
+
56
+ def action_flag(string)
57
+ case string
58
+ when "c", /create/
59
+ "--create"
60
+ when "x", /extract/
61
+ "--extract"
62
+ when "d", /compare/
63
+ "--compare"
64
+ else
65
+ string
66
+ end
67
+ end
68
+
69
+ def add_options(tar)
70
+ tar.options << "--files-from=" + listfile
71
+ end
72
+
73
+ def tar_command(action, verbose = true, &block)
74
+ tar_command_without_directory(action, verbose) do |tar|
75
+ tar.options << "--directory="+unpacked_dir.absolute_path
76
+ yield tar if block_given?
77
+ end
78
+ end
79
+
80
+ def tar_command_without_directory(action, verbose = true)
81
+ command = cmd("tar") do |tar|
82
+ tar.options << action
83
+ tar.options << "--verbose" if verbose
84
+ tar.options << compression_flag
85
+ tar.options << "--file="+archive.absolute_path
86
+ tar.options << "--exclude-vcs" if exclude_vcs
87
+ yield(tar) if block_given?
88
+ end
89
+ return command
90
+ end
91
+ end
92
+
93
+ class PackTarballTask < TarballTask
94
+ default_taskname :pack_tarball
95
+ path :listfile
96
+
97
+ def command
98
+ tar_command("--create") do |tar|
99
+ tar.options << "--files-from="+listfile.absolute_path
100
+ end
101
+ end
102
+
103
+ def needed?
104
+ return true if super
105
+ if File::exists?(target_path)
106
+ return !(tar_command("--compare"){|tar| tar.options << "--files-from=" + listfile.absolute_path } & tar_command("--compare")).succeeds?
107
+ end
108
+ return true
109
+ end
110
+
111
+ def define
112
+ super
113
+ if prerequisite_tasks.empty?
114
+ enhance(source_files)
115
+ end
116
+ end
117
+ end
118
+
119
+ class UnpackTarballTask < TarballTask
120
+ default_taskname :unpack_tarball
121
+
122
+ def command
123
+ (cmd("mkdir", "-p", unpacked_dir.absolute_path) & tar_command("--extract")) #ok
124
+ end
125
+
126
+ def target_files
127
+ FileList[tar_command_without_directory("--list", false).run.stdout.split.map do |path|
128
+ unpacked_dir.pathname.join(path).to_s
129
+ end]
130
+ end
131
+
132
+ def create_target_dependencies
133
+ target_files.each do |path|
134
+ ::Rake::FileTask.define_task(path => name)
135
+ end
136
+ end
137
+
138
+ def needed?
139
+ return true if super
140
+ if File::exists?(archive_path.absolute_path)
141
+ return !(tar_command("--compare")).succeeds?
142
+ end
143
+ return true
144
+ end
145
+ end
146
+
147
+ class PackTarball < ::Mattock::Tasklib
148
+ default_namespace :pack
149
+
150
+ dir(:unpacked_dir)
151
+
152
+ dir(:marshalling,
153
+ path(:listfile),
154
+ path(:archive))
155
+
156
+ setting :basename, nil
157
+ setting :extension, "tbz"
158
+ setting :source_files
159
+ setting :source_pattern, "**/*"
160
+ setting :exclude_patterns, ['**/*.sw[p-z]'] #ok
161
+
162
+ def resolve_configuration
163
+ listfile.relative_path ||= "#{basename}.list"
164
+ unless basename.nil?
165
+ self.unpacked_dir.relative_path ||= basename
166
+ self.archive.relative_path ||= [basename, extension].join(".")
167
+ end
168
+
169
+ resolve_paths
170
+
171
+ self.source_files ||=
172
+ begin
173
+ pattern = File::join(unpacked_dir.absolute_path, source_pattern)
174
+ list = FileList[pattern]
175
+ exclude_patterns.each do |pattern|
176
+ list.exclude(pattern)
177
+ end
178
+ list
179
+ end
180
+
181
+ super
182
+ end
183
+
184
+ def define
185
+ super
186
+ in_namespace do
187
+ file listfile.absolute_path => [Rake.application.rakefile, marshalling.absolute_path] + source_files do |task|
188
+ require 'pathname'
189
+ source_pathname = Pathname.new(unpacked_dir.absolute_path)
190
+ files = source_files.map do |path|
191
+ Pathname.new(path)
192
+ end.find_all do |pathname|
193
+ not (pathname.directory? and not pathname.children.empty?)
194
+ end.map do |pathname|
195
+ pathname.relative_path_from source_pathname
196
+ end
197
+
198
+ File::open(listfile.absolute_path, "w") do |list|
199
+ list.write(files.join("\n"))
200
+ end
201
+ end
202
+
203
+ PackTarballTask.define_task(archive.absolute_path => [marshalling.absolute_path] + source_files + [listfile.absolute_path]) do |task|
204
+ copy_settings_to(task)
205
+ end
206
+ task archive.absolute_path => Rake.application.rakefile unless Rake.application.rakefile.nil?
207
+ end
208
+ end
209
+ end
210
+
211
+ class UnpackTarballs < Mattock::Tasklib
212
+ class RemoveFilesNotInArchives < TarballTask
213
+ dir :unpacked_dir
214
+
215
+ setting :archive_paths
216
+ setting :file_list
217
+
218
+ attr_accessor :stray_files
219
+
220
+ def resolve_configuration
221
+ resolve_paths
222
+
223
+ super
224
+ end
225
+
226
+ def stray_files
227
+ @stray_files ||=
228
+ begin
229
+ archive_paths.each do |archive_path|
230
+ list_process = tar_command("--list")
231
+ if list_process.succeeds?
232
+ self.archive_files += list_process.stdout.lines.to_a.map{|line| line.chomp}
233
+ end
234
+ end
235
+ archive_files.map!{|path| File::expand_path(path, target_dir)}
236
+
237
+ self.stray_files = file_list - archive_files
238
+ stray_files.delete_if{|path| File::directory?(path)}
239
+ unsafe_cleanup = stray_files.find_all do |path|
240
+ %r{\A/} =~ path and not %r{\A#{File::expand_path(target_dir)}} =~ path
241
+ end
242
+ raise "Unsafe stray cleanup: #{unsafe_cleanup.inspect}" unless unsafe_cleanup.empty?
243
+ stray_files
244
+ end
245
+ end
246
+
247
+ def needed?
248
+ stray_files.any? do |path|
249
+ File.exists?(path)
250
+ end
251
+ end
252
+
253
+ def command
254
+ cmd("rm", "-f", *stray_files)
255
+ end
256
+ end
257
+
258
+ default_namespace :unpack
259
+
260
+ setting :archive_paths, []
261
+ setting :archive_path, nil
262
+
263
+ dir :unpacked_dir
264
+ setting :target_pattern, "**/*"
265
+ setting :file_list
266
+
267
+ def resolve_configuration
268
+ unless archive_path.nil?
269
+ archive_paths << archive_path
270
+ end
271
+
272
+ resolve_paths
273
+
274
+ self.file_list ||= FileList[File::join(File::expand_path(target_dir),target_pattern)]
275
+
276
+ super
277
+ end
278
+
279
+ def define
280
+ in_namespace do
281
+ archive_paths.each do |archive|
282
+ UnpackTarballTask.define_task(archive) do |unpack|
283
+ copy_settings_to(unpack)
284
+ unpack.archive_path.absolute_path = archive
285
+ end
286
+ end
287
+
288
+ if file_list.empty?
289
+ task :unpack => archive_paths
290
+ else
291
+ RemoveFilesNotInArchives.define_task(:remove_strays => archive_paths) do |remove_strays|
292
+ copy_settings_to(remove_strays)
293
+ end
294
+
295
+ task :unpack => file_list
296
+ file_list.each do |path|
297
+ file path => :remove_strays
298
+ end
299
+ end
300
+ end
301
+
302
+ task namespace_name => self[:unpack]
303
+ end
304
+ end
305
+
306
+ UnpackTarball = UnpackTarballs
307
+ end
@@ -1,3 +1,6 @@
1
+ require 'mattock'
1
2
  require 'logical-construct/ground-control/core'
2
- require 'logical-construct/ground-control/setup'
3
+ #require 'logical-construct/ground-control/setup'
3
4
  require 'logical-construct/ground-control/provision'
5
+ require 'logical-construct/ground-control/tools'
6
+ require 'logical-construct/ground-control/generate-manifest'
@@ -0,0 +1,95 @@
1
+ require 'logical-construct/ground-control'
2
+ require 'mattock/tasklib'
3
+ require 'logical-construct/archive-tasks'
4
+
5
+ module LogicalConstruct::GroundControl
6
+ class BuildPlan < Mattock::Tasklib
7
+ include Mattock::CommandLineDSL
8
+
9
+ default_namespace :build_plan
10
+
11
+ setting :manifest_task
12
+
13
+ dir(:plan_source, "source",
14
+ dir(:plan, path(:plan_rakefile, "plan.rake")))
15
+ dir(:marshalling, "marshall",
16
+ dir(:plan_temp,
17
+ dir(:synced, "sync")))
18
+
19
+ setting :source_pattern, "**/*"
20
+ setting :exclude_patterns, ["**/*.sw[p-z]"] #ok
21
+ setting :basename
22
+
23
+ setting :synced_files
24
+
25
+ def default_configuration(provisioning)
26
+ super
27
+ provisioning.copy_settings_to(self)
28
+
29
+ self.manifest_task = provisioning[:manifest]
30
+ end
31
+
32
+ def resolve_configuration
33
+ fail_unless_set(:basename)
34
+ plan.relative_path ||= basename
35
+ plan_temp.relative_path ||= basename
36
+
37
+ resolve_paths
38
+
39
+ self.synced_files =
40
+ begin
41
+ pattern = File::join(plan.absolute_path, source_pattern)
42
+ list = FileList[pattern]
43
+ exclude_patterns.each do |pattern|
44
+ list.exclude(pattern)
45
+ end
46
+ list.map do |path|
47
+ synced.pathname.join(Pathname.new(path).relative_path_from(plan.pathname)).to_s
48
+ end
49
+ end
50
+
51
+ super
52
+ end
53
+
54
+ def archive_path
55
+ @pack.archive.absolute_path
56
+ end
57
+
58
+ def define
59
+ super
60
+
61
+ in_namespace do
62
+ task :compile do
63
+ (cmd("cd", plan.absolute_path) & cmd("rake", "--rakefile", plan_rakefile.absolute_path, "construct:compile")).must_succeed!
64
+ end
65
+
66
+ file_create synced.absolute_path do |dir|
67
+ cmd("mkdir", "-p", dir.name).must_succeed! #ok
68
+ end
69
+
70
+ #This looks absurd, but otherwise we need to make sure that no compile
71
+ #task creates a new file it doesn't need. `bundle standalone` already
72
+ #does, so...
73
+ task :rsync_artifacts => [synced.absolute_path, :compile] do
74
+ from_dir = plan.absolute_path
75
+ from_dir += "/" unless from_dir =~ %r"/$"
76
+
77
+ to_dir = synced.absolute_path
78
+ to_dir += "/" unless to_dir =~ %r"/$"
79
+
80
+ cmd("rsync", "-v", "-rlpgo", "--checksum", from_dir, to_dir).must_succeed!
81
+ end
82
+
83
+ synced_files.each do |path|
84
+ file path => :rsync_artifacts
85
+ end
86
+
87
+ @pack = ::LogicalConstruct::PackTarball.new do |pack|
88
+ copy_settings_to(pack)
89
+ pack.source_files = synced_files
90
+ pack.unpacked_dir.absolute_path = synced.absolute_path
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
@@ -23,7 +23,7 @@ module LogicalConstruct
23
23
  in_namespace do
24
24
  desc "List the search paths for files used by ground control"
25
25
  task :search_paths do
26
- p valise
26
+ p valise #ok
27
27
  end
28
28
  end
29
29
  end