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
@@ -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'