logical-construct 0.0.1.localtesting → 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/logical-construct/ground-control/core.rb +0 -1
- data/lib/logical-construct/ground-control/provision.rb +146 -29
- data/lib/logical-construct/ground-control/run-on-target.rb +4 -4
- data/lib/logical-construct/ground-control/setup.rb +5 -14
- data/lib/logical-construct/ground-control/setup/build-files.rb +31 -10
- data/lib/logical-construct/ground-control/setup/copy-files.rb +31 -19
- data/lib/logical-construct/ground-control/setup/create-construct-directory.rb +1 -0
- data/lib/logical-construct/ground-control/setup/install-init.rb +32 -0
- data/lib/logical-construct/resolving-task.rb +108 -5
- data/lib/logical-construct/satisfiable-task.rb +25 -2
- data/lib/logical-construct/target/chef-solo.rb +12 -15
- data/lib/logical-construct/target/platforms/default/chef-config.rb +57 -12
- data/lib/logical-construct/target/platforms/default/resolve-configuration.rb +22 -3
- data/lib/logical-construct/target/provision.rb +10 -0
- data/lib/logical-construct/target/sinatra-resolver.rb +16 -19
- data/lib/logical-construct/testing/resolve-configuration.rb +8 -0
- data/lib/templates/Gemfile.erb +3 -1
- data/lib/templates/chef.rb.erb +6 -1
- data/lib/templates/construct.init.d.erb +15 -0
- data/lib/templates/resolver/index.html.erb +11 -2
- data/lib/templates/resolver/task-file-form.html.erb +6 -0
- data/spec/ground-control/smoke-test.rb +23 -0
- data/spec/resolution.rb +147 -0
- data/spec/target/chef-config.rb +3 -0
- data/spec/target/chef-solo.rb +8 -0
- data/spec/target/smoke-test.rb +45 -0
- metadata +44 -14
- data/lib/logical-construct/ground-control/setup/bundle-setup.rb +0 -36
- data/lib/logical-construct/ground-control/setup/ensure-env.rb +0 -15
@@ -12,15 +12,25 @@ module LogicalConstruct
|
|
12
12
|
:config_path => nil
|
13
13
|
)
|
14
14
|
setting :valise
|
15
|
+
setting :construct_bin_path
|
15
16
|
setting :search_paths, [rel_dir(__FILE__)]
|
16
17
|
|
17
18
|
def resolve_configuration
|
18
19
|
self.valise = default_valise(search_paths)
|
20
|
+
self.construct_bin_path ||= File::expand_path("bin", construct_dir)
|
21
|
+
self.construct_bin_path = File::absolute_path(construct_bin_path)
|
19
22
|
super
|
20
23
|
end
|
21
24
|
|
22
25
|
def define
|
23
26
|
task_spine(:preflight, :approve_host, :build_configs, :provision)
|
27
|
+
|
28
|
+
task :bundled_path do
|
29
|
+
unless ENV['PATH'] =~ /(?:^|:)#{construct_bin_path}(?::|$)/
|
30
|
+
ENV['PATH'] = "#{construct_bin_path}:#{ENV['PATH']}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
task :preflight => :bundled_path
|
24
34
|
end
|
25
35
|
end
|
26
36
|
end
|
@@ -7,9 +7,7 @@ module LogicalConstruct
|
|
7
7
|
class SinatraResolver < ResolvingTask
|
8
8
|
include Mattock::TemplateHost
|
9
9
|
|
10
|
-
|
11
|
-
"/" + task.name.gsub(":", "/")
|
12
|
-
end
|
10
|
+
include ResolutionProtocol
|
13
11
|
|
14
12
|
def build_collector(resolver, prereqs)
|
15
13
|
klass = Class.new(Sinatra::Application) do
|
@@ -24,27 +22,26 @@ module LogicalConstruct
|
|
24
22
|
end
|
25
23
|
|
26
24
|
prereqs.each do |task|
|
27
|
-
path = resolver.web_path(task)
|
25
|
+
path = resolver.web_path(task.name)
|
28
26
|
|
29
27
|
get path do
|
30
|
-
|
31
|
-
|
28
|
+
if task.prefer_file?
|
29
|
+
resolver.render('resolver/task-file-form.html.erb') do |locals|
|
30
|
+
locals[:task_path] = path
|
31
|
+
end
|
32
|
+
else
|
33
|
+
resolver.render('resolver/task-form.html.erb') do |locals|
|
34
|
+
locals[:task_path] = path
|
35
|
+
end
|
32
36
|
end
|
33
37
|
end
|
34
38
|
|
35
39
|
post path do
|
36
|
-
|
37
|
-
|
38
|
-
redirect to("/")
|
40
|
+
if request.content_type =~ %r{multipart/form-data}
|
41
|
+
task.receive(request.params["data"][:tempfile])
|
39
42
|
else
|
40
|
-
|
41
|
-
quit!
|
43
|
+
task.receive(request.params["data"])
|
42
44
|
end
|
43
|
-
end
|
44
|
-
|
45
|
-
put path do
|
46
|
-
request.body.rewind
|
47
|
-
task.fulfill(request.body.read)
|
48
45
|
if resolver.needed?
|
49
46
|
redirect to("/")
|
50
47
|
else
|
@@ -67,14 +64,14 @@ module LogicalConstruct
|
|
67
64
|
|
68
65
|
setting :bind, "0.0.0.0"
|
69
66
|
setting :port, 51076 #JDL's birthday
|
70
|
-
setting :valise
|
67
|
+
setting :valise
|
71
68
|
|
72
69
|
def action
|
73
70
|
puts
|
74
71
|
puts "STARTING WEB LISTENER TO RESOLVE PREREQUISITES"
|
75
72
|
puts
|
76
73
|
|
77
|
-
collector = build_collector(self,
|
74
|
+
collector = build_collector(self, satisfiables)
|
78
75
|
handler = collector.rack_handler
|
79
76
|
handler_name = handler.name
|
80
77
|
|
@@ -96,7 +93,7 @@ module LogicalConstruct
|
|
96
93
|
|
97
94
|
rescue Errno::EADDRINUSE => e
|
98
95
|
puts "Port #{port} in use!"
|
99
|
-
|
96
|
+
raise
|
100
97
|
end
|
101
98
|
end
|
102
99
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'mattock/tasklib'
|
2
2
|
require 'logical-construct/testing/resolving-task'
|
3
|
+
require 'logical-construct/resolving-task'
|
3
4
|
|
4
5
|
module LogicalConstruct
|
5
6
|
module Testing
|
@@ -9,6 +10,11 @@ module LogicalConstruct
|
|
9
10
|
setting :resolutions, {}
|
10
11
|
|
11
12
|
def default_configuration(provision)
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_file(path)
|
17
|
+
#that's nice, dear
|
12
18
|
end
|
13
19
|
|
14
20
|
def define
|
@@ -17,6 +23,8 @@ module LogicalConstruct
|
|
17
23
|
task.task_name = "resolve"
|
18
24
|
copy_settings_to(task)
|
19
25
|
end
|
26
|
+
|
27
|
+
LogicalConstruct::Manifest.new()
|
20
28
|
end
|
21
29
|
end
|
22
30
|
end
|
data/lib/templates/Gemfile.erb
CHANGED
data/lib/templates/chef.rb.erb
CHANGED
@@ -1,4 +1,9 @@
|
|
1
1
|
file_cache_path "<%= file_cache_path %>"
|
2
2
|
cookbook_path "<%= cookbook_path %>"
|
3
3
|
json_attribs "<%= json_attribs %>"
|
4
|
-
<% unless role_path.nil? %>
|
4
|
+
<% unless role_path.nil? %>
|
5
|
+
role_path "<%= role_path %>"
|
6
|
+
<% end %>
|
7
|
+
<% unless data_bags_path.nil? %>
|
8
|
+
data_bag_path "<%= data_bags_path %>"
|
9
|
+
<% end %>
|
@@ -1,8 +1,17 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head profile="http://lrdesign/document-profiles/logical-construct/resolution">
|
4
|
+
<meta charset="UTF-8" />
|
5
|
+
<title>Logical Construct Provisioning Data Resolution</title>
|
6
|
+
</head>
|
7
|
+
<body>
|
1
8
|
<p>The following conditions must be satisfied in order to provision this machine:</p>
|
2
9
|
<ul>
|
3
|
-
<%
|
10
|
+
<% unsatisfied.each do |task| %>
|
4
11
|
<li>
|
5
|
-
|
12
|
+
<a rel="requirement" href="<%= web_path(task.name)%>"><%= task.name %></a>
|
6
13
|
</li>
|
7
14
|
<% end %>
|
8
15
|
</ul>
|
16
|
+
</body>
|
17
|
+
</html>
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'logical-construct/ground-control'
|
2
|
+
|
3
|
+
module LogicalConstruct::GroundControl
|
4
|
+
describe "An example Rakefile" do
|
5
|
+
|
6
|
+
before :each do
|
7
|
+
extend LogicalConstruct::GroundControl
|
8
|
+
core = Core.new
|
9
|
+
|
10
|
+
setup = Setup.new(core)
|
11
|
+
setup.default_subtasks
|
12
|
+
|
13
|
+
provision = Provision.new(core) do |prov|
|
14
|
+
prov.marshalling_path = "marshall"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should load without error" do
|
19
|
+
true.should be_true #oo be doo be doo
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
end
|
data/spec/resolution.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
require 'mattock/testing/rake-example-group'
|
2
|
+
require 'mattock/template-host'
|
3
|
+
require 'timeout'
|
4
|
+
|
5
|
+
require 'logical-construct/target/sinatra-resolver'
|
6
|
+
require 'logical-construct/ground-control/provision'
|
7
|
+
require 'logical-construct/satisfiable-task'
|
8
|
+
|
9
|
+
describe LogicalConstruct::SinatraResolver, :slow => true do
|
10
|
+
include Mattock::RakeExampleGroup
|
11
|
+
|
12
|
+
let :file_target_path do
|
13
|
+
"target-file"
|
14
|
+
end
|
15
|
+
|
16
|
+
let :string_target_path do
|
17
|
+
"target-string"
|
18
|
+
end
|
19
|
+
|
20
|
+
let :resolver_pipe do
|
21
|
+
IO.pipe
|
22
|
+
end
|
23
|
+
|
24
|
+
let! :resolver_write do
|
25
|
+
resolver_pipe[1]
|
26
|
+
end
|
27
|
+
|
28
|
+
let :resolver_read do
|
29
|
+
resolver_pipe[0]
|
30
|
+
end
|
31
|
+
|
32
|
+
let :resolver_buffer do
|
33
|
+
""
|
34
|
+
end
|
35
|
+
|
36
|
+
let :resolver_process do
|
37
|
+
Process.fork do
|
38
|
+
extend Mattock::ValiseManager
|
39
|
+
file = LogicalConstruct::SatisfiableFileTask.new(:file_target) do |task|
|
40
|
+
task.target_path = file_target_path
|
41
|
+
end
|
42
|
+
|
43
|
+
string = LogicalConstruct::SatisfiableFileTask.new(:string_target) do |task|
|
44
|
+
task.target_path = string_target_path
|
45
|
+
end
|
46
|
+
|
47
|
+
LogicalConstruct::SinatraResolver.new(file, string, :resolver) do |task|
|
48
|
+
task.valise = default_valise(File::expand_path("../../lib", __FILE__))
|
49
|
+
task.bind = "127.0.0.1"
|
50
|
+
end
|
51
|
+
|
52
|
+
$stdout.reopen(resolver_write)
|
53
|
+
$stderr.reopen(resolver_write)
|
54
|
+
|
55
|
+
rake[:file_target].invoke
|
56
|
+
rake[:string_target].invoke
|
57
|
+
end.tap do |pid|
|
58
|
+
at_exit do
|
59
|
+
kill("KILL", pid) rescue nil
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
before :each do
|
66
|
+
resolver_process
|
67
|
+
|
68
|
+
begin
|
69
|
+
resolver_buffer << resolver_read.read_nonblock(4096)
|
70
|
+
rescue IO::WaitReadable => err
|
71
|
+
sleep 0.1
|
72
|
+
retry
|
73
|
+
end until /Listening on/ =~ resolver_buffer
|
74
|
+
end
|
75
|
+
|
76
|
+
after do
|
77
|
+
begin
|
78
|
+
Process.kill("INT", resolver_process)
|
79
|
+
Process.wait(resolver_process)
|
80
|
+
rescue => ex
|
81
|
+
warn ex
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should block when unresolved" do
|
86
|
+
expect do
|
87
|
+
Process.wait(resolver_process, Process::WNOHANG)
|
88
|
+
end.not_to raise_error
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should not have a file already" do
|
92
|
+
File::file?(file_target_path).should be_false
|
93
|
+
end
|
94
|
+
|
95
|
+
describe LogicalConstruct::GroundControl::Provision::WebConfigure do
|
96
|
+
let :file_content do
|
97
|
+
"Some test file content"
|
98
|
+
end
|
99
|
+
|
100
|
+
let :string_content do
|
101
|
+
"Some string content"
|
102
|
+
end
|
103
|
+
|
104
|
+
let :file do
|
105
|
+
require 'stringio'
|
106
|
+
StringIO.new(file_content).tap do |str|
|
107
|
+
def str.path
|
108
|
+
"fake_file.txt"
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
let! :web_configure do
|
114
|
+
LogicalConstruct::GroundControl::Provision::WebConfigure.new(:web_configure) do |task|
|
115
|
+
task.target_address = "127.0.0.1"
|
116
|
+
task.resolutions["file_target"] = proc{ file }
|
117
|
+
task.resolutions["string_target"] = string_content
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
before :each do
|
122
|
+
rake[:web_configure].invoke
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should complete resolver thread" do
|
126
|
+
expect do
|
127
|
+
begin
|
128
|
+
Timeout::timeout(10) do
|
129
|
+
Process.wait(resolver_process)
|
130
|
+
end
|
131
|
+
rescue Object => ex
|
132
|
+
resolver_buffer << resolver.read_nonblock(10000) rescue ""
|
133
|
+
p resolver_buffer
|
134
|
+
raise
|
135
|
+
end
|
136
|
+
end.not_to raise_error
|
137
|
+
end
|
138
|
+
|
139
|
+
it "should produce the file" do
|
140
|
+
File::read(file_target_path).should == file_content
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should produce the string" do
|
144
|
+
File::read(string_target_path).should == string_content
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
data/spec/target/chef-config.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require 'logical-construct/target/platforms'
|
2
2
|
require 'mattock/testing/rake-example-group'
|
3
|
+
require 'mattock/testing/mock-command-line'
|
3
4
|
|
4
5
|
describe LogicalConstruct::VirtualBox::ChefConfig do
|
5
6
|
include Mattock::RakeExampleGroup
|
@@ -41,6 +42,8 @@ describe LogicalConstruct::VirtualBox::ChefConfig do
|
|
41
42
|
|
42
43
|
describe "invoked" do
|
43
44
|
before :each do
|
45
|
+
expect_command /tar/, 0
|
46
|
+
expect_command /tar/, 0
|
44
47
|
expect_command /tar/, 0
|
45
48
|
rake[File::join(sandbox["chef-dir"].path, "chef-solo.rb")].invoke
|
46
49
|
end
|
data/spec/target/chef-solo.rb
CHANGED
@@ -36,9 +36,17 @@ describe LogicalConstruct::ChefSolo do
|
|
36
36
|
describe "invoked" do
|
37
37
|
include Mattock::CommandLineExampleGroup
|
38
38
|
|
39
|
+
it "should have the bundle path in the PATH" do
|
40
|
+
expect_some_commands
|
41
|
+
rake["chef_solo:run"].invoke
|
42
|
+
ENV['PATH'].should =~ %r{/var/logical-construct/bin}
|
43
|
+
end
|
44
|
+
|
39
45
|
it "should run chef-solo" do
|
40
46
|
Rake.verbose(true)
|
41
47
|
expect_command /tar/, 0
|
48
|
+
expect_command /tar/, 0
|
49
|
+
expect_command /tar/, 0
|
42
50
|
expect_command /chef-solo/, 0
|
43
51
|
|
44
52
|
rake["chef_solo:run"].invoke
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'logical-construct/target'
|
2
|
+
|
3
|
+
|
4
|
+
module TestAWS
|
5
|
+
include LogicalConstruct
|
6
|
+
include LogicalConstruct::Platform("AWS")
|
7
|
+
|
8
|
+
describe "VirtualBox platform" do
|
9
|
+
before :each do
|
10
|
+
provision = Provision.new
|
11
|
+
|
12
|
+
provision.in_namespace do
|
13
|
+
resolution = ResolveConfiguration.new(provision)
|
14
|
+
chef_config = ChefConfig.new(provision, resolution)
|
15
|
+
chef_solo = ChefSolo.new(chef_config)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should not crash" do
|
20
|
+
true.should be_true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module TestVirtualBox
|
26
|
+
include LogicalConstruct
|
27
|
+
include LogicalConstruct::Platform("VirtualBox")
|
28
|
+
|
29
|
+
describe "VirtualBox platform" do
|
30
|
+
before :each do
|
31
|
+
provision = Provision.new
|
32
|
+
|
33
|
+
provision.in_namespace do
|
34
|
+
resolution = ResolveConfiguration.new(provision)
|
35
|
+
chef_config = ChefConfig.new(provision, resolution)
|
36
|
+
chef_solo = ChefSolo.new(chef_config)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should not crash" do
|
41
|
+
true.should be_true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|