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
@@ -1,93 +0,0 @@
1
- require 'mattock'
2
- require 'mattock/bundle-command-task'
3
-
4
- module LogicalConstruct
5
- class ConfigBuilder < Mattock::TaskLib
6
- include Mattock::TemplateHost
7
- include Mattock::DeferredDefinition
8
- Mattock::DeferredDefinition.add_settings(self)
9
-
10
- setting(:source_path, nil)
11
- setting(:target_path, nil)
12
-
13
- setting(:valise)
14
- setting(:target_dir)
15
-
16
- setting(:base_name)
17
- setting(:extra, {})
18
-
19
- def default_configuration(host)
20
- super
21
- host.copy_settings_to(self)
22
- end
23
-
24
- def resolve_configuration
25
- self.target_path ||= fail_unless_set(:target_dir) && File::join(target_dir, base_name)
26
- self.source_path ||= fail_unless_set(:base_name) && "#{base_name}.erb"
27
- super
28
- end
29
-
30
- def define
31
- task base_name => [target_dir, valise.find("templates/" + source_path).full_path, Rake.application.rakefile] do
32
- finalize_configuration
33
- File::open(target_path, "w") do |file|
34
- file.write render(source_path)
35
- end
36
- end
37
- task base_name => target_dir
38
- task :local_setup => target_path
39
- end
40
- end
41
-
42
- class BuildFiles < Mattock::TaskLib
43
- include Mattock::CommandLineDSL
44
-
45
- default_namespace :build_files
46
-
47
- setting(:target_dir, "target_configs")
48
- required_fields :valise, :construct_dir, :platform
49
-
50
- def default_configuration(parent)
51
- super
52
- self.valise = parent.valise
53
- self.construct_dir = parent.construct_dir
54
- self.platform = parent.proxy_value.platform
55
- end
56
-
57
- def define
58
- rakefile = nil
59
- initd = nil
60
- in_namespace do
61
- directory target_dir
62
-
63
- gemfile = ConfigBuilder.new(self) do |task|
64
- task.base_name = "Gemfile"
65
- end
66
-
67
- Mattock::BundleCommandTask.new(:standalone => gemfile.target_path) do |bundle_build|
68
- bundle_build.command = (
69
- cmd("cd", target_dir) &
70
- cmd("bundle", "install"){|bundler|
71
- bundler.options << "--standalone"
72
- bundler.options << "--binstubs=bin"
73
- })
74
- end
75
-
76
- rakefile = ConfigBuilder.new(self) do |task|
77
- task.base_name = "Rakefile"
78
- end
79
-
80
- initd = ConfigBuilder.new(self) do |task|
81
- task.base_name = "construct.init.d"
82
- task.extra[:construct_dir] = construct_dir
83
- task.runtime_definition do
84
- task.extra[:platform] = platform
85
- end
86
- end
87
- end
88
- task root_task => [rakefile.target_path] + in_namespace(:standalone)
89
- task root_task => [initd.target_path] + in_namespace(:standalone)
90
- task :local_setup => root_task
91
- end
92
- end
93
- end
@@ -1,22 +0,0 @@
1
- require 'logical-construct/ground-control/run-on-target'
2
-
3
- module LogicalConstruct
4
- class CreateConstructDirectory < RunOnTarget
5
- default_namespace :construct_directory
6
-
7
- setting(:construct_dir)
8
-
9
- def default_configuration(setup)
10
- self.construct_dir = setup.construct_dir
11
- self.remote_server = setup.proxy_value.remote_server
12
- super
13
- end
14
-
15
- def define
16
- remote_task(:create) do |task|
17
- task.command = cmd "mkdir", "-p", construct_dir
18
- end
19
- task :remote_groundwork => self[:create]
20
- end
21
- end
22
- end
@@ -1,32 +0,0 @@
1
- require 'mattock'
2
- require 'logical-construct/ground-control/run-on-target'
3
-
4
- module LogicalConstruct
5
- module GroundControl
6
- class InstallInit < RunOnTarget
7
- required_fields :source_path, :target_path
8
- setting :construct_dir
9
- setting :service_name, "logical-construct"
10
- setting :initd_path, "/etc/init.d"
11
-
12
- def default_configuration(setup)
13
- super
14
- setup.copy_settings_to(self)
15
- end
16
-
17
- def resolve_configuration
18
- super
19
- self.source_path ||= File::join(construct_dir, "construct.init.d")
20
- self.target_path ||= File::join(initd_path, service_name)
21
- end
22
-
23
- def define
24
- remote_task(:install_init) do |task|
25
- task.command = cmd("install", "-T", source_path, target_path) &
26
- ["rc-update", "add", service_name, "default"]
27
- end
28
- bracket_task(:remote_config, :install_init, :remote_setup)
29
- end
30
- end
31
- end
32
- end
@@ -1,141 +0,0 @@
1
- require 'rake/task'
2
- require 'mattock/task'
3
- require 'logical-construct/satisfiable-task'
4
-
5
- module LogicalConstruct
6
- #Ensures that all it's deps are satisfied before proceeding - the action for
7
- #ResolvingTasks is all about satisfying deps.
8
- #
9
- #Key is how Rake invokes tasks:
10
- #Task runner calls Task#invoke
11
- #Which is "setup args" and #invoke_with_call_chain
12
- #which is
13
- # return if @already_invoked
14
- # and #invoke_prerequisites
15
- # which is prereqs.each{|pr| pr.invoke_with_call_chain }
16
- # and #execute if needed
17
- #
18
- #So, of note: you'll only get invoked once, ever
19
- #You'll only be executed if #needed?
20
- #Deps will get invoked (ish) even if not #needed?
21
- module SatisfiableManager
22
- def default_configuration(*configurables)
23
- super
24
- self.satisfiables = configurables.find_all do |conf|
25
- conf.is_a? SatisfiableTask
26
- end.map{|sat| sat.rake_task}
27
- end
28
-
29
- def define
30
- super
31
- satisfiables.each do |sat|
32
- sat.enhance([rake_task.name])
33
- end
34
- end
35
-
36
- def add_satisfiable(task)
37
- task = task.rake_task if task.respond_to? :rake_task
38
- satisfiables << task
39
- task.enhance([rake_task.name])
40
- end
41
- end
42
-
43
- require 'yaml'
44
- require 'digest'
45
- module ResolutionProtocol
46
- def digest
47
- @digest ||= Digest::SHA2.new
48
- end
49
-
50
- def file_checksum(path)
51
- generate_checksum(File::read(path))
52
- end
53
-
54
- def generate_checksum(data)
55
- digest.reset
56
- digest << data
57
- digest.hexdigest
58
- end
59
-
60
- def web_path(task_name)
61
- "/" + task_name.gsub(":", "/")
62
- end
63
- end
64
-
65
- class ResolvingTask < Rake::Task
66
- include Mattock::TaskMixin
67
- include SatisfiableManager
68
- setting :satisfiables, []
69
-
70
- def needed?
71
- !unsatisfied.empty?
72
- end
73
-
74
- def unsatisfied
75
- satisfiables.find_all{|task| task.needed?}
76
- end
77
-
78
- def execute(args=nil)
79
- super
80
- if needed?
81
- raise "Task #{name} failed to satisfy: #{unsatisfied.inspect}"
82
- end
83
- end
84
- end
85
-
86
- class Manifest < SatisfiableTask
87
- include SatisfiableManager
88
- include ResolutionProtocol
89
-
90
- setting :satisfiables, []
91
- nil_field :manifest
92
-
93
- default_taskname "Manifest"
94
-
95
- def invalid_checksum(checksum, path)
96
- return false unless File::exists?(path)
97
- return true if checksum.nil? or checksum.empty?
98
- return checksum != file_checksum(path)
99
- end
100
-
101
- def needed?
102
- manifest.nil?
103
- end
104
-
105
- def fulfill(data)
106
- self.manifest = YAML::load(data)
107
- satisfiables.each do |sat|
108
- path = sat.target_path
109
- checksum = manifest[sat.name]
110
- if invalid_checksum(checksum, path)
111
- File::rename(path, path + ".invalid")
112
- end
113
- end
114
- end
115
- end
116
-
117
- class GenerateManifest < Mattock::Task
118
- include ResolutionProtocol
119
- setting :hash, {}
120
- setting :resolutions
121
- setting :receiving_name
122
-
123
- def default_configuration(resolution_host)
124
- super
125
- self.resolutions = resolution_host.resolutions
126
- end
127
-
128
- def data_checksum(path, data)
129
- hash[path] = generate_checksum(data)
130
- end
131
-
132
- def action
133
- resolutions.each_pair do |destination, data|
134
- data = data.call if data.respond_to? :call
135
- data = data.read if data.respond_to? :read
136
- hash[destination] = generate_checksum(data)
137
- end
138
- resolutions[receiving_name] = YAML::dump(hash)
139
- end
140
- end
141
- end
@@ -1,87 +0,0 @@
1
- require 'mattock/task'
2
-
3
- module LogicalConstruct
4
- #This task won't kill the run if it fails - the assumption is that there's a
5
- #ResolvingTask that depends on this task to make it work.
6
- #
7
- #Based on my reasoning about Rake (c.f. ResolvingTask):
8
- # Each ST should have a configured #needed? that checks it's responsibility
9
- # Execute needs to catch errors
10
- class SatisfiableTask < Rake::Task
11
- include Mattock::TaskMixin
12
-
13
- def execute(args=nil)
14
- super
15
- if application.options.trace and needed?
16
- $stderr.puts "** Unsatisfied: #{name}"
17
- end
18
- rescue Object => ex
19
- warn "#{ex.class}: #{ex.message} while performing #{name}"
20
- #Swallowed
21
- end
22
-
23
- def prefer_file?
24
- false
25
- end
26
-
27
- def receive(data)
28
- return unless needed?
29
- fulfill(data)
30
- if data.respond_to? :path
31
- fulfill_file(data)
32
- elsif data.respond_to? :read
33
- fulfill(data.read)
34
- else
35
- fulfill(data.to_s)
36
- end
37
- end
38
-
39
- def receive_file(file)
40
- fulfill(file.read)
41
- end
42
-
43
- def fulfill(string)
44
- end
45
-
46
- def needed?
47
- return !criteria(self)
48
- end
49
-
50
- def criteria(me)
51
- end
52
- end
53
-
54
- class SatisfiableFileTask < SatisfiableTask
55
- setting :target_path
56
-
57
- def prefer_file?
58
- true
59
- end
60
-
61
- def criteria(task)
62
- File::exists?(target_path)
63
- end
64
-
65
- def fulfill_file(file)
66
- FileUtils::move(file.path, target_path)
67
- end
68
-
69
- def fulfill(data)
70
- File::open(target_path, "w") do |file|
71
- file.write(data)
72
- end
73
- end
74
- end
75
-
76
- class SatisfiableEnvTask < SatisfiableTask
77
- setting :target_name
78
-
79
- def criteria(task)
80
- ENV.has_key?(target_name)
81
- end
82
-
83
- def fulfill(string)
84
- ENV[target_name] = string
85
- end
86
- end
87
- end
@@ -1,4 +0,0 @@
1
- require 'logical-construct/target/platforms'
2
- require 'logical-construct/target/provision'
3
- require 'logical-construct/target/chef-solo'
4
- require 'logical-construct/target/unpack-cookbook'
@@ -1,37 +0,0 @@
1
- require 'mattock/tasklib'
2
-
3
- module LogicalConstruct
4
- class ChefSolo < Mattock::TaskLib
5
- default_namespace :chef_solo
6
-
7
- settings(
8
- :chef_solo_bin => "chef-solo",
9
- :daemonize => nil,
10
- :user => nil,
11
- :group => nil,
12
- :node_name => nil
13
- )
14
-
15
- setting :config_file
16
-
17
- def default_configuration(chef_config)
18
- super
19
- self.config_file = chef_config.solo_rb
20
- end
21
-
22
- def define
23
- in_namespace do
24
- Mattock::CommandTask.new(:run) do |task|
25
- task.command = Mattock::CommandLine.new(chef_solo_bin) do |cmd|
26
- cmd.options << "--config #{config_file}" unless config_file.nil?
27
- cmd.options << "--daemonize" if daemonize
28
- cmd.options << "--user #{user}" if user
29
- cmd.options << "--group #{group}" if group
30
- cmd.options << "--node_name #{node_name}" if node_name
31
- end
32
- end
33
- end
34
- bracket_task(:build_configs, :run, :provision)
35
- end
36
- end
37
- end
@@ -1,51 +0,0 @@
1
- module LogicalConstruct
2
- def self.platforms
3
- @platforms ||= {}
4
- end
5
-
6
- def self.register_platform(mod)
7
- name = mod.name.split('::').last
8
- platforms[name] = mod
9
- end
10
-
11
- def self.require_platform_files(platform, mod = nil)
12
- [
13
- ['volume', :Volume],
14
- ['chef-config', :ChefConfig],
15
- ['resolve-configuration', :ResolveConfiguration],
16
- ].each do |file, classname|
17
- begin
18
- require File::join('logical-construct', 'target', 'platforms', platform, file)
19
- rescue LoadError
20
- raise if mod.nil?
21
- klass = Class.new(LogicalConstruct::Default.const_get(classname))
22
- mod.const_set(classname, klass)
23
- end
24
- end
25
- end
26
-
27
- def self.Platform(explicit = nil)
28
- name = explicit || $DEPLOYMENT_PLATFORM || ENV['LOGCON_DEPLOYMENT_PLATFORM']
29
- return platforms.fetch(name)
30
- rescue KeyError
31
- puts "Cannot find platform specified:"
32
- puts " explicit argument: #{explicit.inspect}"
33
- puts " $DEPLOYMENT_PLATFORM: #{$DEPLOYMENT_PLATFORM.inspect}"
34
- puts " ENV['LOGCON_DEPLOYMENT_PLATFORM']: #{ENV['LOGCON_DEPLOYMENT_PLATFORM'].inspect}"
35
- puts " available: #{platforms.keys.inspect}"
36
- puts
37
- raise
38
- end
39
-
40
- module PlatformSpecific
41
- def register_platform(name)
42
- LogicalConstruct.register_platform(self)
43
- LogicalConstruct.require_platform_files(name, self)
44
- end
45
- end
46
-
47
- require_platform_files('default')
48
- end
49
-
50
- require 'logical-construct/target/platforms/virtualbox'
51
- require 'logical-construct/target/platforms/aws'