logical-construct 0.0.1.localtesting → 0.0.1
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.
- 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
|