logical-construct 0.0.5 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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