whipped-cream 0.0.1pre1 → 0.0.1pre2

Sign up to get free protection for your applications and to get access to all the features.
data/lib/whipped-cream.rb CHANGED
@@ -1,8 +1,9 @@
1
- require "whipped-cream/builder"
2
- require "whipped-cream/button"
3
- require "whipped-cream/cli"
4
- require "whipped-cream/plugin"
5
- require "whipped-cream/runner"
6
- require "whipped-cream/sensor"
7
- require "whipped-cream/server"
8
- require "whipped-cream/version"
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'
@@ -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
@@ -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
- Rack::Server.start app: web, port: port
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
@@ -1,3 +1,3 @@
1
1
  module WhippedCream
2
- VERSION = "0.0.1pre1"
2
+ VERSION = "0.0.1pre2"
3
3
  end
@@ -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 "#usage" do
37
- it "displays a banner and help" do
38
- expect(cli).to receive(:puts).exactly(2).times
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
- cli.usage
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(Rack::Server).to receive(:start)
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
- it "starts the Sinatra application" do
35
- expect(Rack::Server).to receive(:start)
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
- server.start
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
@@ -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.1pre1
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