whipped-cream 0.0.1pre1 → 0.0.1pre2
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/whipped-cream.rb +9 -8
- data/lib/whipped-cream/cli.rb +12 -1
- data/lib/whipped-cream/deployer.rb +85 -0
- data/lib/whipped-cream/server.rb +6 -4
- data/lib/whipped-cream/version.rb +1 -1
- data/spec/lib/whipped-cream/cli_spec.rb +31 -6
- data/spec/lib/whipped-cream/deployer_spec.rb +56 -0
- data/spec/lib/whipped-cream/server_spec.rb +17 -3
- data/whipped-cream.gemspec +2 -0
- metadata +36 -1
data/lib/whipped-cream.rb
CHANGED
@@ -1,8 +1,9 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
6
|
-
require
|
7
|
-
require
|
8
|
-
require
|
1
|
+
require 'whipped-cream/builder'
|
2
|
+
require 'whipped-cream/button'
|
3
|
+
require 'whipped-cream/cli'
|
4
|
+
require 'whipped-cream/deployer'
|
5
|
+
require 'whipped-cream/plugin'
|
6
|
+
require 'whipped-cream/runner'
|
7
|
+
require 'whipped-cream/sensor'
|
8
|
+
require 'whipped-cream/server'
|
9
|
+
require 'whipped-cream/version'
|
data/lib/whipped-cream/cli.rb
CHANGED
@@ -25,13 +25,24 @@ module WhippedCream
|
|
25
25
|
server.start
|
26
26
|
end
|
27
27
|
|
28
|
+
desc "deploy PLUGIN IP", "Deploy a plugin to a Pi"
|
29
|
+
def deploy(plugin_name, pi_address)
|
30
|
+
plugin_path = resolve_plugin(plugin_name)
|
31
|
+
|
32
|
+
deployer = Deployer.new(plugin_path, pi_address)
|
33
|
+
deployer.deploy
|
34
|
+
end
|
35
|
+
|
28
36
|
desc "start PLUGIN", "Start a plugin"
|
37
|
+
method_option :daemonize,
|
38
|
+
type: :boolean,
|
39
|
+
desc: "Run the server in the background"
|
29
40
|
def start(plugin_name)
|
30
41
|
plugin_path = resolve_plugin(plugin_name)
|
31
42
|
|
32
43
|
plugin = Plugin.from_file(plugin_path)
|
33
44
|
server = Server.new(plugin)
|
34
|
-
server.start
|
45
|
+
server.start(options)
|
35
46
|
end
|
36
47
|
|
37
48
|
no_tasks do
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'net/scp'
|
2
|
+
require 'net/ssh'
|
3
|
+
|
4
|
+
module WhippedCream
|
5
|
+
# Prepares a Pi for deployment, and deploys a plugin
|
6
|
+
class Deployer
|
7
|
+
attr_reader :plugin_filename, :pi_address
|
8
|
+
|
9
|
+
def initialize(plugin_filename, pi_address)
|
10
|
+
@plugin_filename = plugin_filename
|
11
|
+
@pi_address = pi_address
|
12
|
+
end
|
13
|
+
|
14
|
+
def deploy
|
15
|
+
bootstrap
|
16
|
+
copy_plugin
|
17
|
+
kill_all_plugins
|
18
|
+
run_plugin
|
19
|
+
end
|
20
|
+
|
21
|
+
def scp
|
22
|
+
@scp ||= Net::SCP.start(*connection_arguments)
|
23
|
+
end
|
24
|
+
|
25
|
+
def ssh
|
26
|
+
@ssh ||= Net::SSH.start(*connection_arguments)
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
def connection_arguments
|
32
|
+
[pi_address, 'pi', { password: 'raspberry' }]
|
33
|
+
end
|
34
|
+
|
35
|
+
def bootstrap
|
36
|
+
ssh_exec <<-SCRIPT
|
37
|
+
which ruby ||
|
38
|
+
time sudo apt-get install ruby -y
|
39
|
+
|
40
|
+
which runit ||
|
41
|
+
time sudo apt-get install runit -y
|
42
|
+
|
43
|
+
which whipped-cream ||
|
44
|
+
time sudo gem install whipped-cream --no-ri --no-rdoc --pre
|
45
|
+
|
46
|
+
mkdir -p ~/whipped-cream/
|
47
|
+
SCRIPT
|
48
|
+
end
|
49
|
+
|
50
|
+
def copy_plugin
|
51
|
+
scp_copy plugin_filename, "whipped-cream/#{plugin_filename}"
|
52
|
+
end
|
53
|
+
|
54
|
+
def kill_all_plugins
|
55
|
+
ssh_exec 'sudo pkill -9 -f whipped-cream'
|
56
|
+
end
|
57
|
+
|
58
|
+
def run_plugin
|
59
|
+
ssh_exec <<-SCRIPT
|
60
|
+
cd ~/whipped-cream
|
61
|
+
sudo whipped-cream start demo.rb
|
62
|
+
SCRIPT
|
63
|
+
end
|
64
|
+
|
65
|
+
def scp_copy(local, remote)
|
66
|
+
scp.upload! local, remote
|
67
|
+
end
|
68
|
+
|
69
|
+
def ssh_exec(command)
|
70
|
+
command = command.prepend("set -ex\n")
|
71
|
+
|
72
|
+
ssh.open_channel do |channel|
|
73
|
+
channel.exec command do |process|
|
74
|
+
process.on_data do |_, data|
|
75
|
+
$stdout.print data
|
76
|
+
end
|
77
|
+
|
78
|
+
process.on_extended_data do |_, _, data|
|
79
|
+
$stderr.print data
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end.wait
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/whipped-cream/server.rb
CHANGED
@@ -9,11 +9,11 @@ module WhippedCream
|
|
9
9
|
@plugin = plugin
|
10
10
|
end
|
11
11
|
|
12
|
-
def start
|
12
|
+
def start(options = {})
|
13
13
|
ensure_routes_built
|
14
14
|
ensure_runner_started
|
15
15
|
|
16
|
-
start_web
|
16
|
+
start_web(options)
|
17
17
|
end
|
18
18
|
|
19
19
|
def runner
|
@@ -38,8 +38,10 @@ module WhippedCream
|
|
38
38
|
@routes_built ||= build_routes || true
|
39
39
|
end
|
40
40
|
|
41
|
-
def start_web
|
42
|
-
|
41
|
+
def start_web(options = {})
|
42
|
+
options = options.merge({ app: web, port: port })
|
43
|
+
|
44
|
+
Rack::Server.start options
|
43
45
|
end
|
44
46
|
|
45
47
|
def build_routes
|
@@ -15,6 +15,7 @@ describe WhippedCream::CLI do
|
|
15
15
|
button "Open/Close", pin: 1
|
16
16
|
PLUGIN
|
17
17
|
}
|
18
|
+
let(:pi_address) { "192.168.0.123" }
|
18
19
|
let(:tmpdir) { Dir.mktmpdir }
|
19
20
|
|
20
21
|
before do
|
@@ -33,20 +34,44 @@ describe WhippedCream::CLI do
|
|
33
34
|
end
|
34
35
|
end
|
35
36
|
|
36
|
-
describe "#
|
37
|
-
it "
|
38
|
-
|
39
|
-
expect(cli).to receive(:help)
|
37
|
+
describe "#deploy" do
|
38
|
+
it "deploys a plugin to a Pi" do
|
39
|
+
deployer_double = double(WhippedCream::Deployer)
|
40
40
|
|
41
|
-
|
41
|
+
expect(WhippedCream::Deployer).to receive(:new) { deployer_double }
|
42
|
+
expect(deployer_double).to receive(:deploy)
|
43
|
+
|
44
|
+
cli.deploy(plugin_filename, pi_address)
|
42
45
|
end
|
43
46
|
end
|
44
47
|
|
45
48
|
describe "#start" do
|
49
|
+
let(:server_double) { double(WhippedCream::Server) }
|
50
|
+
|
46
51
|
it "starts a server for the plugin" do
|
47
|
-
expect(
|
52
|
+
expect(WhippedCream::Server).to receive(:new) { server_double }
|
53
|
+
expect(server_double).to receive(:start)
|
48
54
|
|
49
55
|
cli.start(plugin_filename)
|
50
56
|
end
|
57
|
+
|
58
|
+
context "with --daemonize" do
|
59
|
+
it "starts a server in the background" do
|
60
|
+
expect(WhippedCream::Server).to receive(:new) { server_double }
|
61
|
+
expect(server_double).to receive(:start).with(daemonize: true)
|
62
|
+
|
63
|
+
cli.options = { daemonize: true }
|
64
|
+
cli.start(plugin_filename)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "#usage" do
|
70
|
+
it "displays a banner and help" do
|
71
|
+
expect(cli).to receive(:puts).exactly(2).times
|
72
|
+
expect(cli).to receive(:help)
|
73
|
+
|
74
|
+
cli.usage
|
75
|
+
end
|
51
76
|
end
|
52
77
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe WhippedCream::Deployer do
|
4
|
+
subject { deployer }
|
5
|
+
let(:deployer) { described_class.new(plugin_filename, pi_address) }
|
6
|
+
|
7
|
+
let(:plugin_filename) { 'demo.rb' }
|
8
|
+
let(:pi_address) { '192.168.0.123' }
|
9
|
+
|
10
|
+
let(:net_ssh_double) {
|
11
|
+
double(Net::SSH, exec!: nil, open_channel: double(wait: nil))
|
12
|
+
}
|
13
|
+
|
14
|
+
before do
|
15
|
+
deployer.stub :scp_copy
|
16
|
+
deployer.stub :ssh_exec
|
17
|
+
end
|
18
|
+
|
19
|
+
its(:plugin_filename) { should eq(plugin_filename) }
|
20
|
+
its(:pi_address) { should eq(pi_address) }
|
21
|
+
|
22
|
+
describe "#scp" do
|
23
|
+
it "tries to connect with pi:raspberry" do
|
24
|
+
expect(Net::SCP).to receive(:start).with(
|
25
|
+
pi_address, 'pi', password: 'raspberry'
|
26
|
+
)
|
27
|
+
|
28
|
+
deployer.scp
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "#ssh" do
|
33
|
+
it "tries to connect with pi:raspberry" do
|
34
|
+
expect(Net::SSH).to receive(:start).with(
|
35
|
+
pi_address, 'pi', password: 'raspberry'
|
36
|
+
)
|
37
|
+
|
38
|
+
deployer.ssh
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "#deploy" do
|
43
|
+
subject(:deploy) { deployer.deploy }
|
44
|
+
|
45
|
+
it "bootstraps the Pi" do
|
46
|
+
expect(deployer).to receive(:bootstrap)
|
47
|
+
expect(deployer).to receive(:copy_plugin)
|
48
|
+
expect(deployer).to receive(:kill_all_plugins)
|
49
|
+
expect(deployer).to receive(:run_plugin)
|
50
|
+
|
51
|
+
deploy
|
52
|
+
end
|
53
|
+
|
54
|
+
# xit "prompts the user for a password on failure"
|
55
|
+
end
|
56
|
+
end
|
@@ -31,9 +31,23 @@ describe WhippedCream::Server do
|
|
31
31
|
).to be_true
|
32
32
|
end
|
33
33
|
|
34
|
-
|
35
|
-
|
34
|
+
describe "#start" do
|
35
|
+
it "starts a Rack server" do
|
36
|
+
expect(Rack::Server).to receive(:start).with(
|
37
|
+
app: WhippedCream::Server::Web, port: 8080
|
38
|
+
)
|
36
39
|
|
37
|
-
|
40
|
+
server.start
|
41
|
+
end
|
42
|
+
|
43
|
+
context "with daemonize: true" do
|
44
|
+
it "starts the Sinatra application" do
|
45
|
+
expect(Rack::Server).to receive(:start).with(
|
46
|
+
app: WhippedCream::Server::Web, port: 8080, daemonize: true
|
47
|
+
)
|
48
|
+
|
49
|
+
server.start(daemonize: true)
|
50
|
+
end
|
51
|
+
end
|
38
52
|
end
|
39
53
|
end
|
data/whipped-cream.gemspec
CHANGED
@@ -22,6 +22,8 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
spec.required_ruby_version = '>= 1.9.3'
|
24
24
|
|
25
|
+
spec.add_runtime_dependency 'net-scp'
|
26
|
+
spec.add_runtime_dependency 'net-ssh'
|
25
27
|
spec.add_runtime_dependency 'pi_piper'
|
26
28
|
spec.add_runtime_dependency 'sinatra'
|
27
29
|
spec.add_runtime_dependency 'thor'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: whipped-cream
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.1pre2
|
5
5
|
prerelease: 5
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -11,6 +11,38 @@ bindir: bin
|
|
11
11
|
cert_chain: []
|
12
12
|
date: 2013-10-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: net-scp
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: net-ssh
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
14
46
|
- !ruby/object:Gem::Dependency
|
15
47
|
name: pi_piper
|
16
48
|
requirement: !ruby/object:Gem::Requirement
|
@@ -165,6 +197,7 @@ files:
|
|
165
197
|
- lib/whipped-cream/button.rb
|
166
198
|
- lib/whipped-cream/cli.rb
|
167
199
|
- lib/whipped-cream/control.rb
|
200
|
+
- lib/whipped-cream/deployer.rb
|
168
201
|
- lib/whipped-cream/pi_piper.rb
|
169
202
|
- lib/whipped-cream/plugin.rb
|
170
203
|
- lib/whipped-cream/public/assets/application.css
|
@@ -179,6 +212,7 @@ files:
|
|
179
212
|
- spec/lib/whipped-cream/builder_spec.rb
|
180
213
|
- spec/lib/whipped-cream/button_spec.rb
|
181
214
|
- spec/lib/whipped-cream/cli_spec.rb
|
215
|
+
- spec/lib/whipped-cream/deployer_spec.rb
|
182
216
|
- spec/lib/whipped-cream/plugin_spec.rb
|
183
217
|
- spec/lib/whipped-cream/runner_spec.rb
|
184
218
|
- spec/lib/whipped-cream/sensor_spec.rb
|
@@ -218,6 +252,7 @@ test_files:
|
|
218
252
|
- spec/lib/whipped-cream/builder_spec.rb
|
219
253
|
- spec/lib/whipped-cream/button_spec.rb
|
220
254
|
- spec/lib/whipped-cream/cli_spec.rb
|
255
|
+
- spec/lib/whipped-cream/deployer_spec.rb
|
221
256
|
- spec/lib/whipped-cream/plugin_spec.rb
|
222
257
|
- spec/lib/whipped-cream/runner_spec.rb
|
223
258
|
- spec/lib/whipped-cream/sensor_spec.rb
|